I have a chrome extension which injects some DOM event listeners through the content scripts. I want to remove those event listeners from the DOM in the event that the user deactivates the plugins, is there a method to do so?
-
have you tried `removeEventListener()`? – dvenkatsagar Feb 01 '16 at 05:00
2 Answers
It's an interesting question. It has to do with a concept of "orphaned" scripts. I talk at length about those in an addendum here.
Problem is, as soon as the script becomes detached from the parent extension, Chrome APIs will fail. As such, detecting this is not straightforward.
There are many possible approaches:
Maintain an open port to the background page. The port will fire an
onDisconnected
event in case the background page ceases to exist.This is an event-based approach - you will be able to react immediately.
But this has an important downside: maintaining an open port will prevent an Event page from unloading. So if you use a non-persistent background page, this is not optimal.
Periodically, or better yet - in the beginning of your handlers, try to do something with Chrome API. This will fail, and you can catch the exception and assume that the extension is orphaned.
Please note that this is pretty much undefined behavior. How Chrome API reacts can change over time.
function heartbeat(success, failure) { try { if(chrome.runtime.getManifest()) { success(); } else { // will return undefined in an orphaned script failure(); } } catch(e) { // currently doesn't happen, but may happen failure(); } } function handler() { heartbeat( function(){ // hearbeat success /* Do stuff */ }, function(){ // hearbeat failure someEvent.removeListener(handler); console.log("Goodbye, cruel world!"); } ); } someEvent.addListener(handler);
Finally, there is a proposal to make a special event for this situation, but it's not implemented yet.
Specifically for updates when the extension is reloaded, you can make it inject scripts into existing pages and let old scripts know they should deactivate; however, since your question is about extension being removed, it doesn't help.
With the hard part done, actual removal of event listeners depends on how you added them, but should be straightforward.
-
So i should periodically run a chrome API script and catch the error as the trigger for deactivation? that seems very draining if I need the event to be fired instantly, so my interval may be like 10ms (plugin is to do with video streaming), is there no event driven way of notifying at all? – JasonY Feb 01 '16 at 14:08
-
Like I said - there is no event though there is a proposal for it; you can use a port's `onDisconnected` event but it will keep the background page loaded. The only thing I can suggest is rate-limit checks if you don't care that your extension is still active for some time after its background died. – Xan Feb 01 '16 at 14:10
-
oh never mind, the first solution seems to fit well, detect an onDisconnected event by maintaining an open port, i guess i could run the API script on disconnect and if it throws an error then remove the listeners (to be sure the disconnect did indeed come from a deactivation). – JasonY Feb 01 '16 at 14:11
-
As long as you use a persistent background page there are no downsides to this. – Xan Feb 01 '16 at 14:11
-
so I need "persistent" : true in the manifest.json? thats ok I guess. thanks will give best answer. – JasonY Feb 01 '16 at 14:12
-
`"persistent": true` is the default; you don't need to specify it. `"persistent": false` will not fail in this scenario but will be useless. – Xan Feb 01 '16 at 14:13
onDisabled fired when app or extension has been disabled.
chrome.management.onDisabled.addListener(function callback)
EventTarget.removeEventListener() removes the event listener previously registered.
var div = document.getElementById('div'); var listener = function (event) { /* do something here */ }; div.addEventListener('click', listener, false); div.removeEventListener('click', listener, false);
I think you don't need to this, since once your extension is disabled, your event listener will be removed and won't be injected.

- 10,703
- 2
- 31
- 47
-
1Downvoted, since `chrome.management.onDisabled` will most certainly not help. No event will fire in case an extension is disabled or uninstalled. – Xan Feb 01 '16 at 11:26
-
Another reason is #3 i not correct: content scripts from a deactivated extension still linger until navigation happens. – Xan Feb 01 '16 at 13:18
-
@xan Can you clarify "chrome.management.onDisabled will most certainly not help. No event will fire in case an extension is disabled or uninstalled"? The documentation specifically describes the onDisabled event as "Fired when an app or extension has been disabled." https://developer.chrome.com/extensions/management#event-onDisabled – Katie Nov 16 '18 at 18:17
-
1@Katie Specifically, no event is generated when the extension itself is uninstalled/disabled. This event is fired in _other_ extensions with management permissions. – Xan Nov 16 '18 at 18:55