2

我正在尝试查找 body 标记内的所有元素,但是有一个元素 (div) 具有某种“隐藏”类类型,我想将它及其子元素从我的元素数组中排除。

这是我的 var,其中包含正文中的所有元素:

allTagsInBody = document.body.getElementsByTagName('*');

这是我想从此列表中排除的 div:

<div class="myHiddenElement"> 
    <button>Click here</button>
    <div> <button>Click here</button> </div>
    <button>Click here</button>
</div>

问题是我不知道该 div 中有多少元素以及它们的嵌套程度。

4

4 回答 4

1
document.querySelectorAll( '*:not(.myHiddenElement)' );

.querySelectorAllwith css2 :not()选择器会做到这一点。

于 2012-10-29T20:58:11.140 回答
1

当你遍历每个元素时,你不仅需要检查它是否有你的隐藏类,而且它的任何父元素是否有这个类。因此,您需要递归地检查每个元素的父元素。这可能会非常昂贵,具体取决于页面上元素的数量以及它们的嵌套深度,但这是它的完成方式:

var arr = [];
var len;
var i;
var nodes = document.querySelectorAll('body *');

function checkNode(node) {
    if (node.classList.contains('myHiddenElement')) {
        return true;        
    } else if (node.parentNode.nodeType === 1) {
        return checkNode(node.parentNode);
    }

    return false;
};

for (i = 0, len = nodes.length; i < len; i++) {
    if (checkNode(nodes[i])) {
        continue;
    } else {
        arr.push(nodes[i]);
    }
}

这是一个 JSFiddle 示例:http: //jsfiddle.net/xzCfs/5/

不幸的是,我认为没有办法使用 CSS 选择器来做到这一点,因为 :not() 选择器只接受简单的选择器,而不接受复合的选择器(例如, :not(.myHiddenClass *) <-- 如果可行的话会很棒)。

于 2012-10-30T00:32:22.203 回答
0

试试这个

​​var elems = document.body.childNodes;
var filtered = Array();  //holds elements that doesn't have 'myHiddenElement' class

​for(var i=0; i<elems.length; i++)
{
    if(elems[i].className != 'myHiddenElement')
      filtered.push(elems[i]);
}
于 2012-10-29T21:03:49.177 回答
0

如果一切都失败了,你总是可以递归地遍历 DOM(这是所有库所做的):

这是一个通用的 DOM 遍历函数:

# Note: Even though this function accepts a callback it is synchronous:

function traverse (node, callback) {
    // The callback function must return true to continue processing
    // otherwise stop processing down this branch:
    if (callback(node)) {
        for (var i=0;i < node.childNodes.length; i++) {
            traverse(node.childNodes[i],callback);
        }
    }
}

因此,要建立您的收藏:

var elements = [];
traverse(document,function(node){
    // We only care about element nodes, ignore comments, attributes etc:
    if (node.nodeType == 1 && node.className != "myHiddenElement") {
        elements.push(node);
        return true; // continue parsing this branch
    }
    return false; // ignore this branch and its children
});
于 2012-10-29T23:19:01.747 回答