【问题标题】:Disable specific event for browser page禁用浏览器页面的特定事件
【发布时间】:2012-04-13 13:07:38
【问题描述】:

我的目标是找到给定页面中的 Javascript 事件瓶颈,无论是点击、聚焦文本字段还是类似的事情。

我非常相信有一些巧妙的方法可以做到这一点,尽管我不认为这是跨浏览器的事情。但在这一点上,什么浏览器供应商允许我做这样的事情对我来说并不重要。

所以,我需要一种方法,例如,禁用所有特定的事件回调。所以,我需要防止任何点击事件被触发的能力。这在那些体面的浏览器(Chrome、Firefox、Safari、Opera)上是否可行?因为拥有它可以让我有一种方法来隔离什么事件类型和什么事件回调是瓶颈来源。

在有人建议我使用 Chrome 开发人员工具中的脚本选项卡来设置事件侦听器断点之前,我已经发现单击特定文本字段似乎是问题所在(它会触发 4 次单击回调,显然有那里有很多事件委托),但我想在浏览器级别禁用点击事件,以检查我是否真的在正确的路径上准确定位瓶颈罪魁祸首。

【问题讨论】:

标签: javascript performance profiling dom-events


【解决方案1】:

我认为没有任何优雅的方法可以做到这一点,一种方法是编写一些代码来抓取所有元素并将所有事件绑定设置为 null

var events = 'click change focus'.split(' '), // add more as needed
    eLen = events.length,
    eI = 0,
    els = document.getElementsByTagName('*'),
    len = els.length,
    i = 0,
    el;

for (; i < len; i++) {
    el = els[i];
    for (eI = 0; eI < eLen; eI++) {
        el['on' + events[eI]] = null;
    }
}

【讨论】:

    【解决方案2】:

    我要解决这个问题的方法是根据一些全局变量内容短路附加这些事件的函数。

    几乎每个 js 库都将事件处理程序包装在一个函数中,您所要做的就是添加一些代码来跳过调用实际侦听器(如果设置了某些变量)。

    即

    var DO_NOT_FIRE = ['click', 'change'];
    

    在被包裹的监听器内部:

    // I'll just assume Array.prototype.indexOf is present for the sake of clarity
    if(DO_NOT_FIRE.indexOf(eventType) == -1)
    {
        originalListener.call(_this, evt);
    }
    

    【讨论】:

      【解决方案3】:

      我认为这个链接解决了你的问题:

      jQuery: Trap all click events before they happen?

      document.addEventListener('click', function(e) {
          e.stopPropagation();
      }, true);
      

      我认为这是要走的路

      【讨论】:

      • 如果队列中之前没有附加文档单击事件,那将起作用,不是吗?无论哪种方式,我也可以删除那些预先附加的文档点击事件,然后附加上面的回调。我只是认为它可能存在一些浏览器友好的方式来做到这一点。
      • 检查其他堆栈中的答案,使用addEventListener 方法中的true,您将此事件设置为捕获阶段,因此即使它是最后几行,它也会首先触发代码,或者如果你在控制台中写下来
      【解决方案4】:

      我制作了一个 sample on jsfiddler,它可以满足您的需求。您可以将其扩展到其他类型的活动。不像詹姆斯邦德那样优雅,但可以解决问题

      基本上,我正在检查所有分配了事件的元素,并检查它们是否有点击事件(只检查一个,因此是[...].click[0])并使用unbind 函数

      // some elements that I'll bind a click event handler through jquery
      <input type="button" id="btn1" value="click 1" />
      <input type="button" id="btn2" value="click 2" />
      <input type="button" id="btn3" value="click 3" />​
      
      // bind all buttons to some fake click handler
      var btn_Click = function(e) {
          alert("clicked button " + $(this).attr("id")); 
      };
      
      $("input[type='button']").on("click", btn_Click);
      
      // defining which events to block
      var events_to_block = ['click'];
      
      // filtering and unbinding the handler for click 
      
      var x = document.getElementsByTagName("*");
      $(x).each(function() {
          var x_events = $.data(this, 'events' );
          if(x_events !== undefined) { 
              if(-1 != events_to_block.indexOf("click")) {
                  if((x_events.click !== undefined) && (x_events.click !== null)) {
                      if($(this).attr("id") !== "btn2") {
                         $(this).unbind("click", x_events.click[0].handler);
                      }
                  }
              }
          }
      });
      

      PS:我故意“允许”第二个按钮 (btn2) 以保留该事件仅用于演示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-31
        • 2014-05-08
        • 1970-01-01
        • 2019-09-29
        • 1970-01-01
        • 2016-10-18
        • 2017-06-14
        • 2019-09-16
        相关资源
        最近更新 更多