jQuery 源码学习之each遍历 行数 2809&3162
<button id="test1">jQuery遍历祖先</button> <button id="test2">模拟遍历祖先</button> <ul class="level-1"> <li class="item-i">I</li> <li class="item-ii">II <ul class="level-2"> <li class="item-a">A</li> <li class="item-b">B <ul class="level-3"> <li class="item-1">1</li> <li class="item-2">2</li> <li class="item-3">3</li> </ul> </li> <li class="item-c">C</li> </ul> </li> <li class="item-iii">III</li> </ul>
<script type="text/javascript"> //遍历祖先 function parent(elem) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; // parent.nodeType !== 11 // nodeType==11 节点是 DocumentFragment parentNode 为null // nodetype见下图 1.1 } function parents(elem){ var matched = []; // console.log(matched); while ( (elem = elem[ 'parentNode' ]) && elem.nodeType !== 9 ) { // nodetype是Document 代表整个文档(DOM 树的根节点)。 if ( elem.nodeType === 1 ) { matched.push( elem ); } } return matched; } function parentsUntil(elem, filter) { var matched = [], until, truncate = filter !== undefined; while ((elem = elem['parentNode']) && elem.nodeType !== 9) { if (elem.nodeType === 1) { if (truncate) { if(elem.nodeName.toLowerCase() ==filter){ break; } } matched.push(elem); } } return matched; } $("#test1").click(function(){ var item = $('.item-1'); console.log(item); // console.log(item.parent()) console.log( item.parents()) // console.log( item.parentsUntil('body')) }) $("#test2").click(function(){ var item = document.querySelectorAll('.item-1')[0] console.log(parent(item)) console.log(parents(item).length) console.log(parentsUntil(item, 'body').length) }) // 遍历同胞 function dir(elem, dir, until) { var matched = [], truncate = until !== undefined; while ((elem = elem[dir]) && elem.nodeType !== 9) { if (elem.nodeType === 1) { if (truncate) { if (elem.nodeName.toLowerCase() == until || elem.className == until) { break; } } matched.push(elem); } } return matched; } function nextAll(elem) { return dir(elem, "nextSibling"); } function prevAll(elem) { return dir(elem, "previousSibling"); } function nextUntil(elem, until) { return dir(elem, "nextSibling", until); } function prevUntil(elem, until) { return dir(elem, "previousSibling", until); } $("#test1").click(function(){ var item = $('li.item-ii'); console.log(item) console.log(item.nextAll()) console.log(item.prevAll()) console.log(item.nextUntil('.end')) console.log(item.prevUntil('.first')) }) $("#test2").click(function(){ var item = document.querySelectorAll('li.item-ii')[0] console.log(nextAll(item)[0].className) console.log(prevAll(item)[0].className) console.log(nextUntil(item, '.end')[0].className) console.log(prevUntil(item, '.first')[0].className) }) .next() 获得匹配元素集合中每个元素紧邻的同辈元素。 .prev() 获得匹配元素集合中每个元素紧邻的前一个同辈元素,由选择器筛选(可选)。 .siblings() 获得匹配元素集合中所有元素的同辈元素,由选择器筛选(可选)。 function sibling(cur, dir) { while ((cur = cur[dir]) && cur.nodeType !== 1) {} return cur; } function next(elem) { return sibling(elem, "nextSibling"); } function prev(elem) { return sibling(elem, "previousSibling"); } var thirdItem = document.querySelectorAll('.third-item')[0] $("#test1").click(function(){ var thirdItem = document.querySelectorAll('.third-item')[0] alert(prev(thirdItem).innerHTML) }) $("#test2").click(function(){ var thirdItem = document.querySelectorAll('.third-item')[0] alert(next(thirdItem).innerHTML) }) children() find() //遍历子代元素 $("#test1").click(function(){ $('.level-2').children().each(function(i,ele){ $('div').append('<li>jQuery.children方法,子元素的className为:'+ ele.className + '</li>') }) }) $("#test2").click(function() { function sibling(n, elem) { var matched = []; for (; n; n = n.nextSibling) { //如果存在下一个兄弟节点 if (n.nodeType === 1 && n !== elem) { //是元素节点,且不是当前选择器元素 matched.push(n); } } return matched; } var ul = document.querySelectorAll('.level-2')[0]; //遍历所有元素 $.each(sibling(ul.firstChild), function(i, ele) { $('div').append('<li>模拟children方法,子元素的className为:' + ele.className + '</li>') }) })