0
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 );
               }

        }

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

4

3 回答 3

1

首先,您已声明“click”事件处理程序以接受“i”参数作为第二个参数。但是,jquery 参数只通过单个事件对象作为第一个参数传递给 eventHandler。这意味着,当您将 'tim' 指定为 'i' 时,它会出现 undefined。

其次,在改变这个之后,如果你再次运行你的代码,你会得到'tim'等于'num'+1,因为被引用的'i'属于'makeSeats'函数范围,并且不作为函数的一部分存储。

你想要的是这样的:

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

可以在此处找到有关 eventHandler 过去的“数据”属性的更多信息。

于 2012-10-30T06:23:04.980 回答
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 所建议的那样。

于 2012-10-30T06:27:29.133 回答
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函数会生成“Sit Here” div,并且它们的点击事件由新的事件处理程序处理。

于 2012-10-30T06:42:51.643 回答