adj*_*nks 5 html javascript document.write
在下面的例子中:
有了这些信息。是否有一种不同的方法可以销毁文档并将其替换为新文档,从而在不使用函数的情况下销毁事件处理程序?document.write()
document.write()容易出错,“强烈不鼓励”使用它,但我仍然希望能够销毁文档及其事件侦听器。
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>');
}Run Code Online (Sandbox Code Playgroud)
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>Run Code Online (Sandbox Code Playgroud)
需要明确的是,按钮/函数“m1”未能实现我的目标,因为尽管替换了文档元素,但出于某种原因保留了前一个文档元素的事件处理程序。我想实现 m2 实现的目标,但不使用document.write并且document.close不推荐使用。
这个问题是为了更好地理解语言和实现它们的引擎的限制。请不要尝试在字里行间阅读或解决某些替代目标。这只是一个事情是否可能的问题。
我不需要知道如何删除事件侦听器或管理事件侦听器,或删除文档的所有子元素。我想知道是否有可能销毁文档元素本身,不留下任何<html>标签,也不留下任何事件侦听器。这是可能的,document.write()但我只是想知道是否有其他方法可以实现这个确切的目标,而不是任何其他假设的目标。
我刚刚意识到实际上可以,并且第一个示例 m1 实际上确实替换了 documentElement并删除了其事件侦听器。有趣的是,它首先没有事件侦听器,它们位于文档本身而不是文档元素上。开发人员工具(在 FireFox 中)会欺骗您并将它们显示为附加到<html>元素,即使它们在技术上并未附加到元素。如果您修改示例以将事件实际附加到而document.documentElement不是文档本身,则当您单击 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>');
}Run Code Online (Sandbox Code Playgroud)
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>Run Code Online (Sandbox Code Playgroud)
最初我想说不,你不能这样做,正如用户 Livingston Samuel 在这个类似但不相同的问题中所说:“你不能用 createHTMLDocument 方法创建的 Document 对象替换当前文档对象或任何文档对象”。不过,坚持我原来的问题,这不是我要问的文档,而是 documentElement。因此,考虑到上面修改后的代码,我会说是的,这是可能的。
有趣的是,从版本 81 开始,无论事件侦听器附加到文档对象还是 documentElement 对象,事件侦听器都会显示在 FireFox 中的 html 元素上。我可能期望它们在附加到document,或者把它们放在一些抽象的物体上。iframe 确实有一个可用的抽象对象 labelled #document,但它不用于此目的并且没有事件标签:
同样有趣的是,document.write()实际上破坏了对象上的事件document,而不仅仅是document.documentElement. 它可能记录在此处的某个地方,但我似乎找不到它。
测试 Chrome 后,我注意到开发人员工具区分附加到 documentElement 的事件:
以及文档本身: