7

I have put my website through a performance analysis tool, and it has come back saying that there are too many scroll listeners on the document/window object.

Is there a way of finding all my scroll listeners for my document/window object?

Something maybe along the lines of :

window.scroll.listeners
Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225

2 Answers2

12

If you just want to find them, you can use chrome dev tools.

Copied from answer below:

You can right click on the target element -> select "inspect element" Scroll down on the right side of the dev frame, at the bottom is 'event listeners'. Expand the tree to see what events are attached to the element. Not sure if this works for events that are handled through bubbling (I'm guessing not)

Chrome Dev Tools Listeners Tab

See How do I view events fired on an element in Chrome DevTools?

Also, you can programmatically do it in Chrome

getEventListeners(window)

See https://stackoverflow.com/a/16544813/227299 and https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
8

Using jQuery, you can use:

//Change window, for any other element you want to check. IE: document
$._data(window, "events"); 

You can check all jquery events attached to an element, so if someone did:

$(window).on("scroll", function(){ console.log("scroll"); });

You'll see something like this:

enter image description here

Using plain javascript, you can "intercept" the addEventListener and attachEvent to check all events listeners attached to window, or any element for that matter:

(function(){
    function interceptListener(type, element){
        if(typeof element[type] == "function"){
            element[type] = (function(){
                var original = this[type];
                this.allListeners = this.allListeners || {};
                return function() {
                    this.allListeners[arguments[0]] = arguments[0] in this.allListeners ? this.allListeners[arguments[0]] + 1 : 1;

                    return original.apply(this, arguments);
                }

            }.bind(element))();
        }
    }

    interceptListener("attachEvent", window);
    interceptListener("addEventListener", window);
})();

Place this snippet before any other scripts.

If you want to check if window.onscroll was set, you can just test on window load if any other script set it:

if(typeof window.onscroll == "function")
    console.log("onscroll function");

Or you can watch the property with: object watch polyfill

window.watch("onscroll", function(){
    if(typeof this.onscroll == "function")
        this.allListeners["onscroll"] = this.allListeners["onscroll"] + 1 : 1;
});

Then you can check how many listeners are attached to window with:

console.log(window.allListeners);

NOTE: as @JuanMendes pointed out: Be aware that this is an internal data structure that is undocumented and should not be modified and should only be used for debugging.

Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • This is only for jQuery listeners, events could have been set directly without jQuery – Ruan Mendes Jan 20 '16 at 13:23
  • Yes I know, I said that: "You can check all jquery events attached to an element" – Marcos Casagrande Jan 20 '16 at 13:26
  • @OliverWatkins check my edited answer to intercept an event using vanilla js. – Marcos Casagrande Jan 20 '16 at 13:34
  • 1
    I know you know, I'm just making sure others know that this doesn't fully answer the question. You should also explain that this method is for debugging only. `but be aware that this is an internal data structure that is undocumented and should not be modified` http://blog.jquery.com/2011/11/08/building-a-slimmer-jquery/ – Ruan Mendes Jan 20 '16 at 13:36
  • I know I'm being extra picky, but your vanilla JS function also doesn't account for `window.resize = function` and `window.attachEvent()` – Ruan Mendes Jan 20 '16 at 13:51
  • I know, but I like giving the tools to the OP so he can make that by himself, using my snippet, he can easily make that for himself, and learn in the way :), and anyhow window.resize wasn't part of the question, he wanted only scroll listeners. – Marcos Casagrande Jan 20 '16 at 13:55
  • 1
    @MarcosCasagrande I meant `window.onscroll`. The problem with half an answer is that others come to StackOverflow expecting an answer marked as accepted to be correct. We're always trying to answer the question and help all other users, not just the one asking the question. – Ruan Mendes Jan 20 '16 at 14:06
  • @JuanMendes I'll edit the answer, with a full one, as soon as I get to my computer ;) – Marcos Casagrande Jan 20 '16 at 15:30
  • 1
    @JuanMendes Thanks for your input, and now please check my answer, and let me know if you like it now :) – Marcos Casagrande Jan 20 '16 at 16:34
  • 1
    Thanks for putting up with my "suggestions" :) – Ruan Mendes Jan 20 '16 at 16:50