【问题标题】:Jquery - Use of $(this) in eachJquery - 在每个中使用 $(this)
【发布时间】:2013-02-23 17:36:00
【问题描述】:

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

我有一段代码,使用 Jquery 和 Ajax 调用,但我不明白下面的问题。

我有一张桌子,第一行。 在行的末尾,有两个选项:有效和删除。 点击有效图标时,会出现加载图标,出现新行,追加到表格,加载图标消失,显示删除图标。

当你点击删除图标时,它会删除该行。

所以我的问题...

一开始,我直接在图标上实现了“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>

“functions_sandbox.php”中的“ligne_saisie_sandbox”函数

function ligne_saisie_sandbox($j){
    $retour = '
    <tr id="ligne'.$j.'">
        <td class="cellule _light">
            <label>Attraction'.$j.' : </label>
            <input type="text" id="tags'.$j.'" num="'.$j.'" />

            <img src="/dgi/img/b_save.png" alt="Valid" title="Valider votre temps" title="Valider le temps" id="valid'.$j.'" style="margin-top:5px;float:right">
            <img src="/dgi/img/b_empty.png" alt="Supprimer" title="Supprimer votre temps" title="Supprimer le temps" id="delete'.$j.'" style="margin-top:5px;float:right;display:none">
            <img src="/dgi/img/ajax_clock_small.gif" alt="Load" id="loading'.$j.'" style="margin-top:5px;float:right;display:none;" />
        </td>           
    </tr>'; 
    return $retour;
}

和“ajax_sandbox.php”中的Ajax

include_once 'functions_sandbox.php';
switch ($_POST['mode'])
{
    case "saisie_temps":
        $j = $_POST['j'];
        $retour = ligne_saisie_sandbox($j);
        echo $retour;
    break;
}

一张小图来说明问题

【问题讨论】:

    标签: jquery this each


    【解决方案1】:

    您的问题出现是因为您在此行中遗漏了var

    i = $(this).attr('num');
    

    通过省略var,您将i 设为全局变量,这使得您的回调(delete_temps(i);) 中的is 都指向全局i,而不是本地i .

    将该行更改为:

    var i = $(this).attr('num');
    

    它应该可以工作。我还建议不要使用自定义属性。使用 HTML5 data- 属性:

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

    并使用.data()函数:

    var i = $(this).data('num');
    

    【讨论】:

    • 完美!我将“var”添加到我的变量中,我使用了 HTML5 属性,它的工作。
    【解决方案2】:

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

    i = $(this).attr('num');
    

    由于它是隐式声明的,它也是全局的。这将导致.each() 的每次迭代都使用相同的变量。

    在您的情况下,您必须选择如何解决它。 JavaScript 中的变量具有函数作用域,因为你永远不会覆盖 i 的值,你可以简单地像这样显式声明变量:

    var i = $(this).attr('num');
    

    通常建议显式声明变量,如果您像这样启动函数,实际上可以让大多数 JS 引擎为您检查这一点

    function(){
      "use strict";
      //...
    }
    

    另一种选择是解决这种闭包问题的更通用的方法。在这个部分 $('#valid'+i).click(function(){ 有效临时(i); }); $('#delete'+i).click(函数(){ delete_temps(i); });

    你可以改成

    i = $(this).attr('num')       
    (function(i){
      $('#valid'+i).click(function(){
          valid_temps(i);
      });
      $('#delete'+i).click(function(){
          delete_temps(i);
      });
    })(i);
    

    不同之处在于,在您的代码中,直到调用该方法时才对 i 进行评估,从而为您提供在 .each() 的最后一次迭代中写入 i 的值。在上面的代码中,i in 被立即评估。 作为您面临的关闭问题的一个简单示例,您可以使用这段代码

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

    导致大多数人期望的第一手行为,即 0..9 输出到控制台

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

    【讨论】:

      猜你喜欢
      • 2017-02-08
      • 1970-01-01
      • 2013-12-01
      • 2012-07-31
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多