深入學習jquery原始碼之next()和nextAll()與nextUntil()
深入學習jquery原始碼之next()和nextAll()與nextUntil()
next([expr])
概述
取得一個包含匹配的元素集合中每一個元素緊鄰的後面同輩元素的元素集合。
這個函式只返回後面那個緊鄰的同輩元素,而不是後面所有的同輩元素(可以使用nextAll)。可以用一個可選的表示式進行篩選。
引數
expr String
用於篩選的表示式
找到每個段落的後面緊鄰的同輩元素。
<p>Hello</p><p>Hello Again</p><div><span>And Again</span></div>
$("p").next()
[ <p>Hello Again</p>, <div><span>And Again</span></div> ]
找到每個段落的後面緊鄰的同輩元素中類名為selected的元素。
<p>Hello</p><p class="selected">Hello Again</p><div><span>And Again</span></div>
$("p").next(".selected")
[ <p class="selected">Hello Again</p> ]
nextAll([expr])
概述
查詢當前元素之後所有的同輩元素。
可以用表示式過濾
引數
expr String
用來過濾的表示式
給第一個div之後的所有元素加個類
<div></div><div></div><div></div><div></div>
$("div:first").nextAll().addClass("after");
[ <div class="after"></div>, <div class="after"></div>, <div class="after"></div> ]
nextUntil([exp|ele][,fil])
概述
查詢當前元素之後所有的同輩元素,直到遇到匹配的那個元素為止。
如果提供的jQuery代表了一組DOM元素,.nextUntil()方法也能讓我們找遍所有元素所在的DOM樹,直到遇到了一個跟提供的引數匹配的元素的時候才會停下來。這個新jQuery物件裡包含了下面所有找到的同輩元素,但不包括那個選擇器匹配到的元素。
如果沒有選擇器匹配到,或者沒有提供引數,那麼跟在後面的所有同輩元素都會被選中。這就跟用沒有提供引數的 .nextAll()效果一樣。
引數
[expr][,filter] String,String
expr: 用於篩選祖先元素的表示式。
filter: 一個字串,其中包含一個選擇表示式匹配元素。
[element][,filter] DOMElement,String
element: 用於篩選祖先元素的DOM元素。
filter: 一個字串,其中包含一個選擇表示式匹配元素。
給#term-2後面直到dt前的元素加上紅色背景
<dl>
<dt>term 1</dt>
<dd>definition 1-a</dd>
<dd>definition 1-b</dd>
<dd>definition 1-c</dd>
<dd>definition 1-d</dd>
<dt id="term-2">term 2</dt>
<dd>definition 2-a</dd>
<dd>definition 2-b</dd>
<dd>definition 2-c</dd>
<dt>term 3</dt>
<dd>definition 3-a</dd>
<dd>definition 3-b</dd>
</dl>
$('#term-2').nextUntil('dt').css('background-color', 'red');
var term3 = document.getElementById("term-3");
$("#term-1").nextUntil(term3, "dd").css("color", "green");
jquery原始碼
jQuery.extend({
dir: function (elem, dir, until) {
var matched = [],
cur = elem[dir];
while (cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until))) {
if (cur.nodeType === 1) {
matched.push(cur);
}
cur = cur[dir];
}
return matched;
},
sibling: function (n, elem) {
var r = [];
for (; n; n = n.nextSibling) {
if (n.nodeType === 1 && n !== elem) {
r.push(n);
}
}
return r;
}
});
function sibling(cur, dir) {
do {
cur = cur[dir];
} while (cur && cur.nodeType !== 1);
return cur;
}
jQuery.each({
next: function (elem) {
return sibling(elem, "nextSibling");
},
nextAll: function (elem) {
return jQuery.dir(elem, "nextSibling");
},
nextUntil: function (elem, i, until) {
return jQuery.dir(elem, "nextSibling", until);
}
}, function (name, fn) {
jQuery.fn[name] = function (until, selector) {
var ret = jQuery.map(this, fn, until);
if (name.slice(-5) !== "Until") {
selector = until;
}
if (selector && typeof selector === "string") {
ret = jQuery.filter(selector, ret);
}
if (this.length > 1) {
// Remove duplicates
if (!guaranteedUnique[name]) {
ret = jQuery.unique(ret);
}
// Reverse order for parents* and prev-derivatives
if (rparentsprev.test(name)) {
ret = ret.reverse();
}
}
return this.pushStack(ret);
};
});