Trying to click on the next "tag" link after the one marked "active" when I click the Next link. My sample html structure below means to my limited jQuery knowledge that .next is not going to work because the tag elements are not siblings. The end result should be that clicking on the Next link should then click the link around the word '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>
Something like this only works within a single paragraph
$(".next").click(function() {
$(".active").next().click();
});
This is all about giving specific behaviours to the .back
, .next
and .tag
elements.
To keep the code organised, it's advantageous to do just about everything with event handlers including, for convenience and reusability, custom event handlers as follows :
$(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');
});
Once you've got your mind round that, as a bonus it's relatively trivial to add a few extra lines to enable/disable the Back
and Next
buttons in response to clicking the tags. This can include a couple more custom event handlers :
$(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
});
Notes:
.trigger()
and .triggerHandler()
is possibly confusing. The difference lies in what is returned. .trigger()
always returns jQuery (for chaining), whereas .triggerHandler()
returns whatever the handler returns.<button>
elements for Back and Next instead of hyperlinks. Proper buttons can be inherently disabled/enabled without all that messing about with the href
attribute.