我尝试了解如何删除没有指定属性的所有子元素,例如:
这是html:
<div class="container">
<span></span>
<div></div>
<strong data-*></strong>
<p></p>
<div data-*></div>
</div>
我想要的是删除容器内的所有元素,而不使用 data - * 属性。
数据 - *
该属性可以是数据 - 任何(数据颜色,数据边框等)。
我正在寻找仅限javascript的解决方案。
答案 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]);
}
如果您需要支持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]);
}
}