【问题标题】:probably another closure-loop issue可能是另一个闭环问题
【发布时间】:2016-08-04 07:18:56
【问题描述】:

我正在将一组注释导入我的网页,这是在本地循环读取 JSON 文件并将读取的数据附加到主 div 中。到现在都没问题。但是随后我在每个笔记旁边生成了一个 ckeditor 实例,以便客户能够轻松地将 cmets 添加到他感兴趣的笔记中。 cmets 最初生成为另一个 HTML 文件中的几个索引空 div,加载到 ckeditor 实例中。然而,所有这些都发生在一个非常大的 for 循环中(我有近 6000 个音符要使用 if 条件以分段方式加载),所以现在我正在处理经典的闭环问题。已经阅读了 foo this 和其他网站之前的几个问题和答案,并测试了其中一些以摆脱闭环问题,但到目前为止没有成功。

我的java脚本的相关段有以下结构:

var q;
$.when(
    $.ajax( ... loads the json file that contains the notes and set q=$.parseJSON(data) on success)
).then(function() {
    for(var i in q) {
         if(i is in a specific range){
                ... several lines of code for properly importing the notes ...
                ... and generating a place for the comments to appear as:
                ... +'<div id="CKEditor'+i+'" contenteditable="true" placeholder="Put your comment here!"></div>'
                ... which is appended to the main div of the webpage
                ... Now the main problematic part begins:   

                $('#temporary').empty();    // a hidden div defined somewhere in the page       
                var func = (function() {
                     var ilocal=i, tmp;
                     return function() {
                         tmp=document.getElementById('temporary').innerHTML;
                         alert(tmp);
                         CKEDITOR.instances['CKEditor'+ilocal].setData(tmp);
                     }
                })();
                $.when(
                    $('#temporary').load("NewComments.htm #verse-"+i)
                ).then(func);
         };
    };
    CKEDITOR.disableAutoInline = true;
    CKEDITOR.inlineAll();
})

也许问题不在于循环,而在于嵌套的 $.when().then(),有什么解决问题的建议吗?

【问题讨论】:

  • 我猜你的实际问题是每次迭代都使用相同的$('#temporary') div。闭包本身看起来不错。

标签: javascript for-loop closures


【解决方案1】:

问题是您的页面中只有一个$('#temporary') div,每次迭代都会重复使用和覆盖它。特别是在您的回调中

document.getElementById('temporary').innerHTML;
…
CKEDITOR.instances['CKEditor'+ilocal]

ilocal(和tmp)变量确实是 IIFE 和特定迭代的本地变量,但 document.getElementById 是全局变量。它每次都会返回相同的元素。

快速解决方法是为每个请求创建一个新元素,并在迭代期间将其分配给tmp(就像您将i 分配给ilocal)而不是在调用func 时。
然而,更好的做法是不要多次使用 $('#temporary').load("NewComments.htm #verse-"+i),而是在每个 Ajax 中只加载一次 NewComments.htm 并根据需要处理结果。

【讨论】:

  • 非常感谢您提到document.getElementById 是全球性的,也感谢您提出宝贵的建议
猜你喜欢
  • 2021-12-16
  • 1970-01-01
  • 2011-10-19
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多