views:

284

answers:

3

I am doing browser automation using C#, and I would like to modify or possibly just eliminate event handlers on some of the html elements in webpages that I am looking at. E.g., suppose there is a button there which might (or might not) have an attached onClick event. How do I go about: - finding out if there are any event handlers attached to onClick for it? - removing them?

A: 

As far as I know, it's not currently possible to use javascript to get all the event handlers attached to an element.

See this link for more info:

http://www.howtocreate.co.uk/tutorials/javascript/domevents

Waleed Eissa
No, you cannot remove all event handlers by assigning null to an event. For example, events added with `addEventListener`/`attachEvent` are unaffected.
Crescent Fresh
You're right. Edited, thanks
Waleed Eissa
A: 

This depends on how the event handlers have been attached to the element.

If they are attached using addEventListener or one of the proprietary addWhatever listener methdos, there is no way to list them.

If they are attached by modifying the event property, ie. node.onclick = whatever, then you can read the value of the property to get the function and it'll work the same as any other JS func.

There is a third way too:

You can override the default addEventHandler/addListener behavior if the code you automate uses those. By doing this, you can replace the default behavior by one which pushes each handler into an array, which you can then loop over yourself.

The following code might work:

var oldAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function(event, handler, bubbling) {
    /* do whatever you want with event parameters */

    oldAddEventListener.call(this, event, handler, bubbling);
}
Jani Hartikainen
As far as I remember addEventListener works in some browsers, if you can expand your solution for others it will be very nice.
Cem Kalyoncu
This approach works in standards-compliant browsers, such as Firefox, Opera and probably Webkit-based browsers. Internet Explorer does not support HTMLElement.prototype, and as such, it's a bit tricky to do the same in it. You could probably loop over every node in the doc and replace addListener or something along those lines.
Jani Hartikainen
Not a good idea to extend host objects.
kangax
Whether it's a good idea or not depends on what kind of code you're writing. If the code does not need, and will not ever need, to play nice with other code, then it won't matter as much. Also with more specialized purproses (such as the one here) there aren't that many approaches.
Jani Hartikainen
@Jani It's not about 3rd party code really. It's about environment your code is running in. The truth is that extending host objects is inherently a bad idea, due to host objects being unpredictable in their behavior (yet fully compliant with standards). It might be OK to extend them in controlled environment, but in context of general web it's practically shooting yourself in the foot.
kangax
+1  A: 

Replacing element with its own clone should effectively discard all of its event listeners (well, technically listeners are still on an element, but since an element is replaced with its own clone, it looks as if listeners were simply removed):

el.parentNode.replaceChild(el.cloneNode(true), el);

Unfortunately, this won't work in IE, since IE erroneously transfers event listeners of an element on clone. To work around that you can reassign innerHTML of element's parentNode:

el.parentNode.innerHTML = el.parentNode.innerHTML;

Note that this will not only remove event listeners of an element, but also listeners of all of element's siblings.

Alternatively, you can work around IE issue by reassigning outerHTML of an element:

el.outerHTML = el.outerHTML;
kangax
Wow, had no idea about that IE bug. That's a pain!
Gabriel Hurley