jQuery匿名函数通过事件委派运行两次,应该只运行一次

jQuery匿名函数通过事件委派运行两次,应该只运行一次,jquery,Jquery,第一次张贴。有一些jquery问题,这需要一段时间,但我能够解决它,现在我只想知道为什么 我有一个CMS,我试图通过一个lightbox填充2个表单字段,一次一个,lightbox通过AJAX调用填充图像。单击字段旁边的browse images按钮,进行AJAX调用,以使用一系列图像填充lightbox。单击图像将关闭灯箱,并用该图像的路径填充相应的表单字段 整个过程一直持续到我选择第二张图片为止。两个表单字段都填充了第二个选择,因此删除了我所做的第一个选择 function AssetsPi

第一次张贴。有一些jquery问题,这需要一段时间,但我能够解决它,现在我只想知道为什么

我有一个CMS,我试图通过一个lightbox填充2个表单字段,一次一个,lightbox通过AJAX调用填充图像。单击字段旁边的browse images按钮,进行AJAX调用,以使用一系列图像填充lightbox。单击图像将关闭灯箱,并用该图像的路径填充相应的表单字段

整个过程一直持续到我选择第二张图片为止。两个表单字段都填充了第二个选择,因此删除了我所做的第一个选择

function AssetsPicker (el){
  this.el = el;
  this.url = el.attr('href') || '';
  this.gallery = el.data('gallery') || '';      

  this.show_assets = function(){
    //shows a lightbox of the thumbnails
    this.selected_asset();
  }

  //on thumbnail click
  //Grab the image src from the data attribute
  this.selected_asset = function(){
    var gallery = this.gallery, 
        empty_formfield = this.empty_formfield;

            //*************
            this was the problematic event. Works on first click, on second click it would populate both fields with the value.
           ********************//
        $('#lightbox_display').on('click', '.final-asset', function(e){
          e.preventDefault();
          var   el = $(this);
          src = el.data('file');    

          empty_formfield(src, gallery);                
        });
    }

    //empty out the appropriate form field
    //populate appropriate form field with src  
    this.empty_formfield = function(src, field){        
      var targetfield = $('#edit_project').find("[data-field='" + field + "']");                
      targetfield.val('').val(src);     
      console.log("[data-field='" + field + "']");
    }

}//AssetsPicker

var AssetsAjax =  {
    images: function(url, gallery){
        var promise = $.Deferred();         
        $.ajax(url, {
            dataType: 'json',
            contentType: 'application/json',
            success: function(result){
                promise.resolve(result); //when we have a result, then resolve our promise
            },
            error: function(){
                promise.reject('something went wrong. sorry.'); //if an error, then reject our promise
            }

        });//$.ajax         
    return promise;
    }
}//var AssetsAjax


$('#edit_project').on('click', '.gallery-window', function(e){
  e.preventDefault();
  var el = $(this),
    url = el.attr('href');

  var assetspicker = new AssetsPicker(el);                  

  $.when(
    AssetsAjax.images(url)
  ).then(function(result){              
    assetspicker.open_gallery();
    assetspicker.show_assets(result);
  });       
});
只有当我更改此事件处理程序时,它才能停止擦除另一个字段

    $('#lightbox_display .final-asset').on('click', function(e){
        //anonymous function unchanged              
    });
HTML

//通过AJAX填充的lightbox,具体取决于哪个浏览器
...
//在DOM的其他地方,两个适用字段
//点击后的缩略图会显示在这里
//这将触发lightbox显示缩略图
//点击大图片进入这里
//这将触发lightbox以显示大图像
问题在于
$('edit#u project')。在('click','gallery window',函数(e){
,每次单击
#edit#u project
元素时都会运行该函数

在那里,ajax完成后,运行
assetspicker.show_assets
,它依次运行
$(“#lightbox_display”)。on('click','final asset',函数(e){

因此,每次单击
#edit#u project
,您都会
最终资产
单击添加一个新的处理程序到
#lightbox_显示

因为我无法理解您最终想要做什么(由于缺少完整的html/live示例),我建议您每次都取消绑定click处理程序(以便只有一个保持活动状态)

因此,将
assetspicker.show_assets
中的代码更改为

$('#lightbox_display')
    .off('click','.final-asset')  // added this line to ubind the existing handler
    .on('click', '.final-asset', function(e){
        e.preventDefault();
        var   el = $(this);
        src = el.data('file');    

        empty_formfield(src, gallery);                
    });

你能发布你的html吗?可能是你有嵌套的
.final asset
元素吗?(一个
.final asset
在另一个
.final asset
元素中)你调用外部函数的次数是多少?(函数(字段)
一)Is
和同一DOM树级别上的输入?WARE Is
#edit_project
?.find()查找子体,如果存在多个匹配项,则为您提供多个匹配项。您确定数据字段属性值在HTML中是唯一的吗?虽然您认为它运行了两次,但两个“不同”的事实字段的值设置意味着要么没有唯一的数据字段属性,要么@gabykag.Petrioli建议,这与调用函数的方式有关。
$('#lightbox_display')
    .off('click','.final-asset')  // added this line to ubind the existing handler
    .on('click', '.final-asset', function(e){
        e.preventDefault();
        var   el = $(this);
        src = el.data('file');    

        empty_formfield(src, gallery);                
    });