开发者

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')).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜