web-dev-qa-db-fra.com

Comment trouver tous les frères et sœurs de l'objet actuellement sélectionné

Quel est le moyen idéal pour trouver tous les nextSiblings et previousSiblings en javascript. J'ai essayé plusieurs moyens mais je n'ai pas trouvé de solution précise. si un élément est sélectionné, je dois obtenir la longueur de tous les frères et soeurs suivants, à l'exception des espaces, des espaces ou des sauts de ligne

Aussi, je ne veux pas utiliser jquery pour cela, je cherche spécifiquement quelque chose à partir d'un script Java

S'il vous plaît des conseils

20
user504023

Je suppose que cela se produit dans un gestionnaire d'événements, où this est une référence à l'élément ciblé dont vous souhaitez affecter les frères et sœurs. 

Sinon, des ajustements seront nécessaires.

var result = [],
    node = this.parentNode.firstChild;

while ( node ) {
    if ( node !== this && node.nodeType === Node.ELEMENT_NODE ) 
      result.Push( node );
    node = node.nextElementSibling || node.nextSibling;
}

// result will contain all type 1 siblings of "this"
17
user113716

Ceci est un peu plus complexe, mais vous permet de créer un filtre sur la façon dont vous obtenez un frère ou une soeur.

Il y a trois fonctions pour obtenir seulement précédent, seulement suivant ou tout . Cela pourrait être amélioré mais bon point de départ si vous avez besoin de plus de contrôle sur les types de frères et sœurs que vous souhaitez collecter. Pensé que cela pourrait être intéressant d'ajouter.

Exemple de travail

obtenir tous les prochains frères et soeurs

//this will start from the current element and get all of the next siblings

function getNextSiblings(elem, filter) {
    var sibs = [];
    while (elem = elem.nextSibling) {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.Push(elem);
    }
    return sibs;
}

obtenir tous les frères et sœurs précédents

//this will start from the current element and get all the previous siblings

function getPreviousSiblings(elem, filter) {
    var sibs = [];
    while (elem = elem.previousSibling) {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.Push(elem);
    }
    return sibs;
}

obtenir tous les frères et sœurs

//this will start from the first child of the current element's parent and get all the siblings

function getAllSiblings(elem, filter) {
    var sibs = [];
    elem = elem.parentNode.firstChild;
    do {
        if (elem.nodeType === 3) continue; // text node
        if (!filter || filter(elem)) sibs.Push(elem);
    } while (elem = elem.nextSibling)
    return sibs;
}

exemple de filtre à appliquer aux fonctions ci-dessus

// Example filter only counts divs and spans but could be made more complex
function exampleFilter(elem) {
    switch (elem.nodeName.toUpperCase()) {
        case 'DIV':
            return true;
        case 'SPAN':
            return true;
        default:
            return false;
    }
}

HTML et sortie de test

HTML

<div id='test'>
    <div id='test2'>asdf</div>
    <br /> sdf
    <div>asdfasdf<span>asdf</span></div>
    <div>a</div>
    <span>a</span>
    <br />
    <div>d</div>
    <hr/>
</div>

JavaScript

var elem;
elem = document.getElementById('test2');

//with filter alerts 4
alert( getNextSiblings( elem, exampleFilter ).length );

// no filter, alerts 7
elem = document.getElementById('test2');// put elem back to what it was
alert( getNextSiblings( elem ).length );

// alerts 0
elem = document.getElementById('test2');// put elem back to what it was
alert( getPreviousSiblings( elem, exampleFilter ).length );

// alerts 5
elem = document.getElementById('test2');// put elem back to what it was
alert( getAllSiblings( elem, exampleFilter ).length );
20
subhaze

Voici un moyen très simple et rapide de le faire avec ES6:

function getAllSiblings(element, parent) {
        const children = [...parent.children];
        return children.filter(child => child !== element);
    }

Cela renverra tous les enfants du nœud parent qui ne sont pas l'élément.

4
Stéphane Divin

Vous pouvez obtenir tous les enfants du parent de l'élément et exclure l'élément lui-même.

4
SLaks

retour à 2017:
Peut-être qu'il y a une meilleure réponse mais que c'est bon et un peu plus propre

function sibiling(dom, query) {
   var doms = dom.parentElement.querySelectorAll(query);
   return [].slice.call(doms).filter( d => d != dom);
}
2
pery mimon

Ceci est une mise à jour de la réponse de @ subhaze.

Ce code utilise la méthode DOM - matches qui est prise en charge par les navigateurs modernes :

Démo

function matches(elem, filter) {
  if (elem && elem.nodeType === 1) {
    if (filter) {
      return elem.matches(filter);
    }
    return true;
  }
  return false;
}

// this will start from the current element and get all of
// the next siblings
function getNextSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.nextSibling) {
    if (matches(elem, filter)) {
      sibs.Push(elem);
    }
  }
  return sibs;
}

// this will start from the current element and get all the
// previous siblings
function getPreviousSiblings(elem, filter) {
  var sibs = [];
  while (elem = elem.previousSibling) {
    if (matches(elem, filter)) {
      sibs.Push(elem);
    }
  }
  return sibs;
}

// this will start from the first child of the current element's
// parent and get all the siblings
function getAllSiblings(elem, filter) {
  var sibs = [];
  elem = elem.parentNode.firstChild;
  while (elem = elem.nextSibling) {
    if (matches(elem, filter)) {
      sibs.Push(elem);
    }
  } 
  return sibs;
}

Utilisez ces fonctions comme suit:

var elem = document.querySelector('#test');

// find all the "div" and "span" siblings
var after = getNextSiblings(elem, 'div, span');

// find previous siblings with ".list-item" class
var index = getPreviousSiblings(elem, '.list-item');

// get all siblings with a title attribute
var allSibs = getAllSiblings(elem, '[title]');
2
Mottie

Cette réponse a été publiée précédemment ici en réponse à une question similaire.

Il y a plusieurs façons de le faire.

L'un ou l'autre des éléments suivants devrait faire l'affaire.

// 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 code jQuery est une excellente ressource pour l’observation de Javascript de classe A.

Voici un excellent outil qui révèle la base de code jQuery de manière très simple. http://james.padolsey.com/jquery/

1
abbotto

Juste mes deux cents ici, j'ai fait quelques fonctions pour obtenir toutes les previos et les prochains frères et sœurs de n'importe quel élément.

const getPreviousAll = element => {
  const previousAllFound = [];
  const getPrevious = element => {
    if (element !== null) {
      previousAllFound.Push(element);
      const previousFound = element.previousElementSibling;
      if (previousFound !== null) {
        getPrevious(previousFound);
      }
    }
  };
  getPrevious(element.previousElementSibling);
  return previousAllFound;
};
const getNextAll = element => {
  const target = element;
  const nextAllFound = [];
  const getAll = element => {
    if (element !== null) {
      nextAllFound.Push(element);
      const nextFound = element.nextElementSibling;
      if (nextFound !== null) {
        getAll(nextFound);
      }
    }
  };
  getAll(element.nextElementSibling);
  return nextAllFound;
};

Vous devez simplement appeler cette fonction avec un noeud que vous pouvez obtenir avec getElementById.

0