How to find all Siblings of the currently selected DOM object

前端 未结 11 1165
轻奢々
轻奢々 2020-12-08 04:25

What is the perfect way to find all nextSiblings and previousSiblings in JavaScript. I tried few ways but not getting accurate solution. If any element is selected, I need t

相关标签:
11条回答
  • 2020-12-08 05:03

    You can get all of the children of the element's parent, and exclude the element itself.

    0 讨论(0)
  • 2020-12-08 05:04

    This answer was previously published here in response to a similar question .

    There are a few ways to do it.

    Either one of the following should do the trick.

    // 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: The jQuery code-base is a great resource for observing Grade A Javascript.

    Here is an excellant tool that reveals the jQuery code-base in a very streamlined way. http://james.padolsey.com/jquery/

    0 讨论(0)
  • 2020-12-08 05:06

    A simple solution using ES2015 (spread & indexOf)

    const getSiblings = (elm, withTextNodes) => {
      if( !elm || !elm.parentNode ) return
      
      let siblings = [...elm.parentNode[withTextNodes ? 'childNodes' : 'children']],
          idx = siblings.indexOf(elm);
      
      siblings.previous = siblings.slice(0, idx)
      siblings.next = siblings.slice(idx + 1)
      
      return siblings
    }
    
    // Usage example:
    const testElm = document.querySelector('em');
    const testElmSiblings = getSiblings(testElm);
    
    console.log(
      testElmSiblings.previous,
      testElmSiblings.next,
      testElmSiblings
    )
    <div></div>
    text node 1
    <a></a>
    <p></p>
    <em></em>
    <main></main>
    text node 2
    <hr/>
    <b></b>

    0 讨论(0)
  • 2020-12-08 05:10

    I'll assume that this takes place inside an event handler where this is a reference to the targeted element whose siblings you want to affect.

    If not, adjustments will be needed.

    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"
    
    0 讨论(0)
  • 2020-12-08 05:10

    This specifically helps you select all siblings of a selected item

    This one below actually helped me select ALL SIBLINGS (and that originally excludes the selected item itself) through the PARENT (the only person who knows your siblings that you don't know is your parent right, its funny that the only ones YOU know are your immediate elder sibling i.e. previousElementSibling and immediate younger sibling i.e. nextElementSibling). Lol!

    The Code

    const allSiblings = Array.from(YOUR_SELECTION.parentElement.children)
                             .filter(sibling => sibling.UNIQUE_PropertyName !== (YOUR_SELECTION.COMPARABLE/UNIQUE_PropertyName));
    
    // You don't have to save in a variable if you don't want to
    

    Example

    HTML

    <div id="mummy">
        <div id="baby_1">Samuel</div>
        <div id="baby_2">Dave</div>
        <div id="baby_3">Shaun</div>
        <div id="baby_4">Michael</div>
        <div id="baby_5" class="selected">Fazlullah</div>
        <div id="baby_6">Samson</div>
        <div id="baby_7">Bais</div>
    <div>
    

    Javascript

    // I have decide to use the Names of the children as my UNIQUE_Property, So i can get that with the .textContent propertyName 
    
    const selected = document.querySelector('.selected'); // So with "Fazlullah" selected
    
    const allSiblings = Array.from(selected.parentElement.children) // I got to know his mum (.parentElement), then the mum's children(.children)
                             .filter(sibling => sibling.textContent !== selected.textContent); // And this now get's me a list (actually an Array) of his siblings that he doesn't even know.
    
    allSiblings.forEach(sibling => {
        console.log(sibling.textContent);
    });
    

    If i decide to use the children "id", my chained filter method would have looked: .filter(sibling => sibling.id !== selected.id);

    See Demo

    0 讨论(0)
  • 2020-12-08 05:16

    All previous siblings

    // jQuery (optional filter selector)
    $el.prevAll($filter);
    
    // Native (optional filter function)
    function getPreviousSiblings(elem, filter) {
      var sibs = [];
      while (elem = elem.previousSibling) {
          if (elem.nodeType === 3) continue; // ignore text nodes
          if (!filter || filter(elem)) sibs.push(elem);
      }
      return sibs;
    }
    

    All next siblings

    // jQuery (optional selector filter)
    $el.nextAll($filter);
    
    // Native (optional filter function)
    function getNextSiblings(elem, filter) {
            var sibs = [];
            var nextElem = elem.parentNode.firstChild;
            do {
                if (nextElem.nodeType === 3) continue; // ignore text nodes
                if (nextElem === elem) continue; // ignore elem of target
                if (nextElem === elem.nextElementSibling) {
                    if (!filter || filter(elem)) {
                        sibs.push(nextElem);
                        elem = nextElem;
                    }
                }
            } while(nextElem = nextElem.nextSibling)
            return sibs;
        }
    

    An example of filter function:

    function exampleFilter(elem) {
      switch (elem.nodeName.toUpperCase()) {
        case 'DIV':
          return true;
        case 'SPAN':
          return true;
        default:
          return false;
      }
    }
    
    0 讨论(0)
提交回复
热议问题