2013-04-05 75 views
1

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

(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],这让我困惑,因为标题和图片的网址正确地输出会发生什么。

回答

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); 
})(); 
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); 
})(); 
+0

我喜欢这个:)我经常忘记这个约定是一个明确的替代 – Ian 2013-04-05 18:58:09