如何查找当前选定的DOM对象的所有兄弟节点

23 浏览
0 Comments

如何查找当前选定的DOM对象的所有兄弟节点

如何在JavaScript中找到所有的nextSiblings和previousSiblings的最佳方法?我尝试了几种方式,但没有得到准确的解决方案。如果选择了任何元素,我需要获取除了空格、换行或空白字符之外的所有next siblings的长度。同时,我不想使用jQuery来实现这个功能。我特别寻找的是JavaScript的解决方案。

0
0 Comments

如何找到当前选定的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和测试输出

asdf
sdf
asdfasdfasdf
a
a
d

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。

0
0 Comments

问题的出现原因是用户想要找到当前选定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还比较新,并感谢解答者的帮助。解答者解释了如何接受答案,并对只有第一次点击有效的问题进行了解释。

最后,还有其他用户提出了对代码中的一个问题的疑问,解答者对这个问题进行了修复。

通过以上整理,我们得到了解决问题的过程以及相关的讨论和解答。

0
0 Comments

原因:文章中提到了一个问题,即如何找到当前选中的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对象的所有兄弟节点。

0