【问题标题】:jQuery to get next match in the DOM after a particular elementjQuery 在特定元素之后获取 DOM 中的下一个匹配项
【发布时间】:2011-04-11 18:04:47
【问题描述】:

我不想承认这一点,但我一直在试图弄清楚如何做到这一点。

例如假装你有以下结构:

<div>
  ...
  <div>
    <ul>
      <li>
        <a href="..."><img class="foo"/></a><!-- "previous" -->
      </li>
      <li>
        <a href="..."><img class="bar"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- I'm at this node -->
      </li>
      <li>
        <a href="..."><img class="baz"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- "next" 1 -->
      </li>
    </ul>
  </div>
  ...
  <div>
    <ul>
      <li>
        <a href="..."><img class="foo"/></a><!-- "next" 2 -->
      </li>
      <li>
        <a href="..."><img class="baz"/></a>
      </li>
      <li>
        <a href="..."><img class="foo"/></a><!-- "next" 3 -->
      </li>
      <li>
        <a href="..."><img class="bar"/></a>
      </li>
    </ul>
  </div>
</div>

我在一个与上面的 highlighted "foo" 节点相关的 jQuery 事件处理程序中。我想找到"foo" 的“下一个”img 元素。

不过有 2 个问题。

  1. 我只想选择 DOM 中比我所在的当前节点更远的“foo”元素(例如,不需要“前一个”foo 和当前 foo)
  2. 尽管我已将嵌套显示为遵循精确的模式,但生成的代码是/可以 嵌套在 any 级别。 ..因此我不能只做 .parent().parent().parent().siblings().find()... 等等。

如果您可以想象,每次浏览器向 DOM 添加一个节点时,它都会增加一个计数器并为该节点分配索引...您可以检索...我想要的是:

var here = $(this).getIndexInDOM();//e.g. returns 347
$('img.foo').each(function(){
  if($(this).getIndexInDOM() > here){//is this past our current index?
    doSomething($(this));//use it
    break;
  }
});

.getIndexInDOM() 方法显然在 jQuery 中不存在......但我很好奇是否有人有解决方案来获得我所追求的“下一个”元素。

目前我能想到的唯一解决方案真的很不优雅,并且在 DOM 中的后半部分图像中表现非常糟糕......

//using vanilla JavaScript
var thisImg = theCurrentImageIHave;//some reference to the DOM element
var found = false;
for(var i=0;i<document.images.length;i++){
  if(found){
    if(document.images[i].className == 'foo'){
      doSomething(document.images[i]);
      break;
    }
  } else {
    if(document.images[i] == thisImg){
      found = true;
    }
  }
}

【问题讨论】:

    标签: javascript jquery dom jquery-selectors hierarchy


    【解决方案1】:

    查看next。它完全符合您的要求。

    $('img.foo').next().css('background-color', 'red');
    

    如果您想获取当前所选项目之后的所有项目并且您知道它在 DOM 中的位置,您可以使用gt selector 选择所有“大于”自身的项目。

    例如:

    $('img.foo:gt(4)')
    

    将返回所有“大于”选择中第 4 项的所有项目(AKA,之后而不是当前项目)。

    【讨论】:

    • next() 只搜索兄弟姐妹,我想?
    • JasCav - .next() 仅适用于兄弟姐妹。再次阅读问题。 OP 声明 “我在一个与上面突出显示的“foo”节点相关的 jQuery 事件处理程序中。” 突出显示的 .foo 没有兄弟姐妹。需要某种 up then over 遍历。 :o)
    • @JasCav - 根据文档api.jquery.com/next .next() 仅遍历当前节点的兄弟姐妹(在我的示例中,它只会找到“下一个 1”...如果“下一个1" 不存在,它不会找到 "next 2" 或 "next 3")
    • @scunliffe @patrick @Isaac - 你是对的。 :-( 我失败了。更新了我的答案。我认为这是正确的(我以前用它来解决类似的问题。)我不是世界上最好的 jQuery-er。我也在学习。谢谢更正。
    • 嗯,.gt() 可能在这里工作......我仍然需要遍历整个集合以首先找出我的“当前”索引。
    【解决方案2】:

    在点击处理程序中,试试这个:

    示例: http://jsfiddle.net/QVphP/ (单击蓝色框为下一个添加边框)

    var $foo = $('img.foo');  // get all .foo images
    
    var idx = $foo.index( this );  // get the index position of "this"
                                   //    relative to all the .foo images found
    
    var next = $foo.eq( idx + 1 ); // grab the .foo for the incremented index
    

    【讨论】:

    • 太棒了! .index() 正是我在这里需要的......如果我使用的是 jQuery v1.4,我会立即跳上它;-) 但可惜我还没到那里,所以我需要循环有点自己获取索引。
    • @sgunliffe - 传递 DOM 元素时不需要 jQuery 1.4(如上例所示)。 .index() 的另外两个用途需要 1.4。 :o) 这是相同的示例,但使用 jQuery 1.3.2 代替:jsfiddle.net/QVphP/1
    • 哦,伙计,我一直盯着我的代码太久了,你是对的...... .index(element) 在 jQuery 1.0+ 中被支持为我的修复添加修复;- )
    【解决方案3】:

    查看this jsfiddle。单击任何带有红色边框 (foo) 的图像,下一个红色边框(下一个 foo)将变为黄色。

    根据您在页面中有多少foos,此解决方案可能会影响性能。但由于您还没有使用 1.4,所以这将起作用。

    【讨论】:

    • Nate - OP 误认为需要 1.4。您的解决方案会起作用,但您实际上并不需要使用 .data() 来使用如此复杂的任何东西。这是您更新的示例:jsfiddle.net/Bs2M5/2 它只是使用== 来比较 DOM 元素。 :o)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多