2

How can I freeze all JS DOM changes completely using JS from a chrome extension?

Example: a user hovers over a button, which onMouseEnter displays a modal and hides it onMouseLeave. If I bind a callback to a certain keyboard-shortcut, how can I freeze the DOM in that point in time so that the modal stays visible and nothing can change in the DOM anymore (until the shortcut is pressed again) ?

I know there might not be a direct API to freeze the DOM, but I'm looking for any ideas that can help me do this.

One Idea I tried was:

  • When user presses the shortcut (toggles the freeze on)
    • grab the html node in current state
      • query and remove all script nodes
      • clone the html node (to get rid of bound listeners)
    • replace actual html node with the cleaned-out cloned html node (one without js scripts)
  • When user presses the shortcut again (toggles the freeze off)
    • replace the original DOM (with all script tags) back

However that didn't work, if I hovered my mouse over the button and the modal showed up, then I invoked that algorithm with the keybind, the cloning would happen successfully and script tags would be removed, however when I remove the mouse from the button the modal would just close. As if the button was still bound to onMouseLeave.

Edit: I'm trying to do this from an external script, specifically a chrome extension.

Ismael
  • 358
  • 3
  • 15
  • 3
    Sounds like an XY problem. What exactly are you trying to achieve? – elclanrs Mar 05 '22 at 00:02
  • Set a global variable that all your other event listeners check before modifying the DOM. – Barmar Mar 05 '22 at 00:06
  • @elclanrs a chrome extension that allows user to toggle freezing and unfreezing the dom. – Ismael Mar 05 '22 at 00:07
  • @Barmar I'm trying to do that through an external script, chrome extension specifically – Ismael Mar 05 '22 at 00:07
  • 1
    Removing script nodes doesn't undo all the effects of the script. So the event listeners don't go away. – Barmar Mar 05 '22 at 00:09
  • @Barmar but I'm cloning the nodes afterwards, which according to this SO answer should unbind all listeners https://stackoverflow.com/a/19470348/11401702 – Ismael Mar 05 '22 at 00:11
  • How do you create the listeners? If you are using a native method, switch to using a proxy so that you can suspend forwarding events to the subscribed listeners. – jsejcksn Mar 05 '22 at 00:25
  • @jsejcksn He can't change how the listeners work, he's writing an extension that modifies an existing page. – Barmar Mar 05 '22 at 00:26
  • Reloading the script tags is probably not going to work. There's probably listeners for the `load` and `DOMContentLoaded` events, which only fire when the page is initially loaded, not when you recreate it from the saved state. – Barmar Mar 05 '22 at 00:29
  • Maybe you can just display an element over the existing DOM with a high z-index, so no events will go to the original DOM. That's basically how modal dialogs work to prevent you interacting with the page elements. – Barmar Mar 05 '22 at 00:31
  • @Ismael There's probably a much simpler, targeted way to solve your problem, but without all the details, it's not possible to provide more help. – jsejcksn Mar 05 '22 at 00:33
  • @Barmar thanks for the idea, I just tried that, unfortunately when the element is added over the existing dom it causes the `onMouseLeave` event to fire immediately. – Ismael Mar 05 '22 at 00:49
  • @jsejcksn there's not much more detail to it, it's just a chrome extension that allows the user to freeze and unfreeze the dom through a keyboard-shortcut – Ismael Mar 05 '22 at 00:50
  • The only way to actually remove the listeners is to use `chrome.debugger` API and call [DOMDebugger.getEventListeners](https://chromedevtools.github.io/devtools-protocol/tot/DOMDebugger/#method-getEventListeners) on `window` or `document` with depth `-1` to read the entire DOM, then call `Runtime.evaluate` with the code that unregisters each found listener. – wOxxOm Mar 05 '22 at 10:02

1 Answers1

0

if you have a function "myFunc" and want to malfunction it or disable it. you can clear the contents in window object.

<button onclick="freeze()">Freeze alert</button>
<button onclick="testAlert()">Test alert</button>
<script>
    function freeze() {
        window.testAlert = function testAlert() { };
    }

    function testAlert() {
        alert('The alert is active');
    }
</script>

The alert button will not work after clicking the freeze button.

Mehrwarz
  • 413
  • 1
  • 10