jQuery UI Tabs在jQuery 1.8.0及以上版本的兼容性问题
jQuery UI Tabs在jQuery 1.8.0及以上版本的兼容性问题
我完全懂你碰到的这个头疼问题——把jQuery从1.7.2升级到1.8.0及之后的版本后,你的Tabs布局就乱套了,原本切换到「One」标签(对应fragment1)时,第二个row里的红色文本根本不该显示,但新版本里却冒出来了。你猜的没错,重复的嵌套ID就是罪魁祸首!
问题根源
HTML规范明确要求页面上的ID必须是唯一的,早期的jQuery版本(比如1.7.2)在通过ID选择器查找元素时,可能只会返回第一个匹配的元素,所以Tabs组件只会关联到第一个row里的fragment2、fragment3。但从jQuery 1.8.0开始,选择器的处理逻辑有了调整,加上jQuery UI Tabs的内部实现也更新了,它会找到所有同ID的元素,导致第二个row里的重复ID元素也被当成了Tab面板的一部分,从而在不该显示的时候出现。
对比示例
工作版本(jQuery 1.7.2)
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>tabs demo</title> <script src="https://code.jquery.com/jquery-1.7.2.js"></script> <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.3/themes/smoothness/jquery-ui.css"> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> </head> <body> <div class="tabs"> <ul> <li aria-controls="fragment1"><a href="#fragment1" title="fragment1"><span>One</span></a></li> <li aria-controls="fragment2"><a href="#fragment2" title="fragment2"><span>Two</span></a></li> <li aria-controls="fragment3"><a href="#fragment3" title="fragment3"><span>Three</span></a></li> </ul> <div class="row"> <div id="fragment1"> <p>First tab information</p> </div> <div id="fragment2"> Second frgament text </div> <div id="fragment3"> 3rd fragment text </div> </div> <div class="row"> <div id="fragment2" style="color:red;"> 22Lorem ip 222 ipsum dolor </div> <div id="fragment3" style="color:red;"> 333 ipsum do L33orem ipsu Lo333rem ips </div> </div> </div> <script> $(function(){ $( ".tabs" ).tabs({active: 0}); }); </script> </body> </html>
非工作版本(jQuery 1.8.0)
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>tabs demo</title> <script src="https://code.jquery.com/jquery-1.8.0.js"></script> <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.3/themes/smoothness/jquery-ui.css"> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> </head> <body> <div class="tabs"> <ul> <li aria-controls="fragment1"><a href="#fragment1" title="fragment1"><span>One</span></a></li> <li aria-controls="fragment2"><a href="#fragment2" title="fragment2"><span>Two</span></a></li> <li aria-controls="fragment3"><a href="#fragment3" title="fragment3"><span>Three</span></a></li> </ul> <div class="row"> <div id="fragment1"> <p>First tab information</p> </div> <div id="fragment2"> Second frgament text </div> <div id="fragment3"> 3rd fragment text </div> </div> <div class="row"> <div id="fragment2" style="color:red;"> 22Lorem ip 222 ipsum dolor </div> <div id="fragment3" style="color:red;"> 333 ipsum do L33orem ipsu Lo333rem ips </div> </div> </div> <script> $(function(){ $( ".tabs" ).tabs({active: 0}); }); </script> </body> </html>
解决方案
最彻底的办法是修复重复ID的问题,这是符合HTML规范的根本解决方式:
- 把第二个row里的重复ID改成唯一值,比如
fragment2-duplicate、fragment3-duplicate - 如果这些元素不需要作为Tab面板,确保它们不会被jQuery UI Tabs识别到,比如给它们加个类,或者把它们移到Tabs容器外面(如果业务允许的话)
下面是修改后的示例代码:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>tabs demo</title> <script src="https://code.jquery.com/jquery-3.7.1.js"></script> <link rel="stylesheet" href="https://code.jquery.com/ui/1.13.3/themes/smoothness/jquery-ui.css"> <script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script> </head> <body> <div class="tabs"> <ul> <li aria-controls="fragment1"><a href="#fragment1" title="fragment1"><span>One</span></a></li> <li aria-controls="fragment2"><a href="#fragment2" title="fragment2"><span>Two</span></a></li> <li aria-controls="fragment3"><a href="#fragment3" title="fragment3"><span>Three</span></a></li> </ul> <div class="row"> <div id="fragment1"> <p>First tab information</p> </div> <div id="fragment2"> Second frgament text </div> <div id="fragment3"> 3rd fragment text </div> </div> </div> <!-- 把重复内容移到Tabs容器外,或者修改ID --> <div class="row"> <div id="fragment2-duplicate" style="color:red;"> 22Lorem ip 222 ipsum dolor </div> <div id="fragment3-duplicate" style="color:red;"> 333 ipsum do L33orem ipsu Lo333rem ips </div> </div> <script> $(function(){ $( ".tabs" ).tabs({active: 0}); }); </script> </body> </html>
如果因为业务限制暂时不能修改ID,也可以通过配置jQuery UI Tabs的panel选项,指定只选择第一个row里的面板元素:
$( ".tabs" ).tabs({ active: 0, panel: ".row:first > div" // 只识别第一个row下的面板 });
不过这种方式是治标不治本的,还是建议优先修复重复ID的问题,避免后续出现更多兼容性问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

