3

I'm aiming to find Javascript events bottlenecks in a given page, be it from a click, from focusing a text field or anything like that.

I'm very convinced there is some neat way to do this, although I don't think it's something cross-browser. But at this point doesn't matter to me what browser vendor allows me to do such thing.

So, I need a way to, for example, disable ALL specific event callbacks to be called. So, I need the capability of preventing any click event to be triggered. Is that possible on any of those decent browsers (Chrome, Firefox, Safari, Opera)? Because having that would grant me a way to isolate what event type and what event callback is the bottleneck origin.

Before anyone suggests me to use the Script tab in the Chrome Developer Tools to set Event Listener Breakpoints, I already found out that clicking on a specific text field appears to be the problem (it triggers 4 click callbacks, and apparently there is a lot of event delegation there), but I'd like to disable click events at browser-level to check if I'm really in the right path to locate precisely the bottleneck culprit.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
leandroico
  • 1,207
  • 13
  • 17

4 Answers4

3

I don't think there is any elegant way to do it, one way would be to write a bit of code that grab all elements and set all event binding to 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;
    }
}
GillesC
  • 10,647
  • 3
  • 40
  • 55
1

The way I would attack this would be short-circuiting the functions that are attaching these events, based on some global variable content.

Pretty much every js lib out there wraps the event handler in a function, all you'd have to do is add a bit of code to skip calling the actual listener if some variable is set.

I.e.

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

And inside the wrapped listener:

// 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);
}
Gabriel Gilini
  • 127
  • 1
  • 6
0

I think this link solves your problem:

jQuery: Trap all click events before they happen?

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

I think it's the way to go

Community
  • 1
  • 1
Enrique Paredes
  • 467
  • 3
  • 5
  • That would work if didn't have document-click events attached before in the queue, wouldn't it? Either way, I could also remove those pre-attached document-click events and then attach the callback above. I just thought that it could exist some browser-friendly way of doing this. – leandroico Apr 13 '12 at 13:33
  • Check the answer in the oher stack, with the `true` in the `addEventListener` method, you're setting this event to the capture phase, so it will trigger first even if it's the last lines of code, or if you're writing down in the console – Enrique Paredes Apr 13 '12 at 17:36
0

I've made a sample on jsfiddler which does what you need.. you can extend it to other types of events.. not as elegant as James Bond, but does the trick

Essentially, I'm going through all elements that have events assigned to it, and checking whether they have a click event (checking just for one, hence [...].click[0]) and using the unbind function

// 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: I've purposely 'allowed' the 2nd button (btn2) to keep the event just for demonstration

MilkyWayJoe
  • 9,082
  • 2
  • 38
  • 53