误解了Javascript函数调用

时间:2014-05-20 15:22:23

标签: javascript jquery closures

我尝试自定义HTML file input并编写了最简单的jquery API函数:

(function($)
{    
  $.fn.selectFileInputGUI = function()
  { 
    var outerWrapper = $('<div>').css({'display':'inline-block'});
    var innerWrapper = $('<div>').css({'width':'0', 'height':'0', 'overflow':'hidden'});
    var fileInput    = $('<input>').attr({type:'file'});
    var fileNameHTML = $('<div>').css({'display':'inline-block', 'margin-left':'3px'});

    var selectBtnGUI = $('<button>').addClass('btn btn-success btn-sm').text('Select file').click(function()
       {
          $.fn.selectFileInputGUI.resetInput();
          fileInput.trigger('click');
       });

       fileInput.on('change', function()
       {   
          $.fn.selectFileInputGUI.displayFileName();
       });

    $(this)
    .append(outerWrapper.append(innerWrapper.append(fileInput)).append(selectBtnGUI))
    .append(fileNameHTML);

   $.fn.selectFileInputGUI.displayFileName = function()
   {
      var fileName = fileInput.val();
      if(fileName.length > 0)
      {
          var pos = fileName.lastIndexOf("\\");
          if(pos != -1) fileName = fileName.substr(pos + 1);
          if(fileName.length > 14) fileName = fileName.substr(0, 14) + '...';
       } else
       {
          fileName = 'File not selected';
       }
       fileNameHTML.text(fileName);
};


   $.fn.selectFileInputGUI.resetInput = function()
   {           
     fileInput.wrap('<form>').parent('form').trigger('reset');
     fileInput.unwrap();
   };   
}
})(jQuery);

当我尝试将selectFileInputGUI api函数应用于多个选择器时,只有最后一个选择器处理得很好 - http://jsfiddle.net/URKM5/5/

如何正确实施?

1 个答案:

答案 0 :(得分:1)

在用户选择文件后,您的问题就在于如何重复使用变量fileInputfileNameHTML,并且您将此$.fn.selectFileInputGUI.displayFileName();称为fileInput和{{ 1}}总是引用第二个fileDialog的fileNameHTMLfileInput(因为第二个fileDialog在第一个和所有这些变量被覆盖之后被初始化)。因此,要解决此问题,您必须通过所谓的 事件数据 传递这些变量,在这种情况下它非常有用:

fileNameHTML

您的//Note the second argument, it's passed in as event data //You can access the event data via e.data fileInput.on('change', fileNameHTML, function(e) { $.fn.selectFileInputGUI.displayFileName($(this), e.data); }); 需要接受2个参数,第一个引用displayFileName(可以fileInput传递给$(this) onchange事件处理程序1}}),第二个引用fileInput(以fileNameHTML传入)。

e.data

现在选择2个对话框之间的文件是独立的。

Demo.

在深入研究问题之后,看起来您不需要在此处使用事件数据。只需将//note about the change of the arguments $.fn.selectFileInputGUI.displayFileName = function(fileInput, fileNameHTML) { //the code is unchanged here ... } 权限作为第二个参数传递给fileNameHTML函数。的 Updated Demo