什么是非 jQuery 等价物$(document).ready()
?
'$(document).ready()' 的非 jQuery 等价物是什么?
这很完美,来自 ECMA。该代码段就是您所需要的,但如果您想挖掘更多信息并探索其他选项,请查看此详细说明。
document.addEventListener("DOMContentLoaded", function() {
// code...
});
在window.onload
不等于JQuery的$(document).ready
,因为$(document).ready
等待只对DOM树,同时window.onload
检查,包括对外资产和图像的所有元素。
编辑:由于Jan Derk的观察,添加了 IE8 和更旧的等效版本。您可以在 MDN 上阅读此代码的来源:
// alternative to DOMContentLoaded
document.onreadystatechange = function () {
if (document.readyState == "interactive") {
// Initialize your application or run some code.
}
}
除了 ,还有其他选择"interactive"
。有关详细信息,请参阅MDN 文档。
现在是 2018 年,这里有一个快速简单的方法。
这将添加一个事件侦听器,但如果它已经被触发,我们将检查 dom 是否处于就绪状态或是否已完成。这可以在子资源(图像、样式表、框架等)加载完成之前或之后触发。
function domReady(fn) {
// If we're early to the party
document.addEventListener("DOMContentLoaded", fn);
// If late; I mean on time.
if (document.readyState === "interactive" || document.readyState === "complete" ) {
fn();
}
}
domReady(() => console.log("DOM is ready, come and get it!"));
附加阅读
- https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
- https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
更新
这里有一些使用我编写的标准 ES6 导入和导出的快速实用程序助手,其中也包括 TypeScript。也许我可以让这些成为一个快速的库,可以作为依赖项安装到项目中。
JavaScript
export const domReady = (callBack) => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', callBack);
}
else {
callBack();
}
}
export const windowReady = (callBack) => {
if (document.readyState === 'complete') {
callBack();
}
else {
window.addEventListener('load', callBack);
}
}
typescript
export const domReady = (callBack: () => void) => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', callBack);
}
else {
callBack();
}
}
export const windowReady = (callBack: () => void) => {
if (document.readyState === 'complete') {
callBack();
}
else {
window.addEventListener('load', callBack);
}
}
Promise
export const domReady = new Promise(resolve => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', resolve);
}
else {
resolve();
}
});
export const windowReady = new Promise(resolve => {
if (document.readyState === 'complete') {
resolve();
}
else {
window.addEventListener('load', resolve);
}
});
我放在一起的小东西
domready.js
(function(exports, d) {
function domReady(fn, context) {
function onReady(event) {
d.removeEventListener("DOMContentLoaded", onReady);
fn.call(context || exports, event);
}
function onReadyIe(event) {
if (d.readyState === "complete") {
d.detachEvent("onreadystatechange", onReadyIe);
fn.call(context || exports, event);
}
}
d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
d.attachEvent && d.attachEvent("onreadystatechange", onReadyIe);
}
exports.domReady = domReady;
})(window, document);
如何使用它
<script src="domready.js"></script>
<script>
domReady(function(event) {
alert("dom is ready!");
});
</script>
您还可以通过传递第二个参数来更改回调运行的上下文
function init(event) {
alert("check the console");
this.log(event);
}
domReady(init, console);
这不会回答问题,也不会显示任何非 jQuery 代码。请参阅下面的@sospedra 的回答。
好消息$(document).ready()
是它之前触发window.onload
。加载函数会等待所有内容加载完毕,包括外部资产和图像。$(document).ready
,但是,当 DOM 树完成并且可以被操作时触发。如果你想在没有 jQuery 的情况下实现 DOM 就绪,你可以查看这个库。有人只ready
从 jQuery 中提取了一部分。它又好又小,你可能会发现它很有用:
根据http://youmightnotneedjquery.com/#ready,一个仍然适用于 IE8 的不错的替代品是
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading')
fn();
});
}
}
// test
window.ready(function() {
alert('it works');
});
改进:我个人也会检查类型fn
是否为函数。正如@elliottregan建议在使用后删除事件侦听器一样。
function ready(fn) {
if (typeof fn !== 'function') {
throw new Error('Argument passed to ready should be a function');
}
if (document.readyState != 'loading') {
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn, {
once: true // A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.
});
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading')
fn();
});
}
}
// tests
try {
window.ready(5);
} catch (ex) {
console.log(ex.message);
}
window.ready(function() {
alert('it works');
});
我回答这个问题晚的原因是因为我正在寻找这个答案,但在这里找不到。我认为这是最好的解决方案。