Jquery binding events
Why does the handler bound to an event of an element fire the wrong result? I would expect the click event of Div1 below to popup a dialog stating 'div1' but it popup's 'div2'.
I am new to this and I am scratching my head to work out why this is happening. I would appreciate any help to 开发者_如何学Pythonexplain.
Cheers,
Alex
<!DOCTYPE html>
<html>
<head>
<title>TestEvents</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
//Object Array
var objToTest = [{ TabName: "div1" },
{ TabName: "div2"}];
//Adds events to each div
function TestWhatIsGoingOn(myObjToTest) {
for (i in myObjToTest) {
$('#' + myObjToTest[i].TabName).click(function() { TestResult('TabName: ' + myObjToTest[i].TabName); });
}
}
function TestResult(message){
alert(message);
}
$(document).ready(function() {
TestWhatIsGoingOn(objToTest);
});
</script>
<style type="text/css">
#div1, #div2
{
border: solid thin black;
height: 100px;
width: 300px;
}
</style>
</head>
<body>
<div id='div1'>div1; click here to show expected result: 'TabName: div1'</div>
<div id='div2'>div2; click here to show expected result: 'TabName: div2'</div>
</body>
</html>
it seems a classic closure problem, because when you click on div (any) i
variable has already reach the end of for
loop (so it always prints the last value). Try to change like so
function TestWhatIsGoingOn(myObjToTest) {
for (i in myObjToTest) {
(function(i) {
$('#' + myObjToTest[i].TabName).click(function() { TestResult('TabName: ' + myObjToTest[i].TabName); });
)(i);
}
}
Your problem is in this section of code:
for (i in myObjToTest) {
$('#' + myObjToTest[i].TabName).click(function() {
TestResult('TabName: ' + myObjToTest[i].TabName);
});
}
The trouble is that the value of i
is not hard-coded into this section. When the function runs, it will see what the current value of i
is. Since you have since incremented it to refer to your second tab, this function will always refer to the second tab. This feature of Javascript is called a closure -- it closes in the value of i
.
The easiest way around this is to use jQuery to bind to more than one object at once, and then evaluate based on the object clicked on:
$(document).ready(function(){
$('div').click(function(){
alert('TabName: ' + this.id);
});
});
This will do everything you want your code in the question to do.
In a real-world situation, you would probably need to give the divs a common class (e.g. toClick
) and then use a jQuery class selector ($('.toClick')
).
精彩评论