值未正确传递给函数onClick

时间:2012-10-30 06:12:27

标签: javascript-events pass-by-value function-call

            gameDesign = {          

                          makeSeats: function( num ) {  //num = number of seats 


                                    var seats = [];
                                    var seat;

                                    var seatWidth = 20;
                                    var seatHeight = 20;
                                    var total = 100;

                                    for( var i=1; i<= num; i++ ) {

                                        seat = $('<div id="seat_'+i+'" class="seats"><div id="index_'+i+'" style="height:100%; width:100%;"><div style="height:100%; width:100%;">Sit Here</div></div></div>');

                                        seat.children(":first").children(":first").click( function(event, i){ 
                                                                                                                var tim = i;
                                                                                                                gameDesign.sitOnIndexNo( tim ); });

                            },

                           sitOnIndexNo: function( seatIndex ) {

                                   tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
                           }

                    }

问题:单击“坐在这里”索引值正在作为未定义传递..我知道这是与闭包相关的东西..但是,我需要进一步的解释和解决方案..

提前完成

3 个答案:

答案 0 :(得分:1)

首先,您已声明'click'eventHandler接受'i'参数作为第二个参数。但是,jquery参数只传递单个事件对象作为eventHandler的第一个参数。这意味着,当你将'tim'指定为'i'时,它会提出未定义的。

其次,在更改此项后,如果您再次运行代码,则't''等于'num'+ 1,因为被引用的'i'属于'makeSeats'函数范围,并不作为功能的一部分存储。

你想要的是这样的:

for(var i = 0; i <= num; i++){
    $('.foo').click({i:i}, function(e){
        gameDesign.sitOnIndexNo(e.data.i);
    });
}

有关'data'属性的更多信息,可以找到过去eventHandler的here

答案 1 :(得分:1)

function(event, i){ ...

期待i,因为它是第二个参数,其正文中的任何i与其正文之外的任何i无关。

jQuery只将一个参数传递给它调用的事件处理程序 - 事件。另外,它将目标元素传递为this。这意味着第二个参数始终为undefined

如果你这样做:

for(var i=0; i<num; i++){
   var seat = $("...");
   seat.find("...").click(function(e){
     gameDesign.sitOnIndexNo(i)
   )
}

在值更改后访问变量i。您可以创建一个自调用函数来捕获i:

的值
for(var i=0; i<num; i++){
   var seat = $("...");
   var handler = (function(i){
     return function(event){
       gameDesign.sitOnIndexNo(i)
     )
   })(i);
   seat.find("...").click(handler);
}

...或使用seat.data,如@ClarkPan所建议。

答案 2 :(得分:1)

你提到“点击”,所以我假设你计划生成所有这些div,说“坐在这里”。当用户单击“坐在这里”时,将调用函数sitOnIndexNo。基于这个假设,这是我的建议:

gameDesign = {          
    makeSeats: function( num ) {  //num = number of seats 
        for( var i=1; i<= num; i++ ) {
            $("#id_of_element_where_you_want_to_put_the_div").
            append('<div id="'+i+'" class="seats" style="height:100%; width:100%;">Sit Here</div></div></div>');
        }
    },
    sitOnIndexNo: function( seatIndex ) {
        tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
    }
}

// Event handler:
$(".seats").live("click", (function(e) {
    var tim = $(this).attr("id");
    gameDesign.sitOnIndexNo(tim);
});

基本上, makeSeats 函数会生成“坐在这里”div,它们的点击事件由新的事件处理程序处理。