在 jquery $(document).ready(function) 或 $(function) 中,如果没有 jquery,我怎么能做同样的事情,我需要浏览器兼容,并允许附加多个函数。
7 回答
这是 jQuery 包装您正在寻找的函数的方式 - 片段不需要 jQuery,并且是跨浏览器兼容的。我已将所有对 jQuery.ready() 的调用替换为yourcallback
- 您需要定义的。
这里发生了什么:
- 首先,
DOMContentLoaded
定义函数,当 DOMContentLoaded 事件触发时将使用该函数——它确保回调只被调用一次。 - 检查文档是否已经加载 - 如果是,立即触发回调
- 否则嗅探功能(
document.addEventListener
/document.attachEvent
)并将回调绑定到它(IE和普通浏览器不同,加上onload回调)
从 jQuery 1.4.3 提升,函数 bindReady() 和 DOMContentLoaded:
/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
//jQuery.ready();
yourcallback();
};
} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
// Make sure body exists, at least, in case IE gets a little overzealous
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", DOMContentLoaded );
//jQuery.ready();
yourcallback();
}
};
}
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
//return setTimeout( jQuery.ready, 1 );
// ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
setTimeout( yourcallback, 1 );
}
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//window.addEventListener( "load", jQuery.ready, false );
window.addEventListener( "load", yourcallback, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);
// A fallback to window.onload, that will always work
window.attachEvent( "onload", yourcallback );
}
那是 51 行纯 JavaScript 代码,只是为了可靠地注册事件。据我所知,没有更简单的方法。去展示像 jQuery 这样的包装器有什么好处:它们包装了能力嗅探和丑陋的兼容性问题,以便您可以专注于其他事情。
<html>
<head>
<script>
var ready = function (f) {
(/complete|loaded|interactive/.test(document.readyState)) ?
f() :
setTimeout(ready, 9, f);
};
</script>
</head>
<body>
<script>
ready(function () {
alert('DOM Ready!');
});
</script>
</body>
</html>
如果您支持 IE9+ 和现代 (2013) 版本的 Chrome、FF、Safari 等,这就是您所需要的。
function ready(event) {
// your code here
console.log('The DOM is ready.', event);
// clean up event binding
window.removeEventListener('DOMContentLoaded', ready);
}
// bind to the load event
window.addEventListener('DOMContentLoaded', ready);
这是我使用的一种似乎可靠的方法
function ready(func) {
var span = document.createElement('span');
var ms = 0;
setTimeout(function() {
try {
document.body.appendChild(span);
document.body.removeChild(span);
//Still here? Then document is ready
func();
} catch(e) {
//Whoops, document is not ready yet, try again...
setTimeout(arguments.callee, ms);
}
}, ms);
}
很简单,它只是不断尝试将一个空<span>
元素附加到document.body
. 如果文档没有“准备好”,则会抛出异常,在这种情况下,它会再次尝试调用新的setTimeout
调用。一旦没有抛出异常,它就会调用回调函数。
我很高兴听到这种方法是否有任何问题。它对我来说效果很好,但我还没有进行任何流行的 Javascript 框架自然而然的广泛测试。
我已经看到了很多不同的方法来尝试做到这一点。最简单的方法(我认为最初是由雅虎建议的)是在 close body 标记之后调用你的初始化函数,有点突兀,但它是一行。
我在“close body”标签之后和“close html”标签之前有这个。它工作得很好。加载预设功能将宽度、高度和位置值分配给 css div 标签。适用于不同的屏幕尺寸。
document.onreadystatechange = function () {
if (document.readyState == "interactive") {
loadPresets();
}
}
编辑
DomReady 事件在 JavaScript 中不存在。您可以按照 Dean Edwards 等人在此处和此处完成的一些出色工作来实施您自己的工作,您可以在文档而不是窗口上执行类似的事件附件过程。
查看 user83421 对How do I add an additional window.onload event in Javascript的回答
在这里也回顾一下。
if (window.addEventListener) // W3C standard
{
window.addEventListener('load', myFunction, false); // NB **not** 'onload'
}
else if (window.attachEvent) // Microsoft
{
window.attachEvent('onload', myFunction);
}