Javascript 如何查找当前选择的 DOM 对象的所有兄弟节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4378784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find all Siblings of the currently selected DOM object
提问by user504023
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 to get length of all next siblings excluding white-space, any spaces or line-breaks.
在 JavaScript 中查找所有 nextSiblings 和 previousSiblings 的完美方法是什么?我尝试了几种方法,但没有得到准确的解决方案。如果选择了任何元素,我需要获取所有下一个兄弟元素的长度,不包括空格、任何空格或换行符。
Also I don't want to use jQuery for this. I am specifically looking something from JavaScript
我也不想为此使用 jQuery。我专门从 JavaScript 中寻找一些东西
采纳答案by user113716
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.
我假设这发生在一个事件处理程序中,其中this
是对您想要影响其兄弟的目标元素的引用。
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"
回答by subhaze
This is a bit more winded of a solution but allows you to create a filter on how you get siblings.
这是一个更复杂的解决方案,但允许您创建一个关于如何获得兄弟姐妹的过滤器。
There are three functions to get onlyprevious, onlynext, or all. This could be improved but decent starting point if you need more control on what types of siblings you want to collect. Thought it might be worth adding.
有三个函数来获取只有以前,只有未来,或全部。如果您需要更多地控制要收集的兄弟姐妹类型,这可以改进但不错的起点。认为它可能值得添加。
get all next siblings
得到所有下一个兄弟姐妹
//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;
}
get all previous siblings
获取所有以前的兄弟姐妹
//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;
}
get all siblings
得到所有兄弟姐妹
//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 to apply to above functions
应用于上述函数的示例过滤器
// 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 and testing output
HTML 和测试输出
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
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 );
回答by Stéphane Divin
Here is a very short and simple way to do it with ES6:
这是使用 ES6 执行此操作的一种非常简短的方法:
function getAllSiblings(element, parent) {
const children = [...parent.children];
return children.filter(child => child !== element);
}
This will return all children of the parent node that are not the element.
这将返回不是元素的父节点的所有子节点。
回答by SLaks
You can get all of the children of the element's parent, and exclude the element itself.
您可以获取元素父元素的所有子元素,并排除元素本身。
回答by Mottie
This is an update to @subhaze's answer.
这是@subhaze 答案的更新。
This code uses the matches
DOM methodwhich is supported in modern browsers:
该代码使用matches
DOM方法这是在现代浏览器都支持:
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;
}
Use these functions as follows:
使用这些函数如下:
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]');
回答by pery mimon
back to 2017:
Maybe there is a better answer but that good and a little bit cleaner
回到 2017 年:
也许有更好的答案,但那很好而且更简洁
function sibiling(dom, query) {
var doms = dom.parentElement.querySelectorAll(query);
return [].slice.call(doms).filter( d => d != dom);
}
回答by abbotto
This answer was previously published herein 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.
仅供参考:jQuery 代码库是观察 A 级 Javascript 的绝佳资源。
Here is an excellant tool that reveals the jQuery code-base in a very streamlined way.http://james.padolsey.com/jquery/
这是一个出色的工具,它以非常精简的方式展示了 jQuery 代码库。http://james.padolsey.com/jquery/
回答by Nicolás Arévalo
Just my two cents here, I made a couple of functions to get all the previos and the next siblings of any element.
在这里只需两美分,我做了几个函数来获取任何元素的所有前一个和下一个兄弟元素。
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;
};
You just have to call this functions with a node that you can get by getElementById.
您只需要使用可以通过 getElementById 获取的节点来调用此函数。
回答by Shittabey Babblebey
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. previousElementSiblingand immediate younger sibling i.e. nextElementSibling). Lol!
下面的这个实际上帮助我通过父母选择了所有兄弟姐妹(并且最初不包括所选项目本身)(唯一知道您不认识的兄弟姐妹的人是您的父母,这很有趣,您唯一认识的人是您的直系兄弟姐妹,即previousElementSibling和直系弟弟妹妹,即nextElementSibling)。哈哈!
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
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
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);
如果我决定使用孩子的“id”,我的链式过滤器方法应该是: .filter(sibling => sibling.id !== selected.id);
See Demo
看演示
回答by Humoyun Ahmad
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;
}
}