Javascript

【学习笔记】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 来查找元素,换了其他麻烦的方法(相对位置检索大法)

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

这篇关于【学习笔记】JS 在循环中设置监听事件并使用 ajax 设置动态添加的元素的值时出现的问题及其解决方案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!