javascript - 你可以在不使用 document.write() 的情况下销毁文档元素和事件侦听器吗?
问题描述
在下面的示例中:
- 如果您右键单击该文档,它会告诉您它正在收听。
- 如果单击 m1 它将替换文档元素,但右键单击文档仍会通知您它正在侦听。您必须在顶部附近单击鼠标右键,因为该文档没有内容。
- 如果单击 m2 它将覆盖文档内容,并且在顶部附近单击右键不再执行任何操作。检查开发工具中的文档可验证事件处理程序已消失。
- 按下一个按钮后,您必须再次“运行代码片段”才能尝试下一个,因为此演示具有破坏性。
有了这些信息。是否有另一种方法来销毁文档并将其替换为新文档,从而在不使用该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>');
}
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>
需要明确的是,按钮/功能“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>');
}
<button onclick="m1()">m1</button>
<button onclick="m2()">m2</button>
最初我要说不,你不能这样做,正如用户 Livingston Samuel 在这个类似但不相同的问题中所说:“你不能用 createHTMLDocument 方法创建的 Document 对象替换当前文档对象或任何文档对象。” 不过,坚持我最初的问题,这不是我要问的文档,而是 documentElement。所以鉴于上面修改过的代码,我会说是的,这是可能的。
有趣的是,事件侦听器显示在 FireFox 中的 html 元素上,无论它们是附加到文档对象还是 documentElement 对象,从版本 81 开始。我可能希望它们在附加到时根本不会显示它们document
,或将它们放在某个抽象对象上。iframe 确实有一个可用的抽象对象 label #document
,但它不用于此目的并且没有事件标签:
document.write()
实际销毁对象上的事件也很有趣document
,而不仅仅是document.documentElement
. 它可能记录在这里的某个地方,但我似乎无法找到它。
在测试 Chrome 之后,我注意到开发人员工具区分了附加到 documentElement 的事件:
和文件本身:
推荐阅读
- mysql - 如何在mysql中按子字符串尊重分隔符选择行
- python - 了解 OpenCV 矩阵操作
- google-chrome - Chrome WebRTC 回声消除和外部音频源
- python - http post 字节转换为图像文件[无法识别图像文件]
- multithreading - 线程饥饿问题
- hibernate - 如何通过@Query 在多对一关系映射中获取值?
- asp.net-core - Nginx 代理中的跨域预检请求
- css - Bootstrap 4和flex中的元素居中
- amazon-ec2 - 如何使用 aws lambda 代理请求
- envoyproxy - 禁用特使代理上的扩展