删除没有属性的所有元素

时间:2014-03-06 20:31:15

标签: javascript html

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

这是html:

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

我想要的是删除容器内的所有元素,而不使用 data - * 属性。

数据 - *

该属性可以是数据 - 任何(数据颜色,数据边框等)。

我正在寻找仅限javascript的解决方案

5 个答案:

答案 0 :(得分:4)

使用.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);

function remove_nodes(el) {
    el.parentNode.removeChild(el);
}

function has_data_attrs(attr) {
    return /^data/i.test(attr.name);
}

function els_with_no_data(el) {
    return ![].some.call(el.attributes, has_data_attrs)
}

然后使用 Array generics (在支持的浏览器中,否则使用polyfiilled):

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

Array.filter(els, els_with_no_data)
     .forEach(remove_nodes);

function remove_nodes(el) {
    el.parentNode.removeChild(el);
}

function has_data_attrs(attr) {
    return /^data/i.test(attr.name);
}

function els_with_no_data(el) {
    return !Array.some(el.attributes, has_data_attrs)
}

答案 1 :(得分:2)

这应该这样做

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]);
}

FIDDLE

如果您需要支持IE7及以下版本,则必须填充

querySelector(All)

答案 2 :(得分:2)

可能有更好的方法,只需要几分钟就可以浪费,所以我想我会回答这个问题。

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
        }
    }
}

答案 3 :(得分:2)

@cookie monster的重写解决方案:

(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));

答案 4 :(得分: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]);
    }
}

Demo

相关问题