Jquery-在每个数据库中使用$(this)

Jquery-在每个数据库中使用$(this),jquery,this,each,Jquery,This,Each,我是法国人,请原谅一些翻译错误 我有一个代码,使用Jquery和Ajax调用,但我不理解以下问题 我有一张第一排的桌子。 在行的末尾,有两个选项:Valid和delete。 当您单击有效图标时,将显示一个加载图标、一个新行、附加到表中、加载图标消失,并显示删除图标 当您单击删除图标时,它将删除该行 所以我的问题 开始时,我直接在图标上实现了“onclick=valid()”和“onclick=“delete()”。 但现在,我发现使用a更干净: $('#valid'+i).click(funct

我是法国人,请原谅一些翻译错误

我有一个代码,使用Jquery和Ajax调用,但我不理解以下问题

我有一张第一排的桌子。 在行的末尾,有两个选项:Valid和delete。 当您单击有效图标时,将显示一个加载图标、一个新行、附加到表中、加载图标消失,并显示删除图标

当您单击删除图标时,它将删除该行

所以我的问题

开始时,我直接在图标上实现了“onclick=valid()”和“onclick=“delete()”。 但现在,我发现使用a更干净:

$('#valid'+i).click(function(){
    valid(i);
});
$('#delete'+i).click(function(){
    delete(i);
});
问题出现了:当你点击,例如在删除图标第3行,它的加载谁出现在第4行

这是密码

PHP/HTML

<?php
    include_once 'functions_sandbox.php';
?>
<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.9.0.min.js" type="text/javascript"></script>
    </head>
    <body>
    <script type="text/javascript">
        //Fonction qui charge les datepicker et les différentes options sur les champs
        function reload_jquery(){
            $('input[type=text][id*=tags]').each(function() {
                i = $(this).attr('num');
                $(this).css('border','thin blue solid');
                $('#valid'+i).click(function(){
                    valid_temps(i);
                });
                $('#delete'+i).click(function(){
                    delete_temps(i);
                });             
            });     
        }   
        function valid_temps(i){
            $('#loading'+i).show();
            $('#valid'+i).hide();
            var variables = 'mode=saisie_temps&j='+$('#j').val();
            $.ajax(
                {
                    // Define AJAX properties.
                    type: "POST",
                    url: "/dgi/ajax_sandbox.php",
                    data : variables,
                    dataType: "html",
                    timeout: 6000,

                    // Define the succss method.
                    success: function(data)
                    {
                        $('#data_retour').append(data);
                        $('#loading'+i).hide();
                        $('#delete'+i).show();                  
                        $('#j').val(parseInt($('#j').val())+1);
                        reload_jquery();
                    }
                }
            );      
        }
        function delete_temps(i){
            $('#loading'+i).show();
            $('#delete'+i).hide();
            $( "#confirm").dialog({
                resizable: false,
                height:160,
                width: 350,
                modal: true,
                buttons: {
                    "Oui": function() {
                        supp_temps(i);
                        $(this).dialog( "close" );
                    },
                    "Non": function() {
                        $('#loading'+i).hide();
                        $('#delete'+i).show();
                        $(this).dialog( "close" );
                    }
                }
            });
        }
        function supp_temps(i){
            $('#ligne'+i).hide('slow');
        }   

    $(function(){
        reload_jquery();
    });

    </script>
    <table id="data_retour" class="module">
        <?php echo ligne_saisie_sandbox(0); ?>
    </table>
    <div style="display:none" id="confirm" title="Confirmation">Voulez-vous vraiment supprimer ce temps ?</div> 
    <label>Indice J : </label>
    <input type="text" value="1" id="j" name="j" />
</body>
</html>
一个小图片来说明这个问题


您的问题之所以出现,是因为您在这一行中遗漏了
var

i = $(this).attr('num');
通过取消
var
,您使
i
成为一个全局变量,这使得回调中的
i
s(
delete_temps(i);
)都指向全局
i
,而不是本地
i

将该行更改为:

var i = $(this).attr('num');
它应该可以工作。我还建议不要使用自定义属性。使用HTML5
data-
attributes:

<input type="text" id="tags'.$j.'" data-num="'.$j.'" />

您遇到的是JavaScript中的一个常见问题。这是一个闭包问题。您在这一行中隐式声明了一个名为
i
的变量

i = $(this).attr('num');
由于它是隐式声明的,所以它也是全局的。这将导致
的每次迭代。每个()
使用相同的变量

在您的情况下,您必须选择如何解决它。JavaScript中的变量具有函数作用域,并且由于您从不重写i的值,因此您可以简单地显式声明变量,如下所示:

var i = $(this).attr('num');
通常建议显式声明变量,如果您像这样启动函数,实际上可以让大多数JS引擎为您检查这一点

function(){
  "use strict";
  //...
}
另一种选择是对此类闭包问题的更一般的解决方案 $('#有效'+i)。单击(函数(){ 有效时间(i); }); $('#删除'+i)。单击(函数(){ 删除第(i)段; }))

你可以把它改成

i = $(this).attr('num')       
(function(i){
  $('#valid'+i).click(function(){
      valid_temps(i);
  });
  $('#delete'+i).click(function(){
      delete_temps(i);
  });
})(i);
不同之处在于,在您的代码中,在调用方法之前,不会对i求值,从而为您提供在
的最后一次迭代中写入i的值。在上述代码中,会立即对each()
求值。 作为您面临的关闭问题的一个简单示例,您可以使用这段代码

var i,j, arr = [];

for(i=0;i<10;i += 1){
    //creates a function that closes over i
    arr[arr.length] = function(){console.log(i);}
}
for(j=0;j<10;j += 1){
   arr[j](); //They all output 9 to the console
}
结果是大多数人第一手期望的行为,即0..9被输出到控制台

在您的特殊情况下,仅在本地声明
i
可能是两个选项中可读性最好的,但最好知道如何避免在一般情况下关闭变量。

完美!我在变量中添加了“var”,我使用了HTML5属性,这很有效。
function(){
  "use strict";
  //...
}
i = $(this).attr('num')       
(function(i){
  $('#valid'+i).click(function(){
      valid_temps(i);
  });
  $('#delete'+i).click(function(){
      delete_temps(i);
  });
})(i);
var i,j, arr = [];

for(i=0;i<10;i += 1){
    //creates a function that closes over i
    arr[arr.length] = function(){console.log(i);}
}
for(j=0;j<10;j += 1){
   arr[j](); //They all output 9 to the console
}
arr[arr.length] = (function(k){function(){console.log(k);}})(i);