嵌套列表 - 在单独的行上显示每个ul级别

时间:2014-09-25 19:04:44

标签: javascript css

我正在使用jQuery的同位素插件来过滤条目列表,使用下面的标记来列出可能的过滤器。所有顶级列表项最初都是可见的,如果我单击特定的过滤器按钮,则会显示任何子过滤器(如果有)。

所有这一切都很有效。然而,我遇到了一些问题,让CSS正确显示列表。标记是:

<ul class="filter-list">
  <li><button data-filter="*">show all</button></li>
  <li>
    <button data-filter=".filter1">Filter 1</button>
    <ul class="sub-filter">
      <li>
        <button data-filter=".filter1.filtera">Filter 1,A</button>
        <ul class="sub-filter">
          <li><button data-filter=".filtera.filteri">Filter 1,A,i</button></li>
          <li><button data-filter=".filtera.filterii">Filter 1,A,ii</button></li>
          <li><button data-filter=".filtera.filteriii">Filter 1,A,iii</button></li>
        </ul>
      </li>
      <li><button data-filter=".filter1.filterb">Filter 1,B</button></li>
      <li>
        <button data-filter=".filter1.filterc">Filter 1,C</button>
        <ul class="sub-filter">
          <li><button data-filter=".filterc.filteri">Filter 1,C,i</button></li>
          <li><button data-filter=".filterc.filterii">Filter 1,C,ii</button></li>
        </ul>
      </li>
      <li>
        <button data-filter=".filter1.filterd">Filter 1,D</button>
        <ul class="sub-filter">
          <li><button data-filter=".filterd.filteri">Filter 1,D,i</button></li>
          <li><button data-filter=".filterd.filterii">Filter 1,D,ii</button></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><button data-filter=".filter2">Filter 2</button></li>
  <li><button data-filter=".filter3">Filter 3</button></li>
</ul>

我到目前为止的CSS是:

ul.filter-list {
  display:inline-block;
  position: relative;
  width: 100%;
  margin:0;
  padding:0;
}

ul.filter-list ul {
  display: none;
  position:relative;
}

.filter-list ul.active-filter {
  display: block;
  position:absolute;
  top:50px;
  left:0px;
}

ul.filter-list li {
  list-style-type: none;
  display: inline-block;
}

我需要的预期输出是将列表的每个“级别”放在一行上,然后是下一个“级别”的过滤器(如果有的话)是当前活动的那个。最初,它应该如下所示:

show all    Filter 1    Filter 2    Filter 3

如果我点击Filter 1,则该过滤器下方的下一级按钮应显示在下一行:

show all    Filter 1    Filter 2    Filter 3
Filter 1,A    Filter 1,B    Filter 1,C    Filter 1,D

如果我要点击Filter 1,C,第三级按钮将需要显示在第三行:

show all    Filter 1    Filter 2    Filter 3
Filter 1,A    Filter 1,B    Filter 1,C    Filter 1,D
Filter 1,C,i    Filter 1,C,ii

我仍然遇到的最大问题之一是,由于活动列表是绝对定位的,因此它们显示在紧跟此列表过滤器的内容之上,而不是将其推下。您可以在this fiddle中看到此行为。此外,当屏幕尺寸减小时,事物不会像我期望的那样流动/打破(以及将绝对定位的按钮放在其他绝对定位的物品之上)。

有没有办法只使用CSS(可能使用相对定位?)来实现这一点,或者我将不得不添加一些过量的Javascript到我拥有的东西?或者我应该拿出嵌套列表来支持多个“平面”列表?

1 个答案:

答案 0 :(得分:1)

您只需使用常规CSSjQuery/Javascript来切换项目可见性即可实现此目的:

$(function() {
  $('button').on('click', function() {
    // The element to be toggled (show/hide).
    var toToggle = $(this).next('.sub-filter');

    // Go through its parents until the element
    // with class sub-filter and find its
    // children with this same class to hide 
    // them, excluding itself.
    $(this).parents('.sub-filter').find('.sub-filter').not(toToggle).hide();
    
    // Toggle the target.
    toToggle.toggle();
  });
});
* {
  box-sizing: border-box;
}
ul.filter-list,
ul.filter-list li {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
ul.sub-filter {
  /* Giving them the full width and
    floating them you guarantee their 
    place in a new line. */
  width: 100%;
  float: left;
  display: none;
  /* Setting their padding to 0 will
    keep them aligned to the line above
    them. */
  padding: 0;
}
ul.filter-list > li,
ul.sub-filter > li {
  /* Setting their display to inline 
    will show them next to each other. */
  display: inline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="filter-list">
  <li>
    <button data-filter="*">show all</button>
  </li>
  <li>
    <button data-filter=".filter1">Filter 1</button>
    <ul class="sub-filter">
      <li>
        <button data-filter=".filter1.filtera">Filter 1,A</button>
        <ul class="sub-filter">
          <li>
            <button data-filter=".filtera.filteri">Filter 1,A,i</button>
          </li>
          <li>
            <button data-filter=".filtera.filterii">Filter 1,A,ii</button>
          </li>
          <li>
            <button data-filter=".filtera.filteriii">Filter 1,A,iii</button>
          </li>
        </ul>
      </li>
      <li>
        <button data-filter=".filter1.filterb">Filter 1,B</button>
      </li>
      <li>
        <button data-filter=".filter1.filterc">Filter 1,C</button>
        <ul class="sub-filter">
          <li>
            <button data-filter=".filterc.filteri">Filter 1,C,i</button>
          </li>
          <li>
            <button data-filter=".filterc.filterii">Filter 1,C,ii</button>
          </li>
        </ul>
      </li>
      <li>
        <button data-filter=".filter1.filterd">Filter 1,D</button>
        <ul class="sub-filter">
          <li>
            <button data-filter=".filterd.filteri">Filter 1,D,i</button>
          </li>
          <li>
            <button data-filter=".filterd.filterii">Filter 1,D,ii</button>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>
    <button data-filter=".filter2">Filter 2</button>
  </li>
  <li>
    <button data-filter=".filter3">Filter 3</button>
  </li>
</ul>

Demo jsFiddle