Есть ли способ выбрать одноуровневые узлы?
по некоторым причинам производительности я пытаюсь найти способ выбрать только одноуровневые узлы выбранного узла. Например,
<div id="outer">
<div id="inner1"> </div>
<div id="inner2"> </div>
<div id="inner3"> </div>
<div id="inner4"> </div>
</div>
Если я выбрал узел inner1, есть ли способ для меня получить доступ к его братьям и сестрам,inner2-4
узлы?
10 ответов:
хорошо... конечно... просто получите доступ к родителю, а затем к детям.
node.parentNode.childNodes[]
или... с помощью jQuery:
$('#innerId').siblings()
Edit: Клетус, как всегда, вдохновляет. Я копнул дальше. Вот как jQuery получает братьев и сестер по существу:
function getChildren(n, skipMe){ var r = []; for ( ; n; n = n.nextSibling ) if ( n.nodeType == 1 && n != skipMe) r.push( n ); return r; }; function getSiblings(n) { return getChildren(n.parentNode.firstChild, n); }
var sibling = node.nextSibling;
это вернет брата сразу после него, или null больше не доступны братья и сестры. Кроме того, вы можете использовать
previousSibling
.[Edit] на второй мысли, это не даст следующий
div
- тег, но пробел после точки. Лучше, вроде быvar sibling = node.nextElementSibling;
есть
previousElementSibling
.
есть несколько способов сделать это.
либо один из следующих должен сделать трюк.
// METHOD A (ARRAY.FILTER, STRING.INDEXOF) var siblings = function(node, children) { siblingList = children.filter(function(val) { return [node].indexOf(val) != -1; }); return siblingList; } // METHOD B (FOR LOOP, IF STATEMENT, ARRAY.PUSH) var siblings = function(node, children) { var siblingList = []; for (var n = children.length - 1; n >= 0; n--) { if (children[n] != node) { siblingList.push(children[n]); } } return siblingList; } // METHOD C (STRING.INDEXOF, ARRAY.SPLICE) var siblings = function(node, children) { siblingList = children; index = siblingList.indexOf(node); if(index != -1) { siblingList.splice(index, 1); } return siblingList; }
к вашему сведению: базы исходного кода jQuery является отличным ресурсом для наблюдения класс В JavaScript.
вот отличный инструмент, который показывает кодовую базу jQuery очень упрощенным способом. http://james.padolsey.com/jquery/
быстрый:
var siblings = n => [...n.parentElement.children].filter(c=>c!=n)
https://codepen.io/anon/pen/LLoyrP?editors=1011
получить дочерние элементы родителя в виде массива, отфильтровать этот элемент.
Edit:
и отфильтровать текстовые узлы (спасибо pmrotule):
var siblings = n => [...n.parentElement.children].filter(c=>c.nodeType == 1 && c!=n)
вы проверили метод" брат " в jQuery?
sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; }
n. nodeType == 1 проверьте, является ли элемент HTML-узлом и n!== исключить текущий элемент.
Я думаю, что вы можете использовать ту же функцию, весь этот код, кажется, ванильный javascript.
С 2017 года:
прямой ответ:element.nextElementSibling
для получения правильного элемента sibling. также у вас естьelement.previousElementSibling
для предыдущегоотсюда довольно просто получить все следующие sibiling
var n = element, ret = []; while (n = n.nextElementSibling){ ret.push(n) } return ret;
вот как вы могли бы получить предыдущий, следующий и все братья и сестры (с обеих сторон):
function prevSiblings(target) { var siblings = [], n = target; while(n = n.previousElementSibling) siblings.push(n); return siblings; } function nextSiblings(target) { var siblings = [], n = target; while(n = n.nextElementSibling) siblings.push(n); return siblings; } function siblings(target) { var prev = prevSiblings(target) || [], next = nexSiblings(target) || []; return prev.concat(next); }
использовать документ.querySelectorAll() и циклы и итерации
function sibblingOf(children,targetChild){ var children = document.querySelectorAll(children); for(var i=0; i< children.length; i++){ children[i].addEventListener("click", function(){ for(var y=0; y<children.length;y++){children[y].classList.remove("target")} this.classList.add("target") }, false) } } sibblingOf("#outer >div","#inner2");
#outer >div:not(.target){color:red}
<div id="outer"> <div id="inner1">Div 1 </div> <div id="inner2">Div 2 </div> <div id="inner3">Div 3 </div> <div id="inner4">Div 4 </div> </div>