2017-09-03 4 views
0

En cliquant sur le lien "tag" suivant après celui marqué "actif" lorsque je clique sur le lien suivant. Mon exemple de structure html ci-dessous signifie pour ma connaissance limitée de jQuery que .next ne va pas fonctionner parce que les éléments d'étiquette ne sont pas des frères et soeurs. Le résultat final devrait être que cliquer sur le lien suivant devrait alors cliquer sur le lien autour du mot «pizza».Rechercher l'élément suivant non-frère

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

Quelque chose comme cela ne fonctionne que dans un seul paragraphe

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

Répondre

0

Il s'agit de donner des comportements spécifiques aux éléments .back, .next et .tag.

Pour conserver le code organisé, il est avantageux de le faire à peu près tout avec des gestionnaires d'événements, y compris, pour la commodité et la réutilisabilité, les gestionnaires d'événements personnalisés comme suit:

  • un gestionnaire d'événements « findPrev » pour trouver la balise précédente dans l'ensemble,
  • un gestionnaire d'événement 'findNext' pour trouver l'étiquette suivante dans l'ensemble.
$(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

Une fois que vous avez votre esprit rond qui, en prime, il est relativement trivial d'ajouter quelques lignes supplémentaires pour activer/désactiver les boutons Back et Next dans réponse à cliquer sur les tags. Cela peut inclure un couple de gestionnaires d'événements plus personnalisés:

  • un gestionnaire d'événements « enable » pour le dos et les éléments suivants,
  • un gestionnaire d'événements « désactiver » pour le dos et les éléments suivants.
$(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

Notes:

  • utilisation des deux .trigger() et .triggerHandler() est peut-être source de confusion. La différence réside dans ce qui est retourné. .trigger() renvoie toujours jQuery (pour le chaînage), tandis que .triggerHandler() renvoie tout ce que le gestionnaire renvoie.
  • Les choses se simplifieraient légèrement avec les éléments HTML <button> pour Back et Next à la place des hyperliens. Les boutons appropriés peuvent être désactivés/activés de manière inhérente sans que cela ne nuise à l'attribut href.
  • Les événements personnalisés peuvent alternativement être formulés sous la forme de plugins jQuery, ce qui est viable mais peut-être excessif pour une fonctionnalité simple.
+1

Cela a également fonctionné pour moi! Commencer à apprendre voir à quel point les choses peuvent être différentes et faire toujours la même chose. – spicedham

0

EDIT

Si vous voulez faire défiler tous les tags, vous pouvez leur donner un attribut personnalisé pour faciliter leur conclusion.

Voir les commentaires dans le code.

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

Exécuter cet extrait en pleine page;)
Je suis sûr que vous serez en mesure d'appliquer la même logique sur le lien « Retour ».