2009-05-09 10 views
61

Por algunas razones de rendimiento, estoy tratando de encontrar una manera de seleccionar solo los nodos hermanos del nodo seleccionado. Por ejemplo,¿Hay alguna manera de seleccionar los nodos hermanos?

<div id="outer"> 
     <div id="inner1"> </div> 
     <div id="inner2"> </div> 
     <div id="inner3"> </div> 
     <div id="inner4"> </div> 
</div> 

Si he seleccionado nodo inner1, ¿hay alguna manera de acceder a sus hermanos, los nodos inner2-4?

Respuesta

94

Bueno ... claro ... solo acceda al padre y luego a los niños.

node.parentNode.childNodes[] 

o ... usando jQuery:

$('#innerId').siblings() 

Editar: Cletus como siempre está inspirando. Cavé más. Así es como jQuery obtiene esencialmente hermanos:

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); 
} 
+15

Tenga en cuenta que jquery.siblings() excluye el nodo actual del conjunto de resultados. – cletus

+2

¡Cuál es una característica muy agradable! – cgp

+1

En realidad, el equivalente de node.parentNode.childNodes [] en jquery es realmente $ (nodo) .parent(). Children() not $ (node) .siblings(). Puede ser una buena característica, pero también puede ser molesto. Depende de lo que quieras. – cletus

-1
var childNodeArray = document.getElementById('somethingOtherThanid').childNodes; 
+0

window.document.documentElement.childNodes [1] .childNodes [4] recogido de http://www.howtocreate.co.uk/tutorials/javascript/dombasics – Thunderboltz

+0

¿Es alguna solución a la pregunta? – zahid9i

+0

Esto no resuelve el problema en cuestión, o al menos no lo suficientemente claro como para ser útil. – cdeszaq

66
var sibling = node.nextSibling; 

Esto devolverá el hermano inmediatamente después de ella, o nulos no más hermanos están disponibles. Del mismo modo, puede usar previousSibling.

[Editar] Pensándolo bien, esto no dará la siguiente etiqueta div, pero los espacios en blanco después del nodo. Mejor parece ser

var sibling = node.nextElementSibling; 

También existe una previousElementSibling.

+0

siguiente/anteriorElementSibling no es compatible con IE8 – Vadim

+0

A partir de IE9 lo es. Ver también http://stackoverflow.com/questions/5197825/parentnode-or-previouselementsibling-not-working-in-ie8 – parvus

6

¿Has marcado el método "Hermanos" en jQuery?

sibling: function(n, elem) { 
     var r = []; 

     for (; n; n = n.nextSibling) { 
      if (n.nodeType === 1 && n !== elem) { 
       r.push(n); 
      } 
     } 

     return r; 
    } 

la n.nodeType == 1 cheque si el elemento es un nodo html y n! == excluir el elemento actual.

Creo que puede usar la misma función, todo ese código parece ser vainilla javascript.

6

Hay algunas formas de hacerlo.

Cualquiera de los siguientes debe hacer el truco.

// 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; 
} 

FYI: La base de código jQuery es un gran recurso para la observación de grado A Javascript.

Aquí se encuentra una herramienta excelente que revela la base de código jQuery de una manera muy simplificada. http://james.padolsey.com/jquery/

-2
x1 = document.getElementById('outer')[0] 
     .getElementsByTagName('ul')[1] 
     .getElementsByTagName('li')[2]; 
x1.setAttribute("id", "buyOnlineLocationFix"); 
1

Uso document.querySelectorAll() y Loops and iteration

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>

-1

He aquí cómo usted podría conseguir anterior, siguiente y todos los hermanos (ambos lados):

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); 
} 
4

rápida:

var siblings = n => [...n.parentElement.children].filter(c=>c!=n) 

https://codepen.io/anon/pen/LLoyrP?editors=1011

sacar a los niños de los padres como una matriz, el filtro cabo este elemento.

+1

Buena solución. Aunque, verificaría que nodeType descarte el nodo de texto '[... n.parentNode.children] .filter (c => c.nodeType == 1 && c! = N)' – pmrotule

2

De 2017:
respuesta directa: element.nextElementSibling para obtener el hermano del elemento correcto. También tiene element.previousElementSibling anterior para

de aquí es bastante simple tiene todo junto sibiling

var n = element, ret = []; 
while (n = n.nextElementSibling){ 
    ret.push(n) 
} 
return ret; 
+0

Debería devolver todos los hermanos, no solo 'next' o' previous'. Especificar exactamente ir hacia atrás o hacia adelante no ayuda mucho en este caso. – dvLden

+1

por qué no. si tomas el próximo y el anterior puedes obtener la imagen completa. que es la respuesta viene a mostrar una nueva forma de hacer las cosas. y contribuir algo a los lectores. solo para ir a los padres e ir a cada elemento y filtrar el actual que todos pueden hacer –

Cuestiones relacionadas