jquery 查找非同级下一个元素

vptzau2j  于 2023-06-22  发布在  jQuery
关注(0)|答案(2)|浏览(169)

尝试点击下一个“标签”链接 * 后 * 一个标记为“活动”,当我点击下一个链接。我下面的示例html结构意味着,以我有限的jQuery知识,.next不起作用,因为标签元素不是兄弟。最后的结果应该是点击Next链接,然后点击单词“pizza”周围的链接。

<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();
});
alen0pnh

alen0pnh1#

这是关于为.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

一旦您了解了这一点,作为奖励,添加一些额外的行来启用/禁用BackNext按钮以响应单击标记是相对简单的。这可以包括更多的自定义事件处理程序:

  • 用于Back和Next元素的“enable”事件处理程序,
  • Back和Next元素的“disable”事件处理程序。
$(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().triggerHandler()可能会造成混淆。区别在于返回的内容。.trigger()总是返回jQuery(用于链接),而.triggerHandler()返回处理程序返回的任何内容。
  • 用HTML <button>元素代替超链接来表示“上一页”和“下一页”会稍微简化一些。适当的按钮可以被固有地禁用/启用,而不需要对href属性进行任何处理。
  • 定制事件也可以被描述为jQuery插件,这是可行的,但可以说是简单功能的过度。
rryofs0p

rryofs0p2#

编辑

如果你想循环所有的标签,你可以给予他们一个自定义属性,以方便他们的查找。
请参见代码中的注解。

$(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>

在整个页面中运行此片段;)

我相信你将能够在“返回”链接上应用相同的逻辑。

相关问题