Javascript 删除所有不带属性的元素

Javascript 删除所有不带属性的元素,javascript,html,Javascript,Html,我试图了解如何删除没有指定属性的所有子元素,例如: 这是html: <div class="container"> <span></span> <div></div> <strong data-*></strong> <p></p> <div data-*></div> </div> 我想要的是删除容器中的所有元素,并且不带

我试图了解如何删除没有指定属性的所有子元素,例如:

这是html:

<div class="container">
  <span></span>
  <div></div>
  <strong data-*></strong>
  <p></p>
  <div data-*></div>
</div>


我想要的是删除容器中的所有元素,并且不带data-*属性

数据-*

属性可以是数据任何内容(数据颜色、数据边框等)

我正在寻找只使用javascript的解决方案

这应该可以

var parent = document.querySelector('.container');
var elems  = parent.querySelectorAll('*');

for (var i=elems.length; i--;) {
    var attr    = elems[i].attributes,
        hasData = false;

    for (var j = attr.length; j--;) {
        if ( attr[j].name.indexOf('data') === 0 ) {
            hasData = true;
            break;
        }
    }

    if ( ! hasData ) parent.removeChild(elems[i]);
}

querySelector(All)
如果需要支持IE7及以下版本,则必须对其进行多填充。

使用
.filter()
。some()
。forEach()
应该可以做到这一点

var els = document.querySelectorAll(".container *");

[].filter.call(els, function(el) {
    return ![].some.call(el.attributes, function(attr) {
        return /^data/i.test(attr.name);
    });
}).forEach(function(el) {
    el.parentNode.removeChild(el);
});

您将需要旧浏览器的补丁,但您可能已经知道了


如果像我一样,您喜欢可重用函数:

var els = document.querySelectorAll(".container *");

[].filter.call(els, els_with_no_data)
  .forEach(remove_nodes);


然后使用数组泛型(在支持的浏览器中,否则为多边形):


试试这个:

var objects = document.querySelectorAll('.container *');
var parent = document.getElementsByClassName('container')[0];

for (var i = objects.length - 1; i >= 0; i--) {
    if (objects[i].attributes[0]) {
        if (objects[i].attributes[0].name.indexOf('data-') == -1) {
            parent.removeChild(objects[i]);
        }
    } else {
        parent.removeChild(objects[i]);
    }
}

可能有更好的方法,只是浪费了几分钟,所以我想我会玩弄答案

var container = document.getElementsByClassName("container")[0];
var children = container.childNodes;

for (var i=children.length-1;i--) {

    var child = children[i];    
    if (child.nodeType===1) {  //make sure it is an element, not a text node
        var hasMatch = false;
        var attrs = child.attributes;  //get the attributes of the element
        for(var j=0; j<attrs.length;j++){  //loop through
            if(attrs[j].nodeName.indexOf("data-")===0) {  //if it starts we have a match
               hasMatch = true;
               break;
            }
        }
        if (!hasMatch) {
            container.removeChild(child);  //if no match, remove it
        }
    }
}
var container=document.getElementsByClassName(“container”)[0];
var children=container.childNodes;
for(var i=children.length-1;i--){
var child=childs[i];
如果(child.nodeType==1){//请确保它是一个元素,而不是一个文本节点
var hasMatch=false;
var attrs=child.attributes;//获取元素的属性

对于
@cookie monster
的(var j=0;j返工解决方案):

(function r (nodelist) {
    // reduceRight is used only to walk in reverse direction
    [].reduceRight.call(nodelist, function (dummy, e) {
        if ([].every.call(e.attributes, function(a) {
            return !/^data/i.test(a.name);
        })) return e.parentNode.removeChild(e);
        r(e.children);
    }, "filler");
}(document.getElementsByClassName("container")[0].children));

如果你使用jQuery,现在是时候说出来了?你能展示你真正的HTML吗?我不会在这个项目中使用jQuery。如果你使用jQuery,这将是一个解决方案:只要发布它,以防有人在搜索中找到它。这是可能的,但速度会非常慢。(检查页面上的所有元素,将属性加载到数组中,搜索数组中的
数据-
,如果不匹配,最后删除该元素)
\u明白了!你需要反向收集。否则你可能会访问
el.parentNode
,因为
qSA
将父节点放在第一位。@kirilloid:Hmmm…我不明白。即使先删除父节点,也不应该有任何东西阻止子节点被删除(虽然这是不必要的)。还是我遗漏了什么?是的,我错了。分离的DOM节点不会为其子节点自动变为
null
s。为了优化,重新排序可能很有趣。实际上,您需要“自己”遍历节点然后。@kirilloid:如果我们有一个外循环,或者如果只有一个
容器
,我们可以做
如果(container.compareDocumentPosition(el)&16){
…除非我认为你不想要
.every()
。只有当当前元素的每个属性都是
数据属性时,这才是真的。
没关系,你是对的。我已经把它转过来了。没有看到regexp上的否定。你能不能发布一个FIDDLE+1我将对此进行投票,它基本上和我想到的是一样的,而不是所有其他答案的过于聪明和愚蠢。
var objects = document.querySelectorAll('.container *');
var parent = document.getElementsByClassName('container')[0];

for (var i = objects.length - 1; i >= 0; i--) {
    if (objects[i].attributes[0]) {
        if (objects[i].attributes[0].name.indexOf('data-') == -1) {
            parent.removeChild(objects[i]);
        }
    } else {
        parent.removeChild(objects[i]);
    }
}
var container = document.getElementsByClassName("container")[0];
var children = container.childNodes;

for (var i=children.length-1;i--) {

    var child = children[i];    
    if (child.nodeType===1) {  //make sure it is an element, not a text node
        var hasMatch = false;
        var attrs = child.attributes;  //get the attributes of the element
        for(var j=0; j<attrs.length;j++){  //loop through
            if(attrs[j].nodeName.indexOf("data-")===0) {  //if it starts we have a match
               hasMatch = true;
               break;
            }
        }
        if (!hasMatch) {
            container.removeChild(child);  //if no match, remove it
        }
    }
}
(function r (nodelist) {
    // reduceRight is used only to walk in reverse direction
    [].reduceRight.call(nodelist, function (dummy, e) {
        if ([].every.call(e.attributes, function(a) {
            return !/^data/i.test(a.name);
        })) return e.parentNode.removeChild(e);
        r(e.children);
    }, "filler");
}(document.getElementsByClassName("container")[0].children));