I'm very new to writing with JavaScript and am creating a basic tab navigation interface as a prototype/practice. Right now I'm trying to make an alert appear using the onclick
event handler on an unordered list of links just as a test and can't figure it out. Every time I load the page, all 5 onclick
events occur without having clicked anything. Take a look at the code and let me know if you have any suggestions:
window.onload = initAll;
var开发者_JS百科 xhr = false;
function initAll () {
var navDiv = document.getElementById("tab_navigation");
var navTabs = navDiv.getElementsByTagName("a");
for (var i = 0; i < navTabs.length; i++) {
navTabs[i].onclick = tellTab(i);
}
}
function tellTab (number) {
number = number + 1;
alert("You clicked tab number " + number);
}
The HTML structure is as follows:
<div id="tab_navigation">
<ul>
<li><a href="#1">Tab 1</a></li>
<li><a href="#2">Tab 2</a></li>
<li><a href="#3">Tab 3</a></li>
<li><a href="#4">Tab 4</a></li>
<li><a href="#5">Tab 5</a></li>
</ul>
</div>
In a for
loop, you have this line:
navTabs[i].onclick = tellTab(i);
That calls tellTab
immediately. What you can do is have tellTab
return a closure, like this:
function tellTab (number) {
return function() {
// I commented out the following line
// because I don't think it's necessary.
//number = number + 1;
alert("You clicked tab number " + number);
};
}
A different option is creating a closure inside the for
loop:
for (var i = 0; i < navTabs.length; i++) {
(function(i) {
navTabs[i].onclick = function() {
tellTab(i);
};
})(i);
}
Closures for dummies:
function initAll () {
var navDiv = document.getElementById("tab_navigation");
var navTabs = navDiv.getElementsByTagName("a");
for (var i = 0; i < navTabs.length; i++) {
setTabOnclick(navTabs[i], i);
}
}
function setTabOnclick(tab, i) {
tab.onclick = function () { tellTab(i); };
}
function tellTab(i) {
alert('clicked tab ' + i);
}
I've just realized that this is the same as icktoofay's second solution but with a named outer function.
精彩评论