简体   繁体   中英

Is there a way to remove all event listeners at once in a web browser?

Simple curiosity here. Nothing too serious.

Building a new app. The client side's config file should offer a terminateOnError parameter. If set to true the whole world should stop after an error is logged.

Getting out of my showTerminationScreen function without executing any subsequent code should be pretty easy : simply throw an unhandled exception.

However the app may (will...) have ongoing asynchronous events, some of which I don't control (I own like half of the app ; the other half is more or less closed source to me) : timers, http request awaiting to come back etc.

Would there be a simple way to tell the browser to stop listening to anything it had been tracking so far ?

You have two basic solutions to this problem:

  1. Use event delegation so you only have one element on the whole page that has event handlers attached.

  2. Make sure each piece of JavaScript functionality is modular and can detach event handlers on a whim, and then reattach them at a later time.

Event Delegation

Just searching GitHub gives you oodles of options for event delegation. Some require jQuery. Some don't.

<self-promotion type="shameless">

I created Oxydizr , which is an event delegation library that doesn't require jQuery, but does require object oriented JavaScript. It utilizes HTML5 attributes to define which user actions lead to method calls in JavaScript.

</self-promotion>

Writing Module JavaScript Code

You may need to refactor your JavaScript so that it can be initialized and uninitialized:

Sample JavaScript:

function Foo(element) {
    this.element = typeof element === "string"
        ? document.getElementById(element)
        : element;
    this.handleDeleteItem = this.handleDeleteItem.bind(this);
    this.init();
}

Foo.prototype = {

    constructor: Foo,

    init: function() {
        var items = this.element.querySelectorAll("button.delete-item"),
            length = items.length, i = 0;

        for (i; i < length; i++) {
            items[i].addEventListener("click", this.handleDeleteItem, false);
        }
    },

    uninit: function() {
        var items = this.element.querySelectorAll("button.delete-item"),
            length = items.length, i = 0;

        for (i; i < length; i++) {
            items[i].removeEventListener("click", this.handleDeleteItem, false);
        }
    },

    handleDeleteItem: function(event) {
        event.preventDefault();
        // ... do other stuff
    }

};

The HTML:

<ul id="foo">
    <li>Item 1
        <button class="delete-item">X</button>
    </li>
    <li>Item 2
        <button class="delete-item">X</button>
    </li>
</ul>

And the JavaScript to kick things off:

var foo = new Foo("items");

When an error occurs:

foo.uninit();

And if you can resume use of the page:

foo.init();

For timers and Ajax requests, you'll need to keep track of all of those objects and clear the timers, and cancel the AJAX requests manually.

Edit #1

Since large portions of the application are essentially a black box, this becomes an architecture and communication issue. If the "dark half" is something that your company controls, you would need to bring this up with that team and work on a solution. If they use a JavaScript framework, ask them which framework they use and start learning that framework. You might dig in to the lower level API of the framework and discover a solution. The art of Reverse Engineering is your friend in this scenario.

not 100% sure but I think that

$("*").unbind();

should works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM