简体   繁体   English

我是否在此jQuery代码中一再绑定事件?

[英]Am I binding events over and over again in this jQuery code?

So I used this totally awesome tool called Visual Event , which shows all the event handlers bound to an object - and I noticed that every time I clicked or played around with my object and checked the list of event handlers bound to it, there were and more every time. 因此,我使用了一个非常出色的工具Visual Event ,它显示了绑定到对象的所有事件处理程序-我注意到每次单击或玩弄对象并检查绑定到该对象的事件处理程序列表时,都会看到每次都更多。 My problem is this one: console.trace or stack trace to pinpiont the source of a bug in javascript? 我的问题是这个:用console.trace或stack trace来固定javascript错误的源头? After using Visual Event and someone else's suggestion, I'm thinking my problem is that I'm probably binding the same handlers to the same events over and over again. 在使用Visual Event和其他人的建议之后,我在想我的问题是我可能一次又一次地将相同的处理程序绑定到相同的事件。 Is there a way to unbind things regularly? 有没有办法定期取消绑定?

My application has a bunch of plugins connect to dynamically created div s. 我的应用程序有许多插件可以连接到动态创建的div These divs can be resized and moved around the place. 这些divs可以调整大小并在该位置移动。 The application is a kind of editor, so users arrange these divs (which contain either images or text) in any design they like. 该应用程序是一种编辑器,因此用户可以按照自己喜欢的任何设计来排列这些div(包含图像或文本)。 If the user clicks on a div, it becomes "activated", while all other divs on the page get "deactivated". 如果用户单击div,则它会变为“已激活”,而页面上的所有其他div都将变为“已停用”。 I have a bunch of related plugins, like activateTextBox , initTextBox , deactivateTextBox , readyTextBox , and so on. 我有一大堆相关的插件,像activateTextBoxinitTextBoxdeactivateTextBoxreadyTextBox ,等等。 Whenever a div is first created, the init plugin is called once, just the first time after creation, like so: 每当首次创建div时,都会在创建后的第一次调用一次init插件,如下所示:

$(mydiv).initTextBox();

But readyTextBox and activateTextBox and deactivateTextBox are called often, depending on other user events. readyTextBoxactivateTextBoxdeactivateTextBox通常被称为,这取决于其他用户的事件。

In init , I first use bind things like resizable() and draggable() , then I make the box "ready" for use init ,我首先使用诸如resizable()draggable()类的绑定对象,然后将框“准备好”使用

    $.fn.extend({
        initTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.mouseenter(function(){ 
        if(!$this.hasClass('activated'))
            $this.readyTextBox();
         }
         $this.mouseleave(function(){ 
        if($this.hasClass('ready')){
            $this.deactivateTextBox(); 
                    $this.click(function(e){
                 e.preventDefault();
                 });
                }
             });
     }); 
  });

Here's a simplified summary version of the readyTextBox plugin: 这是readyTextBox插件的简化摘要版本:

(function($){
    $.fn.extend({
        readyTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable({ handles: 'all', alsoResize: img_id});
               $this.draggable('enable');
               $this.on( "dragstop", function( event, ui )
               {/* some function */ });
               $this.on("resizestop", function( event, ui ){ /* another function */ });
               // and so on
});

Then there's activateTextBox() : 然后是activateTextBox()

    $.fn.extend({
        activateTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable('option','disabled',true); //switch of resize & drag
               $this.draggable('option', 'disabled', true);
});

Then deactivate , where I turn on draggable and resizable again, using the code: 然后deactivate ,使用以下代码再次启用可拖动和可调整大小的代码:

$this.draggable('enable'); $this.resizable('option','disabled',false);

These divs, or "textboxes" are contained within a bigger div called content , and this is the click code I have in content : 这些div或“文本框”包含在一个名为content的较大div中,这是我在content拥有的点击代码:

$content.click(function(e){
    //some irrelevant code
     if( /* condition to decide if a textbox is clicked */) 
     {  $(".textbox").each(function(){ //deactivate all except this
        if($(this).attr('id') != $eparent.attr('id')) 
            $(this).deactivateTextBox();
        });
        // now activate this particular textbox
        $eparent.activateTextBox();
             }
          });

This is pretty much the relevant code related to text boxes. 这几乎是与文本框相关的代码。 Why is it that whenever I drag something around and then check Visual Event, there are more clicks and dragstops and mouseovers than before? 为什么每次我拖动一些东西然后检查Visual Event时,点击,拖动和鼠标悬停都比以前更多? Also, the more user interacts with the page, the longer the events take to complete. 同样,用户与页面的互动越多,事件花费的时间就越长。 For example, I mouseout from a div, but the move cursor takes a loooong time to get back to default. 例如,我从一个div鼠标移出,但move光标花费过长...时间回到默认值。 I quit dragging, but everything gets stuck for a while before getting ready to take more user clicks, etc. So I'm guessing the problem has to be that I'm binding too many things to the same events need to be unbinding at some point? 我退出了拖动,但是在准备好接受更多用户点击之前,一切都停滞了一段时间。因此,我猜问题是我将太多东西绑定到同一事件上,需要在某些时候解绑定点? It gets so bad that draggable eventually stops working at some point. 它变得如此糟糕,以至于可拖动最终在某些时候停止工作。 The textboxes just get stuck - they're still able to be resized, but dragging stops working. 文本框只是卡住了-它们仍然可以调整大小,但是拖动停止工作。

Am I binding events over and over 我是否一再约束事件

Yes. 是。 Have a look at your code: 看一下你的代码:

$this.mouseenter(function(){ 
    …
    $this.mouseleave(function(){ 
        …
        $this.click(function(e){
            …
        });
    });
});

That means every time you mouseover the element, you add another leave handler. 这意味着每次将鼠标悬停在元素上时,都会添加另一个离开处理程序。 And when you leave the element, every of those handlers adds another click event. 当您离开该元素时,所有这些处理程序都会添加另一个click事件。

I'm not sure what you want to do, but there are several options: 我不确定您要做什么,但是有几种选择:

  • bind the event handlers only once, and keep track of the current state with boolean variables etc. 仅将事件处理程序绑定一次,并使用布尔变量等跟踪当前状态。
  • before binding, remove all other event handlers that are already bound. 绑定之前,请删除所有其他已绑定的事件处理程序。 jQuery's event namespacing can help you to remove only those which your own plugin added. jQuery的事件命名空间可以帮助您仅删除自己的插件添加的事件。
  • use the one() method that automatically unbinds a listener after firing it. 使用one()方法 ,在触发监听器后自动解除绑定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 一个简单的 JS 代码,我一遍又一遍地收到相同的结果,我想,我可能犯了一个逻辑错误, - A simple JS code and I am receiving the same result over and over again, I think, I may have done a logical error, 对 jQuery 事件感到困惑? - Confusion Over jQuery Events? 我是否对以下代码感到满意? - Am I over promising with the following code? 我得到输入字符串的格式不正确,尽管我一遍又一遍地使用相同的格式 - I am getting Input string was not in a correct format although i used the same format over and over again 当我使用反应钩子时,API 被一遍又一遍地调用 - API is getting called over and over again when I am using react hooks 我不知道这个简单的 javascript 代码有什么问题,我一遍又一遍地检查了这个但不起作用 - I dont know whats wrong with this simple javascript code, I have checked this over and over again but does not work jQuery fadeOut一遍又一遍执行回调,这是为什么,如何防止这种情况呢? - Jquery fadeOut executes callback over and over again, why is this and how can I prevent this? 我正在为我的应用程序使用Firebase身份验证。 似乎有一个无限循环,页面不断被重定向 - I am using Firebase authentication for my application. There seems to be an infinite loop where the page keeps being redirected over and over again jQuery scrollTop在移动设备上不起作用(一遍又一遍) - jQuery scrollTop not working (repeats over and over again) for mobile 我在使用switch语句时遇到麻烦,特别是使它们反复检查我的代码 - I am having trouble with switch statements specifically making them check my code over and over
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM