查找下一个非兄弟元素
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');
});
一旦你明白了这一点,作为奖励,在 enable/disable Back
和 Next
按钮上添加一些额外的行以响应点击是相对微不足道的标签。这可以包括更多的自定义事件处理程序:
- '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
});
备注:
- 同时使用
.trigger()
and .triggerHandler()
可能会造成混淆。区别在于返回的内容。 .trigger()
始终 returns jQuery (用于链接),而 .triggerHandler()
returns 无论处理程序如何 returns.
- 使用 HTML
<button>
Back 和 Next 元素而不是超链接,事情会稍微简化。正确的按钮可以是固有的 disabled/enabled,而不会乱用 href
属性。
- 自定义事件也可以表述为 jQuery 插件,这是可行的,但可以说是过于简单的功能。
尝试单击下一个 "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');
});
一旦你明白了这一点,作为奖励,在 enable/disable Back
和 Next
按钮上添加一些额外的行以响应点击是相对微不足道的标签。这可以包括更多的自定义事件处理程序:
- '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
});
备注:
- 同时使用
.trigger()
and.triggerHandler()
可能会造成混淆。区别在于返回的内容。.trigger()
始终 returns jQuery (用于链接),而.triggerHandler()
returns 无论处理程序如何 returns. - 使用 HTML
<button>
Back 和 Next 元素而不是超链接,事情会稍微简化。正确的按钮可以是固有的 disabled/enabled,而不会乱用href
属性。 - 自定义事件也可以表述为 jQuery 插件,这是可行的,但可以说是过于简单的功能。