如何查找当前选定的DOM对象的所有兄弟节点
如何找到当前选定的DOM对象的所有兄弟姐妹
有三个函数来获取仅前一个、仅后一个或全部的兄弟姐妹。这个方法可能还有改进的空间,但如果你需要更多控制要收集哪些类型的兄弟姐妹,这是一个不错的起点。可能值得添加。
获取所有后续兄弟姐妹
//从当前元素开始获取所有后续兄弟姐妹 function getNextSiblings(elem, filter) { var sibs = []; while (elem = elem.nextSibling) { if (elem.nodeType === 3) continue; //文本节点 if (!filter || filter(elem)) sibs.push(elem); } return sibs; }
获取所有上一个兄弟姐妹
//从当前元素开始获取所有上一个兄弟姐妹 function getPreviousSiblings(elem, filter) { var sibs = []; while (elem = elem.previousSibling) { if (elem.nodeType === 3) continue; //文本节点 if (!filter || filter(elem)) sibs.push(elem); } return sibs; }
获取所有兄弟姐妹
//从当前元素的父节点的第一个子节点开始获取所有兄弟姐妹 function getAllSiblings(elem, filter) { var sibs = []; elem = elem.parentNode.firstChild; do { if (elem.nodeType === 3) continue; //文本节点 if (!filter || filter(elem)) sibs.push(elem); } while (elem = elem.nextSibling) return sibs; }
应用于上述函数的示例过滤器
//示例过滤器仅计算div和span元素,但可以更复杂 function exampleFilter(elem) { switch (elem.nodeName.toUpperCase()) { case 'DIV': return true; case 'SPAN': return true; default: return false; } }
HTML和测试输出
asdfsdfasdfasdfasdfaad
JavaScript
var elem; elem = document.getElementById('test2'); //带有过滤器的返回4 alert(getNextSiblings(elem, exampleFilter).length); //没有过滤器,返回7 elem = document.getElementById('test2'); alert(getNextSiblings(elem).length); //返回0 elem = document.getElementById('test2'); alert(getPreviousSiblings(elem, exampleFilter).length); //返回5 elem = document.getElementById('test2'); alert(getAllSiblings(elem, exampleFilter).length);
通过使用do/while
循环而不是while
循环,可以消除getAllSiblings
函数中的冗余。通过使用条件||
替换if/else
,可以稍微减少代码量,如下所示:if(!filter || filter( elem )) sibs.push( elem );
那些是很棒的示例。不过,我对为什么需要"exampleFilter"函数感到困惑。
它只是一个过滤器的基本示例,但并不是必需的。
getNextSiblings( elem )
不应该返回15个元素,演示中只有7个。之所以有15个是因为它返回了文本节点。如果你从每个函数中删除!filter ||
,它就会忽略文本节点。此外,请查看我的答案,它使用了matches
DOM方法,允许使用类名和属性选择器。
哦,哇,是的...很好的发现。现在网络发展了大约6年,新的API使事情变得更容易了:P。关于匹配,值得注意的一点是,我相信IE需要一个前缀。
你可以使用previousElementSibling
来过滤掉不匹配的节点类型。
谢谢,我会尽量在有时间的时候更新为现代API。
问题的出现原因是用户想要找到当前选定DOM对象的所有兄弟元素,并对它们进行操作。解决方法是通过遍历当前选定DOM对象的父节点的所有子节点,将类型为元素节点且不等于当前选定DOM对象的节点添加到一个结果数组中。
具体代码如下:
var result = [], node = this.parentNode.firstChild; while ( node ) { if ( node !== this && node.nodeType === Node.ELEMENT_NODE ) result.push( node ); node = node.nextElementSibling || node.nextSibling; }
这段代码会将所有类型为元素节点且不等于当前选定DOM对象的兄弟节点添加到结果数组中。
然后,用户提出另一个问题,即将webkit样式应用于结果数组中的元素,但动画不起作用。解答者建议用户在Stack Overflow上搜索解决方案,如果找不到答案,可以再次提问。
用户尝试使用循环将样式应用于结果数组中的所有元素,但发现只有第一次点击有效,再次点击其他对象时不起作用。解答者表示可能是与webkitTransform属性的工作方式有关,无法提供更多帮助。
最后,用户提到自己对JavaScript还比较新,并感谢解答者的帮助。解答者解释了如何接受答案,并对只有第一次点击有效的问题进行了解释。
最后,还有其他用户提出了对代码中的一个问题的疑问,解答者对这个问题进行了修复。
通过以上整理,我们得到了解决问题的过程以及相关的讨论和解答。
原因:文章中提到了一个问题,即如何找到当前选中的DOM对象的所有兄弟节点。
解决方法:文章给出了两种解决方法。第一种方法使用ES6的扩展运算符和filter方法,通过获取父节点的所有子节点,然后筛选出不是当前元素的节点,即可得到所有兄弟节点。第二种方法是使用ES2015的箭头函数和父节点的children属性,通过筛选出不是当前元素的子节点,即可得到所有兄弟节点。
以下是整理后的
如何找到当前选中的DOM对象的所有兄弟节点?下面提供了两种简洁的解决方法。
第一种方法使用了ES6的扩展运算符和filter方法。代码如下:
function getAllSiblings(element, parent) {
const children = [...parent.children];
return children.filter(child => child !== element);
}
这段代码将返回父节点的所有子节点中不是当前选中元素的节点,即为所有兄弟节点。
第二种方法使用了ES2015的箭头函数和父节点的children属性。代码如下:
const getSiblings = elm => elm && elm.parentNode && [...elm.parentNode.children].filter(node => node != elm)
这段代码通过筛选出不是当前选中元素的子节点,得到了所有兄弟节点。
以上就是两种简洁的方法,可以帮助我们找到当前选中的DOM对象的所有兄弟节点。