admin管理员组文章数量:1134247
I am a new programmer and still learning. This is the code that I am trying to figure out:
<div id="buy" class="buy button">Buy</div>
When I click on the div (button), some JavaScript code is executed but I don't know were it is. How can I tell what function is fired when click happens? Some how a listener is attached to this element.
I am a new programmer and still learning. This is the code that I am trying to figure out:
<div id="buy" class="buy button">Buy</div>
When I click on the div (button), some JavaScript code is executed but I don't know were it is. How can I tell what function is fired when click happens? Some how a listener is attached to this element.
Share Improve this question edited Nov 15, 2022 at 19:45 Brian Tompsett - 汤莱恩 5,87572 gold badges61 silver badges133 bronze badges asked Aug 6, 2012 at 17:02 Vaso A.Vaso A. 6571 gold badge6 silver badges7 bronze badges 6- Are you asking how an event handler is attached to the div? – Blazemonger Commented Aug 6, 2012 at 17:06
- 2 side note: you should not use divs as a buttons use <button type="button">Im a button</button> or <a href="www.google.com">Im a link</a> instead. – Mauno Vähä Commented Aug 6, 2012 at 17:06
- 1 @RandyMarsh I don't know were the event listener is, This is what I am trying to find out. Because usually i learned in school that you add can add an onclick attribute in the element and then specify the function that you need to fire. But with firebug when i mouse over on that element I can't see the event :( how do they do this? – Vaso A. Commented Aug 6, 2012 at 17:08
- The listener isn't necessarily attached directly to that element. It could be on an ancestor. – user1106925 Commented Aug 6, 2012 at 17:09
- We have FireFox and Chrome solutions. I wonder about IE... Not holding my breath. – Chad Harrison Commented Aug 6, 2012 at 20:04
12 Answers
Reset to default 107In Google chrome's developer tools (click the wrench icon >Tools>Developer tools), select the element in the Elements tab, on the right open the 'Event Listeners' panel you'll will see all events
If you use Firefox and Firebug you can try installing FireQuery. It will make it so you can see the handlers bound by jQuery. http://firequery.binaryage.com/
You can't do it in a really good manner by "just" using ECMAscript itself. For instance, if there was a click event handler added by DOM Level 1 in the form of
document.getElementById('buy').onclick = function() {};
you can of course easily intercept that property on the node itself. Things are getting more complicated if DOM Level 2 comes into play with .addEventListener()
respectevily .attachEvent()
. Now you don't really have a "place" to look for where all the different listener functions where bound from.
It gets better by using jQuery. jQuery will hold all it's event handler functions in a special object which is linked to the DOM node of invocation. You can check for that by getting the .data()
-expando property for a node like
$('#buy').data('events');
However, now I already described three different ways of binding event listeners to a node (actually its two because a library like jQuery also uses DOM Level 1 or 2 methods of course).
It's really getting ugly if an event is triggerd by delegation. That means, we bound our click event on some parent-node just waiting for that event bubbling up to us so we can check the target
. So now we don't even have a direct relationship between the node
and the event listener
.
Conclusion here is, lookout of a browser plugin or probably a thing like VisualEvent.
You may use "Visual Event 2" script as a bookmark or same script as Chrome extension.
This script shows all js events attached to dom-elements.
Use jQuery("#buy").data('events');
http://api.jquery.com/jQuery.data/ may be interesting.
Event handlers attached using traditional element.onclick=
handler or HTML <element onclick="handler">
can be retrieved trivially from the element.onclick
property from script or in-debugger.
Event handlers attached using DOM Level 2 Events addEventListener methods and IE's attachEvent cannot currently be retrieved from script at all. DOM Level 3 once proposed element.eventListenerList to get all listeners, but it is unclear whether this will make it to the final specification. There is no implementation in any browser today.
If you're using FireFox, you should have FireBug installed. Once you have that, you can install FireQuery, which will show you what jQuery events are bound to which objects.
http://getfirebug.com/
http://firequery.binaryage.com/
This is the easiest way I've found of how to do it: http://www.sprymedia.co.uk/article/Visual+Event
When working with events in Javascript, it is often easy to lose track of what events are subscribed where. This is particularly true if you are using a large number of events, which is typical in a modern interface employing progressive enhancement. Javascript libraries also add another degree of complexity to listeners from a technical point of view, while from a developers point of view they of course can make life much easier! But when things go wrong it can be difficult to trace down why this might be.
It is due to this I've put together a Javascript bookmarklet called Visual Event which visually shows the elements on a page that have events subscribed to them, what those events are and the function that the event would run when triggered. This is primarily intended to assist debugging, but it can also be very interesting and informative to see the subscribed events on other pages.
There's a bookmark button there you can drag to your toolbar (FF or Chrome), then just click the button on any page where you want to see the events attached. Works great! (at least for events attached by jQuery or other libraries).
Are you using jQuery? If so, you want to search for one of these three lines of code:
$("#buy").click //the div is refered by its id
or
$(".buy").click //the div is refered to by the style "buy"
or
$(".button").click //refered to by the style "button"
Most newer browsers have "Developer Tools" built into them by pressing F12 (at least in IE and Chrome). That may help you do some further debugging and tracing.
Below is something I’ve used in the past that I think may be what you're looking for. What this does is watch a property on a page element (In the example below, it's the document's "Title" property) and then display an alert with the JS callstack whenever that property is changed. You’ll need to get this into the DOM before whatever code you're trying to find fires, but hopefully you’ll be able to identify what’s causing the problem.
I would recommend using Firefox and getting Firebug for JavaScript debugging.
// Call stack code
function showCallStack() {
var f=showCallStack,result="Call stack:\n";
while((f=f.caller)!==null) {
var sFunctionName = f.toString().match(/^function (\w+)\(/)
sFunctionName = (sFunctionName) ? sFunctionName[1] : 'anonymous function';
result += sFunctionName;
result += getArguments(f.toString(), f.arguments);
result += "\n";
}
alert(result);
}
function getArguments(sFunction, a) {
var i = sFunction.indexOf(' ');
var ii = sFunction.indexOf('(');
var iii = sFunction.indexOf(')');
var aArgs = sFunction.substr(ii+1, iii-ii-1).split(',')
var sArgs = '';
for(var i=0; i<a.length; i++) {
var q = ('string' == typeof a[i]) ? '"' : '';
sArgs+=((i>0) ? ', ' : '')+(typeof a[i])+' '+aArgs[i]+':'+q+a[i]+q+'';
}
return '('+sArgs+')';
}
var watchTitle = function(id, oldval, newval) { showCallStack(); }
// !! This is all you should need to update, setting it to whatever you want to watch.
document.watch("title", watchTitle);
- Right-click page, and choose to view the page's source
- Find
<script>
tags - Look for
$("#buy")
and something mentioningonClick
or.on("click",function(){...});
- If you can't find it, search for something along these lines:
document.getElementById("buy")
- You have found the
function
, or code, where the event handler code is
$("#buy")
is JQuery's way of saying find an element that has an id
attribute of buy
and if it has a .
following it with some function, that function is acting upon the element that was found by JQuery.
You can even do it in JavaScript, but only if you intercept/override the addEventListener and removeEventListener prototype functions with your own interceptor, so you can intercept them.
This will work for anything that has been added with addEventListener (and it accounts for removeEventListener).
But if you added them without EventListener, e.g. with element.onclick (or in the onclick/onAnything-attribute in the markup), this won't list them, you'll have to manually check for them.
Be sure that the bellow JavaScript is the first script that is executed on your page, otherwise it might not work properly.
Here's how (TypeScript):
type EventHandlerMapType = {
// [key: EventTarget]: { [type: string]: EventListenerOrEventListenerObject[] };
[key: string]: { [type: string]: EventListenerOrEventListenerObject[] };
};
type EventHandlerMapValue = { [type: string]: EventListenerOrEventListenerObject[] };
interface EventTarget
{
getEventHandlers: (type?: string) => EventHandlerMapValue | EventListenerOrEventListenerObject[];
}
// function addEventListener<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options ?: boolean | AddEventListenerOptions): void;
// addEventListener(type: string, listener: EventListenerOrEventListenerObject, options ?: boolean | AddEventListenerOptions): void;
(function ()
{
// Store the handlers by element reference
// WeakMap can take an object, such as an Element, as a key, object cannot.
// This is useful because WeakMap allows for garbage collection of the keys(the elements),
// meaning when an Element is removed from the DOM and no longer referenced, it gets garbage - collected,
// and its entry in the WeakMap is automatically removed.
// This prevents memory leaks.
const eventHandlerMap = new WeakMap<EventTarget>(); // Dictionary<Element, { type:[]}> // where type is string and array is an array of handlers/listeners
// Override the native addEventListener
const originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions)
{
// Call the original addEventListener to ensure normal behavior
originalAddEventListener.call(this, type, listener, options);
// Initialize tracking for the current element if it doesn't exist
if (!eventHandlerMap.has(this))
{
eventHandlerMap.set(this, {});
}
// Get the event type handlers for this element
const handlersForElement = eventHandlerMap.get(this);
if (!handlersForElement[type])
{
handlersForElement[type] = [];
}
// Add the handler to the list for this event type
handlersForElement[type].push(listener);
};
// Override the native removeEventListener
const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions)
{
// Call the original removeEventListener to ensure normal behavior
originalRemoveEventListener.call(this, type, listener, options);
// Remove the handler from the tracking list
if (eventHandlerMap.has(this))
{
const handlersForElement = eventHandlerMap.get(this);
if (handlersForElement[type])
{
// Filter out the handler that matches the one being removed
handlersForElement[type] = handlersForElement[type].filter((h: EventListenerOrEventListenerObject) => h !== listener);
// Clean up if no handlers left for this event type
if (handlersForElement[type].length === 0)
{
delete handlersForElement[type];
}
}
// Clean up the element if no handlers left for any event type
if (Object.keys(handlersForElement).length === 0)
{
eventHandlerMap.delete(this);
}
}
};
// Function to retrieve all event handlers for an element
EventTarget.prototype.getEventHandlers = function (type?: string): EventHandlerMapValue | EventListenerOrEventListenerObject[]
{
// Get the tracking list for the current element
const handlersForElement = eventHandlerMap.get(this) || {};
if (type)
{
// If a specific event type is requested, return its handlers
return handlersForElement[type] || [];
}
// If no type is specified, return all handlers grouped by type
return handlersForElement;
};
})();
Now on EventTarget (Element, Node, etc):
getEventHandlers(type?: string)
or in plain-JS
(function () {
var eventHandlerMap = new WeakMap();
var originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, options) {
originalAddEventListener.call(this, type, listener, options);
if (!eventHandlerMap.has(this)) {
eventHandlerMap.set(this, {});
}
var handlersForElement = eventHandlerMap.get(this);
if (!handlersForElement[type]) {
handlersForElement[type] = [];
}
handlersForElement[type].push(listener);
};
var originalRemoveEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function (type, listener, options) {
originalRemoveEventListener.call(this, type, listener, options);
if (eventHandlerMap.has(this)) {
var handlersForElement = eventHandlerMap.get(this);
if (handlersForElement[type]) {
handlersForElement[type] = handlersForElement[type].filter(function (h) { return h !== listener; });
if (handlersForElement[type].length === 0) {
delete handlersForElement[type];
}
}
if (Object.keys(handlersForElement).length === 0) {
eventHandlerMap.delete(this);
}
}
};
EventTarget.prototype.getEventHandlers = function (type) {
var handlersForElement = eventHandlerMap.get(this) || {};
if (type) {
return handlersForElement[type] || [];
}
return handlersForElement;
};
})();
Tests:
var btnCreated = document.createElement("button");
btnCreated.textContent = "Hello Kitty";
btnCreated.value = "Hello Kitty";
document.body.appendChild(btnCreated);
var btn = document.querySelector('button');
function handleClick() {
console.log('Button clicked');
}
btn.addEventListener('click', handleClick);
btn.addEventListener('clock', handleClick);
console.log(btn.getEventHandlers('click'));
console.log("before click");
btn.click();
console.log("after click");
btn.removeEventListener('click', handleClick);
console.log("before click after click removed");
btn.click();
console.log("after click after click removed");
console.log("click handlers", btn.getEventHandlers('click'));
console.log("all handlers", btn.getEventHandlers());
本文标签: javascriptHow can I see the event that is attached to an html elementStack Overflow
版权声明:本文标题:javascript - How can I see the event that is attached to an html element? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736857180a1955761.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论