Javascript数组变量在循环中丢失

时间:2013-04-05 18:47:33

标签: javascript variables loops tinymce

所以我试图在wordpress上的tinyMCE wysiwyg编辑器中加入其他按钮。他们出现并正在运作(有点)。单击时,它们只是输出数组中的最后一个变量,这很奇怪,因为我在循环中的其他位置使用变量,它工作正常。

(function() {
  tinymce.create('tinymce.plugins.col', {
    init : function(ed, url) {
      var col_id = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'];
      for(var i = 0; i < col_id.length; i++){
        var colNum = col_id[i];
        ed.addButton(colNum+'_col', {
          title : colNum+' Column',
          image : url+'/images/mce/'+colNum+'.png',
          onclick : function() {
            ed.selection.setContent('['+colNum+'_col]' + ed.selection.getContent() + '[/'+colNum+'_col]');
           }
         }); // ***** Col *****
         ed.addButton(colNum+'_col_first', {
           title : colNum+' Column First',
           image : url+'/images/mce/'+colNum+'.png',
           onclick : function() {
             ed.selection.setContent('['+colNum+'_col_first]' + ed.selection.getContent() + '[/'+colNum+'_col_first]');
            }
          });  // ******  Col First ******
          ed.addButton(colNum+'_col_last', {
            title : colNum+' Column Last',
            image : url+'/images/mce/'+colNum+'.png',
            onclick : function() {
              ed.selection.setContent('['+colNum+'_col_last]' + ed.selection.getContent() + '[/'+colNum+'_col_last]');
            }
          });   //*********  Col Last **********
        }
      },
      createControl : function(n, cm) {
        return null;
      },
    });
    tinymce.PluginManager.add('col', tinymce.plugins.col);
  })();

当我点击其中一个按钮时会发生什么,它会输出[eleven_col] [/ eleven_col]的短代码,这会让我感到困惑,因为标题和图像网址输出正确。

2 个答案:

答案 0 :(得分:3)

我认为这是经典的闭包问题,可以在此解释:JavaScript closure inside loops – simple practical example

在此for循环中包裹所有内容:

(function (colNum) {
    // Your code in the for loop
})(col_id[i]);

然后移除var colNum = col_id[i];

所以最终的代码如下所示:

(function() {
    tinymce.create('tinymce.plugins.col', {
        init : function(ed, url) {
            var col_id = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'];
            for(var i = 0; i < col_id.length; i++){
                (function (colNum) {    // <---------------------- ADDED THIS
                    ed.addButton(colNum+'_col', {
                        title : colNum+' Column',
                        image : url+'/images/mce/'+colNum+'.png',
                        onclick : function() {
                            ed.selection.setContent('['+colNum+'_col]' + ed.selection.getContent() + '[/'+colNum+'_col]');

                        }
                    }); // ***** Col *****

                    ed.addButton(colNum+'_col_first', {
                        title : colNum+' Column First',
                        image : url+'/images/mce/'+colNum+'.png',
                        onclick : function() {
                            ed.selection.setContent('['+colNum+'_col_first]' + ed.selection.getContent() + '[/'+colNum+'_col_first]');

                        }
                    });  // ******  Col First ******

                    ed.addButton(colNum+'_col_last', {
                        title : colNum+' Column Last',
                        image : url+'/images/mce/'+colNum+'.png',
                        onclick : function() {
                            ed.selection.setContent('['+colNum+'_col_last]' + ed.selection.getContent() + '[/'+colNum+'_col_last]');

                        }
                    });   //*********  Col Last **********
                })(col_id[i]);    // <------------------------- ADDED THIS
            }
        },
        createControl : function(n, cm) {
            return null;
        }
    });
    tinymce.PluginManager.add('col', tinymce.plugins.col);
})();

答案 1 :(得分:3)

@Ian的答案是正确的,但您可能希望以这种方式组织代码,在循环中使用命名函数而不是an IIFE

该函数的col_id参数实际上是不必要的,因为该函数具有col_id变量的可见性,但我认为这样更清晰。

(function () {
    tinymce.create('tinymce.plugins.col', {
        init: function (ed, url) {
            function handleColumn(col_id, i) {
                // loop code in here
            }

            var col_id = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'];
            for (var i = 0; i < col_id.length; i++) {
                handleColumn(col_id, i);
            }
        },
        createControl: function (n, cm) {
            return null;
        },
    });
    tinymce.PluginManager.add('col', tinymce.plugins.col);
})();