查找下一个非兄弟元素

Find non-sibling next element

尝试单击下一个 "tag" link 标记为 "active" 之后单击下一个 link .我下面的示例 html 结构意味着我有限的 jQuery 知识是 .next 不会工作,因为标签元素不是兄弟元素。最终结果应该是点击下一步 link 然后点击单词 'pizza' 周围的 link。

<div class="wrapper">
<p>some <a href="#" class="tag">text</a>here and more <a href="#" class="tag">text</a></p>
<p>some <a href="#" class="tag active">text</a>here</p>
<p>some <a href="#" class="tag">pizza</a>here and more <a href="#" class="tag">text</a></p>
<p>some <a href="#" class="tag">text</a>here and some more <a href="#" class="tag">text</a></p>
</div>

<div class="nav">
<a href="#" class="back">Back</a>
<a href="#" class="next">Next</a>
</div>

像这样的东西只适用于一个段落

$(".next").click(function() {
    $(".active").next().click();
});

编辑

如果你想循环所有标签,你可以给它们一个自定义属性以方便它们查找。

查看代码中的注释。

$(document).ready(function(){

  // Get all tags.
  var tagCollection = $(".tag");

  // Give them an "index"
  tagCollection.each(function(index){
    //console.log( index );
    $(this).attr("data-index",index);
  });

  // Click handler
  $(".next").click(function() {
    
    // Get the index of the active tag +1 (for the next).
    var dataIndex = parseInt( $(".active").attr("data-index") )+1;
    //console.log(dataIndex);

    // If last index, back to the very first.
    if(dataIndex>tagCollection.length-1){
      dataIndex = 0;
    }

    // Here, we remove the active class on the current tag
    // And find the next one to add the active class on it.
    // For that demo, I turned it to red.
    // You may click it!
    $(document).find(".active")                       // Find the active one.
               .removeClass("active")                 // Remove the class
               .closest(".wrapper")                   // climb up to the wrapper
               .find("[data-index='"+dataIndex+"']")  // to find the next tag
               .addClass("active")                    // Give it the class
               .click();                              // And click it!

  });
  
  // Tag click handler
  $(".tag").click(function(){
    console.log( $(this).text() );
  });
  
});
.active{
  color:red;
  font-weight:bold;
  text-decoration:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="wrapper">
  <p>some <a href="#" class="tag">text</a>here and more <a href="#" class="tag">text</a></p>
  <p>some <a href="#" class="tag active">text</a>here</p>
  <p>some <a href="#" class="tag">pizza</a>here and more <a href="#" class="tag">text</a></p>
  <p>some <a href="#" class="tag">text</a>here and some more <a href="#" class="tag">text</a></p>
</div>

<div class="nav">
<a href="#" class="back">Back</a>
<a href="#" class="next">Next</a>
</div>

运行 此代码段在整页中;)
我相信您将能够在 "Back" link.

上应用相同的逻辑

这就是为 .back.next.tag 元素赋予特定行为。

为了使代码井井有条,使用事件处理程序做几乎所有事情是有利的,包括为了方便和可重用性,自定义事件处理程序如下:

  • 一个 'findPrev' 事件处理程序,用于查找集合中的前一个标签,
  • 一个 'findNext' 事件处理程序,用于查找集合中的下一个标签。
$(document).ready(function() {
    $(".nav .back").on('click', function(e) {
        e.preventDefault();
        if(this.href) { $(".wrapper .active").triggerHandler('findPrev').click(); }
    });
    $(".nav .next").on('click', function(e) {
        e.preventDefault();
        if(this.href) { $(".wrapper .active").triggerHandler('findNext').click(); }
    });

    $(".tag").on('findPrev', function() { // <<< custom event handler
        var $tags = $(this).closest('.wrapper').find('.tag');
        var index = $tags.index(this);
        return (index > 0) ? $tags.eq(index - 1) : $();
    }).on('findNext', function() { // <<< custom event handler
        var $tags = $(this).closest('.wrapper').find('.tag');
        var index = $tags.index(this);
        return (index < $tags.length) ? $tags.eq(index + 1) : $();
    }).on('click', function(e) {
        e.preventDefault();
        $(".wrapper .tag").filter(".active").removeClass('active').end().filter(this).addClass('active'); // move the 'active' highlight
        // desired click action here
    }).filter(".active").trigger('click');
});

Demo

一旦你明白了这一点,作为奖励,在 enable/disable BackNext 按钮上添加一些额外的行以响应点击是相对微不足道的标签。这可以包括更多的自定义事件处理程序:

  • 'enable' Back 和 Next 元素的事件处理程序,
  • 一个 'disable' Back 和 Next 元素的事件处理程序。
$(document).ready(function() {
    $(".nav .back").on('click', function(e) {
        e.preventDefault();
        if(this.href) { $(".wrapper .active").triggerHandler('findPrev').click(); } // find previous tag and 'click' it.
    });
    $(".nav .next").on('click', function(e) {
        e.preventDefault();
        if(this.href) { $(".wrapper .active").triggerHandler('findNext').click(); } // find next tag and 'click' it.
    });
    $(".nav .back, .nav .next").on('enable', function() { // <<< custom event handler
        $(this).attr('href', '#'); // enable
    }).on('disable', function() { // <<< custom event handler
        $(this).removeAttr('href'); // disable
    });

    $(".tag").on('findPrev', function() { // <<< custom event handler
        var $tags = $(this).closest('.wrapper').find('.tag');
        var index = $tags.index(this);
        return (index > 0) ? $tags.eq(index - 1) : $();
    }).on('findNext', function() { // <<< custom event handler
        var $tags = $(this).closest('.wrapper').find('.tag');
        var index = $tags.index(this);
        return (index < $tags.length) ? $tags.eq(index + 1) : $();
    }).on('click', function(e) {
        e.preventDefault();
        $(".wrapper .tag").filter(".active").removeClass('active').end().filter(this).addClass('active'); // move the 'active' highlight
        $(".nav .back").trigger($(this).triggerHandler('findPrev').length ? 'enable' : 'disable'); // manage the back button
        $(".nav .next").trigger($(this).triggerHandler('findNext').length ? 'enable' : 'disable'); // manage the next button
        // desired click action here
    }).filter(".active").trigger('click'); // trigger 'click' to initialize everything
});

Demo

备注:

  • 同时使用 .trigger() and .triggerHandler() 可能会造成混淆。区别在于返回的内容。 .trigger() 始终 returns jQuery (用于链接),而 .triggerHandler() returns 无论处理程序如何 returns.
  • 使用 HTML <button> Back 和 Next 元素而不是超链接,事情会稍微简化。正确的按钮可以是固有的 disabled/enabled,而不会乱用 href 属性。
  • 自定义事件也可以表述为 jQuery 插件,这是可行的,但可以说是过于简单的功能。