【问题标题】:Cycling through a jQuery object with elements grouped together循环浏览 jQuery 对象,其中元素组合在一起
【发布时间】:2014-06-17 22:18:03
【问题描述】:

我有一组包含嵌套列表的列表项,有点像这样:

<ul class="searchselectors">
  <li class="group">Group name 1
    <ul>
      <li class="item selected">List item 1.1</li>
      <li class="item">List item 1.2</li>
      <li class="item">List item 1.3</li>
    </ul>
  </li>
  <li class="group">Group name 2
    <ul>
      <li class="item">List item 2.1</li>
      <li class="item">List item 2.2</li>
      <li class="item">List item 2.3</li>
    </ul>
  </li>
  <li class="group">Group name 3
    <ul>
      <li class="item">List item 3.1</li>
    </ul>
  </li>
</ul>

我想使用向上/向下箭头键循环遍历所有 .item 元素(我已经通过使用 on('keydown') 并捕获键代码 3840 进行设置)并设置 .selected在当前选定项目之前或之后的下一个项目上,根据需要环绕到顶部/底部。

使用$().next()$().prev() 将不起作用,因为它仅适用于兄弟姐妹,而不适用于$('.searchselectors .item') 等jQuery 对象。\

【问题讨论】:

    标签: javascript jquery css dom-manipulation


    【解决方案1】:

    我正在解决同样的问题,但在我的项目中我使用的是KnockoutJS。事实上,最初的逻辑是用纯 jQuery 编写的,我用 Knockout 对其进行了重构。这是使用 jQuery 解决问题的方法:

    Fiddle - http://jsfiddle.net/6QN77/2/

    我没有花太多时间清理 JavaScript,但我现在把它留给你。

    HTML

    <ul id="searchselectors">
      <li class="group">Group name 1
        <ul>
          <li class="item selected">List item 1.1</li>
          <li class="item">List item 1.2</li>
          <li class="item">List item 1.3</li>
        </ul>
      </li>
      <li class="group">Group name 2
        <ul>
          <li class="item">List item 2.1</li>
          <li class="item">List item 2.2</li>
          <li class="item">List item 2.3</li>
        </ul>
      </li>
      <li class="group">Group name 3
        <ul>
          <li class="item">List item 3.1</li>
        </ul>
      </li>
    </ul>
    

    jQuery

    $(function () {
        var $menu = $("#searchselectors"),
            $items = $menu.find(".item"),
            $selectedItem = $menu.find(".selected"),
            selectedIndex = $selectedItem.length - 1;
    
        $(document).on("keydown", function (e) {
            switch(e.keyCode) {
                case 40:  // down arrow
                    $selectedItem.removeClass("selected");
                    selectedIndex = (selectedIndex + 1) % $items.length;
                    $selectedItem = $items.eq(selectedIndex).addClass("selected");
                    break;
                case 38:  // up arrow
                    $selectedItem.removeClass("selected");
                    selectedIndex = (selectedIndex - 1) % $items.length;
                    $selectedItem = $items.eq(selectedIndex).addClass("selected");
                    break;
            }
        });
    });
    

    更新:我的解决方案围绕获取对包装器元素 (#searchselectors) 的引用并获取所有标记为 CSS 类 .itemLI 元素。接下来,我获得对当前选定元素及其索引的引用。最后,代码监听向下和向上箭头键被按下 (keydown),如果向上则递减,如果向上则递增。循环是通过模算子实现的。所选项目的 CSS 类被移除并放回。所选项目引用是出于性能原因,所以我不必写$items.removeClass(".selected").eq(selectedIndex).addClass("selected");

    【讨论】:

    • 我一直在尝试将它实现到我的解决方案中,但由于某种原因,它不像在 jsFiddle 中那样工作,我什至引入了我自己的代码并对其进行了测试,只是为了它去工作。可以在jsfiddle.net/AYpe8 查看小提琴。如果需要,我可以稍后上传整个页面/js。
    • 嗯...这很有趣。您在 JavaScript 控制台中看到任何错误吗?我想知道 jQuery 是否找不到特定的元素集?是的,如果可能的话,我想看看发生了什么。
    • 我没有看到任何错误,但是当我将变量的内容记录到控制台时,它们是空的。 lain.rustedlogic.net/projects/hp(可以在lain.rustedlogic.net/projects/hp/js/app.js查看Javascript)
    • 我想我知道发生了什么。当您初始化小部件并第一次调用this.bindUIActions(); 时,$items 正在被缓存。一旦搜索小部件收到项目,它就永远不会更新。将初始化$items$selectedItem 的代码移动到keydown 事件。 See your updated Fiddle
    • 那行得通。我想我应该在一开始就注意到这一点。
    【解决方案2】:

    在我为那些寻找它的人提供原生 JS 答案的过程中,这里是 @Mario j Vargas 用原生 Javascript 改编的好答案。只需要两行额外的代码。

    http://jsfiddle.net/kevinvanlierde/7tQSW/2/

    这里只放JS,HTML也是一样。

    (function () {
        var $menu = document.getElementById('searchselectors'),
            items = $menu.getElementsByClassName('item'),
            $selectedItem = $menu.getElementsByClassName('selected')[0],
            selectedIndex = Array.prototype.indexOf.call($selectedItem, items)+1;
    
        document.body.addEventListener('keydown', function (e) {
            switch(e.keyCode) {
                case 40:  // down arrow
                    $selectedItem.className = $selectedItem.className.replace(' selected','');
                    selectedIndex = selectedIndex < items.length - 1 ? selectedIndex + 1 : selectedIndex;
                    $selectedItem = items[selectedIndex];
                    $selectedItem.className += ' selected';
                    break;
                case 38:  // up arrow
                    $selectedItem.className = $selectedItem.className.replace(' selected','');
                    selectedIndex = selectedIndex > 0 ? selectedIndex - 1 : selectedIndex;
                    $selectedItem = items[selectedIndex];
                    $selectedItem.className += ' selected';
                    break;
            }
        }, false);
    }());
    

    【讨论】:

      【解决方案3】:

      获取“item”类的所有列表项的最简单方法是:

      var items = $('.item'); 
      
       for (var i = 0; i < items.length; i++) {
            var item = items[i]; // iterate
       }
      

      然后,您可以从列表中选择下一项

      你可以这样做

       if (!$().next) {
          var nextUL= $().parent.find('ul')
          iterateThruList(nextUL);
       }
      

      【讨论】:

        【解决方案4】:

        你可以使用类似的东西

        var UL = $(".searchselectors").children().length; //number of UL (group names)
        

        遍历项目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-14
          • 1970-01-01
          • 2010-12-20
          • 1970-01-01
          • 1970-01-01
          • 2021-10-05
          • 1970-01-01
          相关资源
          最近更新 更多