JavaScript 如何检测元素何时添加到 DOM?
JavaScript 如何检测元素何时添加到 Dom?这在 Web 网页中,尤其是针对不能操控源码的网站,是极为常见的问题。那么如何有效检测元素已成功渲染呢,本文旨在对此问题进行探讨。
需求背景
清风明月阁 ,是基于 Wiki.js 搭建的 Web 应用;其内容默认的排版(UI )并不是很喜欢;而 赫蹏 (专为中文网页内容设计的排版样式增强。它基于通行的中文排版规范,可为网站的读者带来更好的内容阅读体验)这种风格,令我更觉得舒服。于是就想为 清风明月阁 接入下 赫hè蹏tí
。
如何使用赫蹏?
项目地址: https://github.com/sivan/heti ,其使用方法如下:
-
在页面的
</head>
标签前中引入heti.css
样式文件:<link rel="stylesheet" href="//unpkg.com/heti/umd/heti.min.css">
-
在要作用的容器元素上增加
class="heti"
的类名即可:<article class="entry heti"> <h1>我的世界观</h1> <p>有钱人的生活就是这么朴实无华,且枯燥。</p> …… </article>
备注:赫蹏是正文区域的样式增强,不是_normalize.css_或_CSS Reset_的替代。因此不建议将它作用在根标签(如 <body>
或 <div class="container">
)上。
而 Wiki.js 跟 Ghost 一样,有强大的后台,支持插入 Css / JS 代码于 head 或 body;那问题就来了,何时为文章内容加 heti
这个类呢?
JavaScript 如何检测元素何时添加到 Dom?
当然,可以很容易想到以下方案:
window.onload = () => {}
setTimeout(function(){}, 100)
但是,这两种方案,可以有效,但不够干净,不能得知元素是否已被渲染的准确时机。截至 2018 年,您应该使用 MutationObserver 来检测元素何时添加到 DOM。现在,所有现代浏览器(Chrome 26+、Firefox 14+、IE11、Edge、Opera 15+ 等)都广泛支持 MutationObservers。此外,将元素添加到 DOM 后,您将能够检索其实际尺寸。于是乎,为 清风明月阁 添加「赫蹏」,其体验就能变得非常自然,没有中间不符合预期的变化。
<link rel="stylesheet" href="//unpkg.com/heti/umd/heti.min.css">
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', (event) => {
var observer = new MutationObserver(function(mutations) {
var contents = document.querySelector('.contents')
if (document.contains(contents)) {
contents.classList.add('heti', 'heti--classic');
observer.disconnect();
}
});
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree:true});
});
</script>
另外,值得一提的是,在此处使用了 DOMContentLoaded 事件(当初始 HTML 文档完全加载和解析时触发,无需等待样式表、图像和子框架完成加载),在其成功回调中,再调用 MutationObservers,算是细微处优化处理。
本文首发于:JavaScript 如何检测元素何时添加到 DOM? | 悠然宜想亭。