此代码旨在为每个没有“ShowThis”类的元素或者该类的后代添加样式“display:none”:
var x = document.getElementsByTagName('*');
for(var i = x.length; i--;){
x[i].style.display = 'none';
if((' '+x[i].className+' ').indexOf(' ShowThis ') >= 0){
var y = x[i];
while(y){
if(y.nodeType === 1){
console.log(y.style.cssText); // Outputs: "display: none;"
console.log(y.style.display); // Outputs: "none"
y.style.display = 'block';
console.log(y.style.display); // Outputs: "block"
console.log(y.style.cssText); // Outputs: "display: block;"
// ERROR here:
// Outputs the elements HTML (Chrome Console),
// But the style attribute isn't changed
// EX. <div style="display: none;">...</div>
console.log(y);
}
y = y.parentNode;
}
}
}
这是一个JSFiddle:http://jsfiddle.net/Paulpro/wEq8X/
如果您注释掉if(y.nodeType === 1){
和匹配的}
(http://jsfiddle.net/Paulpro/wEq8X/1/),或者我将if语句更改为if(y.nodeType)
或if(true)
,则可以正常工作这对我来说没有任何意义,因为程序流正在输入if语句(所有console.log
都被执行)。
我已尝试将if语句更改为if(typeof y.style !== 'undefined')
,但其行为也不正确。 (完全相同的问题)
我需要测试nodeType或样式以防止在尝试访问文档的样式属性时出错,但是测试其中任何一个都会给我带来这种奇怪的行为。
我可以在Chrome,Firefox和IE中重复此操作。
答案 0 :(得分:2)
您的代码将包含块设置为“display:none”。在那之后,内部<div>
是“display:block”无关紧要。
您倾倒元素的诊断技术存在缺陷。如果你使用Chrome调试器或Firebug之类的东西,你会发现你的“ShowThis”元素确实在其“style”属性中有“display:block”。但是,它没有显示,因为它的所有父元素(包括<body>
标记)仍然是“display:none”。
编辑我认为问题可能源于页面元素在“getElementsByTagName()”结果中出现的顺序。如果在子元素之后到达父元素,那么它们将被设置为“display:none”在之后它们被设置为“display:block”。
再次编辑 - 已确认。从“getElementsByTagName()”返回的元素以逆序的形式返回,它们出现在HTML中。因此,代码在外部循环中看到的最后一个元素是“ShowThis”<div>
的容器<div>
。
再次编辑哦,我看到了 - 你要倒退!!杜尔。如果你继续通过节点列表,它应该工作。
答案 1 :(得分:1)
你问的是你的外部循环隐藏了所有东西,然后在你设置为display ='block'之后隐藏'showthis'节点的父节点。如果你将隐藏和显示分成两个步骤,它就可以正常工作。
var y, x = document.getElementsByTagName('*');
for(var i = 0, len = x.length; i < len; i++){
x[i].style.display = 'none';
}
x = document.getElementsByClassName('ShowThis');
for(var i = 0, len = x.length; i < len; i++) {
y = x[i];
while(y){
if(y.nodeType === 1){
y.style.display = 'block';
}
y = y.parentNode;
}
}
另外,只是为了记录,这种类型的东西是jQuery很棒的地方。
jQuery('*').hide();
jQuery('.ShowThis').show().parents().show();