基于多组data属性实现元素隐藏的问题排查
问题:多部门标签页筛选功能异常排查
我有一组元素,每个元素带有一个或多个数组形式的data-dept属性;上方有一组标签页,每个标签页的data-dept属性与其标签文本一致。点击标签页时,希望隐藏所有不匹配该data-dept属性的元素。若元素只有单个data-dept属性,实现起来很简单,但部分元素有多组属性,只要匹配其中一个就需要显示。目前JavaScript代码存在问题,请求排查。
原代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <main class="main"> <div class="tabs"> <div data-dept="all" class="tab">All</div> <div data-dept="finance" class="tab">Finance</div> <div data-dept="adminisration" class="tab">Admin</div> <div data-dept="marketing" class="tab">Marketing</div> <div data-dept="executive" class="tab">Executive</div> <div data-dept="senior" class="tab">Senior</div> <div data-dept="organization" class="tab">Org</div> </div> <div class="member-container"> <div data-dept='["finance"]' class="member">John Doe</div> <div data-dept='["finance", "marketing"]' class="member">Jane Doe</div> <div data-dept='["senior"]' class="member">Billy Bob</div> <div data-dept='["adminisration", "senior"]' class="member">Suzy Q</div> <div data-dept='["executive"]' class="member">Random Name</div> <div data-dept='["marketing"]' class="member">Another Name</div> <div data-dept='["organization","executive","marketing"]' class="member">Foo Bar</div> <div data-dept='["adminisration"]' class="member">Does it Matter?</div> </div> </main>
CSS
body { margin: 0; padding: 0; box-sizing: border-box; } .tabs { display: flex; column-gap: 15px; padding-top: 100px; justify-content: center; } .tabs .tab { padding: 20px; border: 2px solid green; cursor: pointer; } .tabs .tab.active { background-color: green; color: #fff; } .member-container { display: flex; width: 90%; padding-top: 100px; margin: 0 auto; flex-wrap: wrap; column-gap: 20px; row-gap: 20px; } .member-container .member { width: 30%; border: 2px solid red; height: 100px; display: flex; align-items: center; justify-content: center; font-size: 25px; } .member-container .member.hide { display: none; }
JavaScript
(function($) { $(document).ready(function() { $(".main .tabs .tab").click(function() { let currentTab; currentTab = $(this).data('dept'); $(".main .tabs .tab").removeClass('active'); $(this).addClass('active'); // loop through all members and match those of currentTab $(".member-container .member").each(function(i, member) { if (currentTab == 'all') { $(member).removeClass('hide'); } else { $(member).removeClass('hide'); let memberDepts = $(member).data('dept'); $(memberDepts).each(function(j, dept) { if ($(member).data('dept') != dept) { $(member).addClass('hide') } }) } }) }) }); })(jQuery);
错误原因分析
- 遍历逻辑完全错误:遍历成员的部门数组时,你拿整个部门数组和单个部门字符串做比较(
$(member).data('dept') != dept),这永远不会成立;而且只要有一个部门不匹配就添加hide类,导致即使有匹配的部门,后续不匹配的部门也会把元素强制隐藏。 - 状态处理逻辑混乱:每次判断前先移除
hide,但后续错误的遍历逻辑会直接覆盖这个操作,导致元素状态异常。
修正后的代码
修正后的JavaScript
(function($) { $(document).ready(function() { $(".main .tabs .tab").click(function() { const currentTab = $(this).data('dept'); $(".main .tabs .tab").removeClass('active'); $(this).addClass('active'); $(".member-container .member").each(function(i, member) { const $member = $(member); const memberDepts = $member.data('dept'); if (currentTab === 'all') { $member.removeClass('hide'); } else { // 直接判断当前标签是否在成员的部门列表中 const isMatch = memberDepts.includes(currentTab); // 根据匹配结果切换隐藏状态 $member.toggleClass('hide', !isMatch); } }); }); }); })(jQuery);
修正说明
- 用数组的
includes()方法直接判断选中部门是否存在于成员的部门数组中,逻辑简洁准确。 - 使用
toggleClass('hide', !isMatch)一键控制显示/隐藏,无需先移除再添加,避免状态冲突。 - 缓存
$(member)为$member,减少重复DOM查询,提升代码性能。
内容的提问来源于stack exchange,提问作者RRhodes
相关产品推荐
相关产品推荐

