其他分享
首页 > 其他分享> > 【学习笔记】JS 在循环中设置监听事件并使用 ajax 设置动态添加的元素的值时出现的问题及其解决方案

【学习笔记】JS 在循环中设置监听事件并使用 ajax 设置动态添加的元素的值时出现的问题及其解决方案

作者:互联网

问题

for(var i = 1 ; i <= 10 ; i ++) { // 注意循环变量 i
    var newLine = "<tr>";
    newLine += "<td><input type='text' id='sampleInput" + i + "'></td>";
    newLine += "<td><span id='sampleSpan" + i + "'></td>";
    newLine += "</tr>";
    // 动态为 newLine 追加 HTML,id 与循环变量有关
    
    $("#sampleTable tbody").append(newLine);
    // 往已存在的 table 中添加新的这一行
    
    $("#sampleInput" + i).on("input", function(){ //这里设置的监听对象是没问题的,能够实现对于 sampleInput i 的监听
        $.ajax({
            type: "get",
            url: "sampleAction",
            // data: {}, 假装这里有传别的值
            success: function(data){
                // data = eval("(" + data + ")");
                $("#sampleSpan" + i).html(data); // 这里想修改 sampleSpan i 的值
            }
        });
    });
}

上面这一段 \(JS\) 代码,意图是往 \(sampleTable\) 中插入十行,每行一个文本框 \(sampleInput\{i\}\) 和一个行内元素 \(sampleSpan\{i\}\)

然后对于每行的文本框,只要触发了 \(input\) 事件就向后台发送请求,将获取到的数据在同一行的行内元素上显示出来


但这段代码的事实却是,不论修改哪个文本框,行内元素都没有效果


实际上在 \(ajax\) 的 \(success\) 匿名函数里看看 \(i\) 的值就清楚了,加一行 \(alert\) 输出,发现所有 \(i\) 的值都是 \(11\)

这是因为 \(ajax\) 只有执行完请求且获得数据后才会执行 \(success\) 匿名函数,这一部分与循环是异步执行的,也就是说在执行这个函数的时候可能外头的 \(for\) 循环已经结束了(终值就是 \(11\))

而在函数内调用 \(i\) 这个变量是通过地址去取值的,并没有把执行 \(ajax\) 时的 \(i\) 的值缓存下来,才会出现上面的这种情况


这里可能有人会说,我直接把 \(ajax\) 的异步关了就是了 async: false

所以上面的例子里在外层套了个监听

监听事件触发的时候循环肯定是执行完了的,与这个异步没有关系


解决

解决方法,把需要的值通过 \(ajax\) 传给后端,让后端重新传回来,问题解决(简单粗暴)

因为传入值时还没有开始异步执行,引用的 \(i\) 是会缓存当时的值的

for(var i = 1 ; i <= 10 ; i ++) {
    var newLine = "<tr>";
    newLine += "<td><input type='text' id='sampleInput" + i + "'></td>";
    newLine += "<td><span id='sampleSpan" + i + "'></td>";
    newLine += "</tr>";
    
    $("#sampleTable tbody").append(newLine);
    
    $("#sampleInput" + i).on("input", function(){
        $.ajax({
            type: "get",
            url: "sampleAction",
            data: {id: i}, // 把需要的值 i 传给后端
            success: function(data){
                data = eval("(" + data + ")");
                var i = data.id; // 让 action 再把它返回来就是了
                $("#sampleSpan" + i).html(data.data);
            }
        });
    });
}

后记:

挺奇妙的,在 debug 的时候竟然没有遇到“无法找到动态添加的元素”的问题

本来我是往这个方向想的,于是就舍弃了通过 id 来查找元素,换了其他麻烦的方法(相对位置检索大法)

然后重新回来看这个问题,越看越奇怪,于是输出了一下循环变量,直接豁然开朗……

标签:值时,function,success,newLine,JS,ajax,设置,data,监听
来源: https://www.cnblogs.com/stelayuri/p/16088829.html