How do I know what types of event listeners are associated with a particular HTML element in the Chrome extension?

I am posting this question here since I cannot post it on the official Chromium extension forums (or there is an amazing delay until it is moderated). I need to check the Chromium extension, is there a listener for a certain type of event attached to an arbitrary HTML element. In Firefox, I can use the following service to get this information:

var listenerService = Components.classes["@mozilla.org/eventlistenerservice;1"]
            .getService(Components.interfaces.nsIEventListenerService);
var infos = listenerService.getListenerInfoFor(element, {});
var types = [];
for ( var i = 0; i < infos.length; ++i) {
  var info = infos[i].QueryInterface(Components.interfaces.nsIEventListenerInfo);
  types.push(info.type);
}

As I see, there is no such API in Chromium. So I tried the following method (which was suggested here ):

I created a script events_spy.js:

(function(original) {
  Element.prototype.addEventListener = function(type, listener, useCapture) {
    if (typeof (this._handlerTypes) == 'undefined') {
      this._handlerTypes = {};
    }
    this._handlerTypes[type] = true;
    return original.apply(this, arguments);
  }
})(Element.prototype.addEventListener);

(function(original) {
  Element.prototype.removeEventListener = function(type, listener,useCapture) {
    if (typeof (this._handlerTypes) != 'undefined') {
      delete this._handlerTypes[type];
    }
    return original.apply(this, arguments);
  }
})(Element.prototype.removeEventListener);

I declare this script manifest.jsonas follows:

"content_scripts" : [{
  "matches" : [ "http://*/*", "https://*/*" ],
  "js" : [ "content/events_spy.js" ],
  "run_at" : "document_start",
  "all_frames" : true
},
...
]

Then I test my extension on the following HTML page:

<!DOCTYPE html>
<html>
 <head>
 </head>
 <body>
  <a id="test" href="#">Click here</a>
  <script type="application/javascript">
       document.getElementById("test").addEventListener("click", function()
{ alert("clicked"); }, false);
  </script>
 </body>
</html>

, - , addEventListener(). ?

!

EDIT: () , @kdzwinel

var injectedJS = "\
(function(original) { \
  Element.prototype.addEventListener = function(type, listener, useCapture) { \
    var attr = this.getAttribute('_handlerTypes'); \
    var types = attr ? attr.split(',') : []; \
    var found = false; \
    for (var i = 0; i < types.length; ++i) { \
      if (types[i] == type) { \
        found = true; \         
        break; \                
      } \               
    } \         
    if (!found) { \
      types.push(type); \
    } \         
    this.setAttribute('_handlerTypes', types.join(',')); \
    return original.apply(this, arguments); \
  } \   
})(Element.prototype.addEventListener); \
\
(function(original) { \
  Element.prototype.removeEventListener = function(type, listener, useCapture) { \
    var attr = this.getAttribute('_handlerTypes'); \
    var types = attr ? attr.split(',') : []; \
    var removed = false; \
    for (var i = 0; i < types.length; ++i) { \
      if (types[i] == type) { \
        types.splice(i, 1); \   
        removed = true; \       
        break; \                
      } \               
    } \         
    if (removed) { \
      this.setAttribute('_handlerTypes', types.join(',')); \
    } \         
    return original.apply(this, arguments); \
  } \   
})(Element.prototype.removeEventListener); \
";

var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(injectedJS));
document.documentElement.appendChild(script);

HTML, , "_handlerTypes", , . Chrome script!

+5
3

script , HTML . Chrome, - :

, . DOM , , JavaScript, . script, , , JavaScript. : JavaScript, , - , . []

. script DOM.


, - , , :

, script, , DOM jQuery $(node). data ( "events" ). , . , , , API jQuery, , - , , . . , . : github.com/grantyb/Google-Chrome-Link-URL-Extension []

, events_spy.js $(node).data("events"). , script, . , docs ( " " ).

+1

Chrome getEventListeners(), . https://code.google.com/p/accessibility-developer-tools/source/browse/src/audits/UnfocusableElementsWithOnClick.js .

, - script Firefox, Chrome, , . , . , script. ( Firefox .)

0

, , ( jQuery)...

, "" addEventListener removeEventListener javascript. DOM, .

content_script.js:

window.addEventListener('DOMContentLoaded', function() {
  var script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.setAttribute('src', chrome.extension.getURL('eventtarget.js'));
  // injected <script> tag must be parsed first!
  document.head.insertBefore(script, document.head.firstChild);
});

- EventTarget element.__eventListeners, content_script.js. . , , __eventname (: <div id="test" __click="1" __mouseover="2">, , ).

eventtarget.js:

EventTarget.prototype.__eventListeners = [];

EventTarget.prototype.__addEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function() {
  var found = false;
  if(!this.__eventListeners[arguments[0]])
   this.__eventListeners[arguments[0]] = [];
  var key;
  for(key in this.__eventListeners[arguments[0]]) {
    found = this.__eventListeners[arguments[0]][key] === arguments[1];
    if(found)
     break;
  }
  if(!found)
   this.__eventListeners[arguments[0]].push(arguments[1]);
  if(this.setAttribute)
   this.setAttribute('__'+arguments[0], this.__eventListeners[arguments[0]].length);
  return(this.__addEventListener.apply(this, arguments));
}

EventTarget.prototype.__removeEventListener = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function() {
  var found = false;
  if(!this.__eventListeners[arguments[0]])
   this.__eventListeners[arguments[0]] = [];
  var key;
  for(key in this.__eventListeners[arguments[0]]) {
    found = this.__eventListeners[arguments[0]][key] === arguments[1];
    if(found)
     break;
  }
  if(found)
  this.__eventListeners[arguments[0]].splice(key, 1);
  if(this.setAttribute)
   this.setAttribute('__'+arguments[0], this.__eventListeners[arguments[0]].length);
  return(this.__removeEventListener.apply(this, arguments));
}

In my solution, I use a separate file eventtarget.js, it must be included in the section of web_accessable_resourcesthe manifest file. Also note: run_atmust be set to document_startto subscribe to the event DOMContentLoaded. No additional permissions required.

manifest.json:

...
"web_accessible_resources": ["eventtarget.js"],
"content_scripts": [
  {
    "matches": ["<all_urls>"],
    "js": ["content_script.js"],
    "run_at": "document_start",
    "all_frames": true
  }
],
...

A small example of how it works:

if(document.body.getAttribute('__wheel') > 0)
 console.log('document.body subscribed to mouse wheel event');
0
source

All Articles