3

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

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

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

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

4

4 回答 4

3

我认为没有任何优雅的方法可以做到这一点,一种方法是编写一些代码来获取所有元素并将所有事件绑定设置为 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;
    }
}
于 2012-04-13T13:24:52.067 回答
1

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

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

IE

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);
}
于 2012-04-13T13:37:49.607 回答
0

在 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)来保持事件只是为了演示

于 2012-04-13T14:10:58.907 回答
0

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

jQuery:在所有点击事件发生之前捕获它们?

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

我认为这是要走的路

于 2012-04-13T13:28:27.620 回答