问题
I use this code to add or remove certain nodes from a page I have on my site:
function nextChild() {
var elem = document.getElementById('formtbody');
var a = 0;
var b = elem.childNodes[a];
var node = b.style.display;
var lastnode = 0;
while (node !== "none") {
(lastnode++);
(a++);
}
(lastnode++);
var c = lastnode;
var therightnode = elem.childNodes[c];
return therightnode;
}
function addRemoveClass(option) {
var elem = document.getElementById('formtbody');
if (option === "add") {
nextChild().style.display = "";
} else if (option === "remove") {
elem.lastChild.style.display = "none";
elem.lastChild.form.reset();
}
}
I execute with addRemoveClass("add")
and addRemoveClass('remove')
But when I try to add, it goes unresponsive. I think it's getting stuck in an infinite loop but I can't tell.
I've tried JS Lint but it didn't find anything either.
What I'm trying to do with this script is find the first child node of formtbody
with the style="display:none;"
attribute and make it visible.
回答1:
This code is an infinite loop if node !== "none"
when the loop starts:
while (node !== "none") {
(lastnode++);
(a++);
}
Nothing in the loop changes the value of node
so once the loop starts, it will never stop.
Also, this syntax is odd and not required:
(lastnode++);
Remove the parens so it's just:
lastnode++;
Using the jQuery library (which makes cross browser DOM manipulation sooo much easier), here's some code to find the first item in a list that is set to display: none.
Here's a working version: http://jsfiddle.net/jfriend00/Um95a/
and the code:
HTML:
<ul id="container">
<li class="show">First item</li>
<li class="hide">Second item</li>
<li class="show">Third item</li>
<li class="show">Fourth item</li>
<li class="show">Fifth item</li>
</ul>
<br><br>
<div id="result"></div>
CSS:
.hide {display: none;}
Javascript (run after page is loaded):
function findFirstDisplayNoneChild(parent) {
var result = null;
$("#" + parent + " li").each(function() {
if ($(this).css("display") == "none") {
result = this;
return(false); // break out of each() function
}
});
return(result);
}
var hidden = findFirstDisplayNoneChild("container");
if (hidden) {
$("#result").html("Hidden Element: '" + hidden.innerHTML + "'");
} else {
$("#result").html("No hidden elements found");
}
Or, any even simpler version of the code using the :hidden selector:
http://jsfiddle.net/jfriend00/Xsgmu/
function findFirstDisplayNoneChild(parent) {
return($("#" + parent + " li:hidden").get(0));
}
回答2:
while (node !== "none") {
(lastnode++);
(a++);
}
is an infinite loop since the value of node does not change in the loop. If node !== "none"
when the loop is reached it will never be equal to "none"
回答3:
function nextHiddenChild(element) {
var child = element.firstChild;
while (child && child.style.display !== 'none') {
child = child.nextSibling;
}
return child
}
function addRemoveClass(option) {
var elem = document.getElementById('formtbody');
if (option === "add") {
elem = nextHiddenChild(elem);
if (elem !== null) {
elem.style.display = '';
}
} else if (option === "remove") {
elem.lastChild.style.display = 'none';
elem.lastChild.form.reset();
}
}
But I recommend you use a library like jQuery. Seriously, you're wasting time learning the nitty gritty of direct DOM manipulation. If you have a job to do besides academic learning the DOM inside and out, such as getting a site built, then go get jQuery or prototype or MooTools or any other library and use it. Later, if you have time, you can come back and see how it all works.
Also, addressing your questions about the variables a
and b
: they are just scalar values. They're not reference types, not objects. Just because you used a
in an earlier statement to get a value out of an array doesn't somehow bind that array to a
's updated value.
var arr = ['x', 'y', 'z'],
a = 0,
value;
value = arr[a];
alert(value); //'x'
a += 1;
alert(value); //notice value hasn't changed, and why should it? You haven't assigned anything to it since last time.
value = arr[a];
alert(value); // now it's 'y'
来源:https://stackoverflow.com/questions/6714917/my-browser-goes-unresponsive-when-i-try-to-execute-this-js