如何查找当前所选对象的所有兄弟姐妹

use*_*023 26 javascript unobtrusive-javascript

在javascript中查找所有nextSiblings和previousSiblings的完美方式是什么?我尝试了几种方法但没有得到准确的解决方案 如果选择了任何元素,我需要得到所有下一个兄弟的长度,不包括空格,任何空格或换行符

另外我不想为此使用jquery,我特意从java脚本中查找内容

请指教

sub*_*aze 25

这是一个解决方案有点多,但允许您创建一个关于如何获得兄弟姐妹的过滤器.

有三个函数来获取只有以前,只有未来,或全部.如果您需要更多地控制您想要收集的兄弟姐妹类型,这可以改善但是起点不错.认为它可能值得添加.

工作实例

得到所有下一个兄弟姐妹

//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;
}
Run Code Online (Sandbox Code Playgroud)

得到所有以前的兄弟姐妹

//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;
}
Run Code Online (Sandbox Code Playgroud)

得到所有兄弟姐妹

//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;
}
Run Code Online (Sandbox Code Playgroud)

示例过滤器以应用于上述功能

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

HTML和测试输出

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>
Run Code Online (Sandbox Code Playgroud)

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 );
Run Code Online (Sandbox Code Playgroud)


use*_*716 21

我假设这发生在事件处理程序中,其中this是对您想要影响其兄弟的目标元素的引用.

如果没有,则需要进行调整.

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"
Run Code Online (Sandbox Code Playgroud)


小智 6

这是使用ES6的一种非常简短的方法:

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

这将返回不是该元素的父节点的所有子节点。

  • 不错的[Spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)。使用它和 `children.splice(0,1+children.indexOf(element));` 你可以获得所有下一个兄弟姐妹。 (2认同)

vsy*_*ync 5

使用ES2015 的简单解决方案(spread & indexOf

const getSiblings = (elm, withTextNodes) => {
  if( !elm || !elm.parentNode ) return
  
  let siblings = [...elm.parentNode[withTextNodes ? 'childNodes' : 'children']],
      idx = siblings.indexOf(elm);
  
  siblings.before = siblings.slice(0, idx)
  siblings.after = siblings.slice(idx + 1)
  
  return siblings
}


// Usage example:

const $elm = document.querySelector('em') // target node 
const elmSiblings = getSiblings($elm)

console.log("Siblings Before <em/>:", print(elmSiblings.before))
console.log("Siblings After <em/>:", print(elmSiblings.after))
console.log("All Siblings of <em/>:", print(elmSiblings))

function print(elms){
  return JSON.stringify(elms.map(n => n.tagName || n.textContent))
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
text node 1
<a></a>
<p></p>
<em></em>
<main></main>
text node 2
<hr/>
<b></b>
Run Code Online (Sandbox Code Playgroud)