In the example below:
With this information. Is there a different way to destroy the document and replace it with a new one, in such a way that the event handlers are destroyed, without using the document.write()
function?
document.write()
is prone to errors and its usage is "strongly discouraged", but I would still like to be able to destroy the document and it's event listeners.
document.addEventListener('contextmenu', function (e) {
alert('still listening');
e.preventDefault();
})
function m1() {
var doc = document.implementation.createHTMLDocument();
document.replaceChild(
document.importNode(doc.documentElement, true),
document.documentElement
);
}
function m2() {
document.close();
document.write('<html></html>');
}
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>
To be clear, button/function "m1" fails my goals, because although the document element was replaced, the event handlers from the previous document element were preserved for some reason. I would like to achieve what m2 achieves, but without using document.write
and document.close
which are recommended against.
This question is strictly for the sake of better understanding the limits of the language and the engines that implement them. Please do not try to read between the lines or solve some alternate goal. It's just a question of whether something is possible or not.
I don't need to know how to remove event listeners or manage event listeners, or remove all child elements of a document. I would like to know if it's possible to destroy the document element itself, leaving no <html>
tag whatsoever and leaving none of its event listeners behind. This is possible with document.write()
but I simply want to know if there are alternate means of achieving this exact goal, not any other assumed goals.
I just realised that actually you can, and that the first example, m1, actually does replace the documentElement and removes its event listeners. The interesting thing is that there were no event listeners on it in the first place, they were on the document itself not the document element. The developer tools (in FireFox) tricks you and shows them as being attached to the <html>
element, even though they aren't technically attached to an element. If you modify the example to actually attach the events to the document.documentElement
instead of the document itself the event will be disabled when you click m1:
document.documentElement.addEventListener('contextmenu', function (e) {
alert('still listening');
e.preventDefault();
})
function m1() {
var doc = document.implementation.createHTMLDocument();
document.replaceChild(
document.importNode(doc.documentElement, true),
document.documentElement
);
}
function m2() {
document.close();
document.write('<html></html>');
}
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>
Originally I was going to say no, and that you can't do it, as user Livingston Samuel states in this similar but not identical question: "You cannot replace the current document object or any document object with the Document object created with createHTMLDocument method." Sticking to my original question though, it is not the document I was asking about, it was the documentElement. So given the modified code above, I will say that Yes, it is possible.
It is interesting to see that the event listeners are displayed on the html element in FireFox whether they are attached to the document object or the documentElement object, as of version 81. I might expect that they would instead not display them at all when attached to document
, or put them on some abstract object. An iframe does have an abstract object available labeled #document
, but it is not used for this and has no event label:
It is also interesting that document.write()
actually destroys the events on the document
object, not just the document.documentElement
. It might be documented somewhere in here but I can't seem to find it.
After testing Chrome I noticed that the developer tools distinguishes between events being attached to the documentElement:
and the document itself:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With