jquery 如何仅在事件处理程序不存在时才绑定它?

6g8kf2rb  于 2023-08-04  发布在  jQuery
关注(0)|答案(3)|浏览(99)

我有一个页面,我想绑定拖放事件。我希望浏览器中的整个页面都成为放置目标,因此我将事件绑定到document对象。我的应用程序的内容是通过 AJAX 加载到主内容区域的,但是,我只希望这些事件处理程序在上传页面当前可见时处于活动状态。
现在,我在检索上载页面时绑定事件处理程序;但是,每次上载页面变为活动状态时,它都会绑定一个新的事件处理程序,这会导致当用户转到上载页面、离开然后返回时,该处理程序会多次触发。我在想,如果我能让处理程序只在它还没有绑定的时候绑定,就可以解决这个问题。这是可能的,还是我忽略了一个更好的选择?
相关代码,如果有帮助的话:

$(document).bind('dragenter', function(e) {
    e.stopPropagation();
    e.preventDefault();
}).bind('dragover', function(e) {
    e.stopPropagation();
    e.preventDefault();
}).bind('drop', function(e) {
    e.stopPropagation();
    e.preventDefault();
    self._handleFileSelections(e.originalEvent.dataTransfer.files);
});

字符串

vdzxcuhz

vdzxcuhz1#

在绑定新的事件处理程序之前,请取消绑定现有的事件处理程序。这对于namespaced events [docs]来说非常简单:

$(document)
  .off('.upload') // remove all events in namespace upload
  .on({
      'dragenter.upload': function(e) {
          e.stopPropagation();
          e.preventDefault();
      },
      'dragover.upload': function(e) {
          e.stopPropagation();
          e.preventDefault();
      },
      // ...
  });

字符串

dba5bblo

dba5bblo2#

对于那些只想添加一次事件的人,避免对每个新克隆的元素使用unbind()/off()bind()/on()方法。
我在Code Project网站上找到了一篇文章"Binding Events to Not Yet Added DOM Elements with JQuery (by Khrystyna Popadyuk)",它展示了如何只注册一次事件,甚至在元素存在之前。Read his full article for details.

$("body").on("click", ".your-style", function(event) {
       // your code ...
});

字符串

bnlyeluc

bnlyeluc3#

我写了一个“uon”(unique on)jquery扩展来实现:

$.fn.extend({
    uon:function(eventname,fn) {
        this.each(function() {
            var alreadyexists=false;
            var exevby=$._data(this,'events');
            for(var xevn in exevby) {
                if(xevn==eventname) {
                    exevby[xevn].forEach(evobj=>{
                        if(evobj.handler==fn) alreadyexists=true;
                    });
                }
            }
            if(!alreadyexists) $(this).on(eventname,fn);
        });
    }
});

字符串
也就是说你可以说

$(this).uon('click',doSomething);
$(this).uon('click',doSomething);
$(this).uon('click',doSomething);


而且它只会在点击时做一次-而不是3次。
它特别适合这个对象:

var JQEvent={
    ons:[],
    onload:function(sel,fn) {
        JQEvent.ons.push({sel:sel,fn:fn});
    },
    apply:function($el) {
        JQEvent.ons.forEach(on => {
            $el.find(on.sel).each(on.fn);
        });
    }
}


也就是说你可以说

JQEvent.onload('input.field',function() {
   $(this).uon('click',doSomething);
}


这可能是你想在你的系统中,当你点击一个input. field的时候做一些事情。
然后,当你动态加载一些HTML或在JavaScript中构建一些dom元素时,你可以只应用泛型:

JQuery.apply('div.new-container-element');


并且该元素的任何子div将具有应用于它的那些函数。

相关问题