jquery 基于多个数据属性隐藏元素

fkaflof6  于 2023-10-17  发布在  jQuery
关注(0)|答案(4)|浏览(103)

我有一组项目,每个项目都有一个或多个数据属性(在数组中)。在它们上面,有一组选项卡,每个选项卡都有一个与其标签相同的数据属性。当我单击一个选项卡时,我想隐藏所有不具有相同数据属性的项。如果每个项目只有一个数据属性,这将很容易,但有些项目有多个数据属性,如果它们匹配,则需要显示。我有点陷入JS,但我觉得我很接近。有人看出我哪里做错了吗?
谢谢你

(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);
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;
}
<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="[&#34;finance&#34;]" class="member">John Doe</div>
    <div data-dept="[&#34;finance&#34;, &#34;marketing&#34;]" class="member">Jane Doe</div>
    <div data-dept="[&#34;senior&#34;]" class="member">Billy Bob</div>
    <div data-dept="[&#34;adminisration&#34;, &#34;senior&#34;]" class="member">Suzy Q</div>
    <div data-dept="[&#34;executive&#34;]" class="member">Random Name</div>
    <div data-dept="[&#34;marketing&#34;]" class="member">Another Name</div>
    <div data-dept="[&#34;organization&#34;,&#34;executive&#34;,&#34;marketing&#34;]" class="member">Foo Bar</div>
    <div data-dept="[&#34;adminisration&#34;]" class="member">Does it Matter?</div>
  </div>
</main>

我也有一个Codepen的链接:https://codepen.io/paul-molnar/pen/QWzazKq

lh80um4z

lh80um4z1#

试试这个基本上你的问题是围绕着这段代码:

let memberDepts = $(member).data('dept');
$(memberDepts).each(function(j, dept) {
  if ($(member).data('dept') != dept) {
    $(member).addClass('hide')
  }
})

memberDepts是一个字符串数组,一个部门列表。然后,您尝试选择它作为jQuery对象,就像它是一个HTML元素一样,并在它上面循环。在这个循环中,你试图查看每个成员是否被包含。
由于我们已经将当前选定的department作为一个字符串,并且我们有一个字符串数组,因此我们可以使用.includes()来大大简化并纠正这个问题。

if(!memberDepts.includes(currentTabDept)){
  thisMemberEl.addClass('hide')
}

我还做了一些其他的改变,主要是围绕尽可能少地选择元素。如果在一个包含10个元素的循环中调用$(member) 3次,那就是30次选择元素的调用!它只需要发生一次。

(function ($) {
  $(function () {
    const allTabEls = $(".main .tabs .tab");
    const allMemberEls = $(".member-container .member");
    
    allTabEls.click(function () {
      const currentTabEl = $(this);
      const currentTabDept = currentTabEl.data('dept');
      
      //console.clear()
      //console.log('click', currentTabDept)

      allTabEls.removeClass('active');
      currentTabEl.addClass('active');

      // loop through all members and match those of currentTab
      allMemberEls
        .removeClass('hide')
        .each(function (i, member) {
          
          if (currentTabDept !== 'all') {
            const thisMemberEl = $(member);
            const memberDepts = thisMemberEl.data('dept');
            if(!memberDepts.includes(currentTabDept)){
              //console.log('depts', memberDepts)
              thisMemberEl.addClass('hide')
            }
          }
          
        });
    });
  });
})(jQuery);
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;
}
<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="[&#34;finance&#34;]" class="member">John Doe</div>
        <div data-dept="[&#34;finance&#34;, &#34;marketing&#34;]" class="member">Jane Doe</div>
        <div data-dept="[&#34;senior&#34;]" class="member">Billy Bob</div>
        <div data-dept="[&#34;adminisration&#34;, &#34;senior&#34;]" class="member">Suzy Q</div>
        <div data-dept="[&#34;executive&#34;]" class="member">Random Name</div>
        <div data-dept="[&#34;marketing&#34;]" class="member">Another Name</div>
        <div data-dept="[&#34;organization&#34;,&#34;executive&#34;,&#34;marketing&#34;]" class="member">Foo Bar</div>
        <div data-dept="[&#34;adminisration&#34;]" class="member">Does it Matter?</div>
    </div>
</main>
tsm1rwdh

tsm1rwdh2#

试试这个。我只是用空格作为dept之间的分隔符。如果你有一个部门。名称与空格,你可以选择一个不同的字符作为字符或使用破折号来表示一个空格。
你可以用add/remove类替换.show()和.hide()。我只是拿它们做例子。

(function ($) {
    $(document).ready(function () {

        $(".main .tabs .tab").click(function () {
            let currentTab;
            currentTab = $(this).data('dept');

            $(".main .tabs .tab").removeClass('active');
            $(this).addClass('active');

             if (currentTab == 'all') {
                    $('.member').show();
             } else {
                    $('.member').each(function(i,member){
                      let depts = $(member).attr('data-dept').split(" ");
                      if (depts.includes(currentTab)) {
                        $(member).show();
                      } else {
                        $(member).hide();
                      }
                    });
             }
        });
    });
})(jQuery);
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;
}
<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="administration" class="member">Does it Matter?</div>
    </div>
</main>
r3i60tvu

r3i60tvu3#

使用array .includes()方法测试所选选项卡是否在data属性的数组中。

(function($) {
  $(document).ready(function() {
    $(".main .tabs .tab").click(function() {
      let currentTab;
      currentTab = $(this).data('dept');

      $(".main .tabs .tab").removeClass('active');
      $(this).addClass('active');

      if (currentTab == 'all') {
        $(".member-container .member").removeClass('hide');
      } else {
        $(".member-container .member").each(function(i, member) {
          let memberDepts = $(member).data('dept');
          $(member).toggleClass('hide', !memberDepts.includes(currentTab));
        });
      }
    });
  });
})(jQuery);
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;
}
<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="[&#34;finance&#34;]" class="member">John Doe</div>
    <div data-dept="[&#34;finance&#34;, &#34;marketing&#34;]" class="member">Jane Doe</div>
    <div data-dept="[&#34;senior&#34;]" class="member">Billy Bob</div>
    <div data-dept="[&#34;adminisration&#34;, &#34;senior&#34;]" class="member">Suzy Q</div>
    <div data-dept="[&#34;executive&#34;]" class="member">Random Name</div>
    <div data-dept="[&#34;marketing&#34;]" class="member">Another Name</div>
    <div data-dept="[&#34;organization&#34;,&#34;executive&#34;,&#34;marketing&#34;]" class="member">Foo Bar</div>
    <div data-dept="[&#34;adminisration&#34;]" class="member">Does it Matter?</div>
  </div>
</main>
rslzwgfq

rslzwgfq4#

按空格分割 depts 数据集,并使用Array.prototype.includes()

jQuery($ => {

  const $tabs = $(".main .tab");
  const $memb = $(".member-container .member");
  
  $tabs.on("click", function() {
    const dept = this.dataset.dept;

    $tabs.not(this).removeClass("active");
    $(this).addClass("active");

    $memb.each(function() {
      const show = dept === "all" || this.dataset.dept.split(/ /).includes(dept);
      $(this).toggleClass("hide", !show);
    });
  });
  
});
* {margin: 0; box-sizing: border-box; }

.tabs {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
}

.tabs .tab {
  padding: 1rem;
  border: 2px solid green;
  cursor: pointer;
}

.tabs .tab.active {
  background-color: green;
  color: #fff;
}

.member-container {
  display: flex;
  padding-top: 3rem;
  flex-wrap: wrap;
  gap: 1rem;
}

.member-container .member {
  width: 30%;
  border: 2px solid red;
  display: flex;
  padding: 1rem;
  align-items: center;
  justify-content: center;
}

.member-container .member.hide {
  display: none;
}
<main class="main">
  <div class="tabs">
    <div data-dept="all" class="tab active">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>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

相关问题