如何查找当前所选DOM对象的所有同级元素

问题描述 投票:26回答:9

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

而且我也不想为此使用jQuery。我特别在寻找JavaScript的内容

javascript dom
9个回答
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"

25
投票

这是一种解决方案,但可以让您创建有关如何获取兄弟姐妹的筛选器。

有三个函数可以使only上一个,only下一个或all。如果您需要对要收集的兄弟姐妹类型进行更多控制,可以对此进行改进,但要有一个不错的起点。认为可能值得添加。

Working Example

获取下一个兄弟姐妹

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

获取所有以前的兄弟姐妹

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

获取所有兄弟姐妹

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

适用于上述功能的示例过滤器

// 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和测试输出

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

7
投票

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

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

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


4
投票

您可以获取元素父级的所有子级,并排除元素本身。


3
投票

这是@subhaze答案的更新。

此代码使用matches DOM method,即matches

supported in modern browsers

Demo

使用这些功能如下:

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

2
投票

回到2017年:也许有一个更好的答案,但又好又干净一点

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]');

1
投票

此答案先前针对类似问题在function sibiling(dom, query) { var doms = dom.parentElement.querySelectorAll(query); return [].slice.call(doms).filter( d => d != dom); } 中发布。

有几种方法。

以下任何一项都可以解决问题。

here

FYI:jQuery代码库是观察A级Javascript的绝佳资源。

这里是一个非常精巧的工具,可以非常简化地显示jQuery代码库。// 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; }


0
投票

仅是我的两分钱,我做了几个函数来获取任何元素的所有首字母和下一个兄弟姐妹。

http://james.padolsey.com/jquery/

您只需要使用可以通过getElementById获得的节点来调用此函数。


0
投票

以前所有的兄弟姐妹

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

[所有下一个兄弟姐妹

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

过滤器功能示例:

// 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;
    }
© www.soinside.com 2019 - 2024. All rights reserved.