纯JavaScript等价于jQuery';s$.ready()-如何在页面/DOM准备就绪时调用函数
使用jQuery,我们都知道奇妙的纯JavaScript等价于jQuery';s$.ready()-如何在页面/DOM准备就绪时调用函数,javascript,jquery,html,Javascript,Jquery,Html,使用jQuery,我们都知道奇妙的.ready()函数: $('document').ready(function(){}); 但是,假设我想运行一个用标准JavaScript编写的函数,而没有库支持它,并且我想在页面准备好处理它后立即启动一个函数。正确的方法是什么 我知道我能做到: window.onload=“myFunction()”; 或者我可以使用body标签: 或者我甚至可以尝试在页面底部完成所有操作,但结尾正文或html标记如下: myFunction(); 什么是跨浏
.ready()
函数:
$('document').ready(function(){});
但是,假设我想运行一个用标准JavaScript编写的函数,而没有库支持它,并且我想在页面准备好处理它后立即启动一个函数。正确的方法是什么
我知道我能做到:
window.onload=“myFunction()”;
或者我可以使用body
标签:
或者我甚至可以尝试在页面底部完成所有操作,但结尾正文
或html
标记如下:
myFunction();
什么是跨浏览器(旧/新)兼容的方法,它可以像jQuery的
$.ready()
那样发布一个或多个函数?文档。ondomcontentready=function(){}
应该可以做到这一点,但它没有完全的浏览器兼容性
似乎您应该只使用jQuery min您的方法(将脚本放在结束正文标记之前)
myFunction()
是支持新旧浏览器的可靠方法。如果没有一个框架来为您提供所有跨浏览器兼容性,最简单的方法就是在正文末尾调用代码。这比
onload
处理程序执行得更快,因为它只等待DOM准备就绪,而不是等待加载所有图像。而且,这适用于所有浏览器
<!doctype html>
<html>
<head>
</head>
<body>
Your HTML here
<script>
// self executing function here
(function() {
// your page initialization code here
// the DOM will be available here
})();
</script>
</body>
</html>
用法:
docReady(function() {
// DOM is loaded and ready for manipulation here
});
// pass a function reference
docReady(fn);
// use an anonymous function
docReady(function() {
// code here
});
// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);
// use an anonymous function with a context
docReady(function(context) {
// code here that can use the context argument that was passed to docReady
}, ctx);
ready(function () {
// your code here
});
如果您需要完全的跨浏览器兼容性(包括旧版本的IE),并且不想等待
window.onload
,那么您可能应该看看像jQuery这样的框架是如何实现其$(document.ready()
方法的。这取决于浏览器的功能
让您稍微了解jQuery的功能(无论脚本标记放在哪里,jQuery都可以工作)
如果支持,它将尝试以下标准:
document.addEventListener('DOMContentLoaded', fn, false);
回退到:
window.addEventListener('load', fn, false )
window.attachEvent("onload", fn);
或者对于旧版本的IE,它使用:
document.attachEvent("onreadystatechange", fn);
回退到:
window.addEventListener('load', fn, false )
window.attachEvent("onload", fn);
而且,在IE代码路径中有一些我没有完全遵循的变通方法,但它似乎与框架有关
以下是用纯javascript编写的jQuery的
.ready()
的完全替代:
(function(funcName, baseObj) {
// The public function name defaults to window.docReady
// but you can pass in your own object and own function name and those will be used
// if you want to put them in a different namespace
funcName = funcName || "docReady";
baseObj = baseObj || window;
var readyList = [];
var readyFired = false;
var readyEventHandlersInstalled = false;
// call this when the document is ready
// this function protects itself against being called more than once
function ready() {
if (!readyFired) {
// this must be set to true before we start calling callbacks
readyFired = true;
for (var i = 0; i < readyList.length; i++) {
// if a callback here happens to add new ready handlers,
// the docReady() function will see that it already fired
// and will schedule the callback to run right after
// this event loop finishes so all handlers will still execute
// in order and no new ones will be added to the readyList
// while we are processing the list
readyList[i].fn.call(window, readyList[i].ctx);
}
// allow any closures held by these functions to free
readyList = [];
}
}
function readyStateChange() {
if ( document.readyState === "complete" ) {
ready();
}
}
// This is the one public interface
// docReady(fn, context);
// the context argument is optional - if present, it will be passed
// as an argument to the callback
baseObj[funcName] = function(callback, context) {
if (typeof callback !== "function") {
throw new TypeError("callback for docReady(fn) must be a function");
}
// if ready has already fired, then just schedule the callback
// to fire asynchronously, but right away
if (readyFired) {
setTimeout(function() {callback(context);}, 1);
return;
} else {
// add the function and context to the list
readyList.push({fn: callback, ctx: context});
}
// if document already ready to go, schedule the ready function to run
if (document.readyState === "complete") {
setTimeout(ready, 1);
} else if (!readyEventHandlersInstalled) {
// otherwise if we don't have event handlers installed, install them
if (document.addEventListener) {
// first choice is DOMContentLoaded event
document.addEventListener("DOMContentLoaded", ready, false);
// backup is window load event
window.addEventListener("load", ready, false);
} else {
// must be IE
document.attachEvent("onreadystatechange", readyStateChange);
window.attachEvent("onload", ready);
}
readyEventHandlersInstalled = true;
}
}
})("docReady", window);
这已在以下方面进行了测试:
IE6及以上
Firefox3.6及以上版本
铬14及以上
Safari 5.1及以上版本
歌剧11.6及以上
多个iOS设备
多个Android设备
工作实施和测试平台:
以下是其工作原理的摘要:
docReady(fn,context)
docReady(fn,context)
时,检查ready处理程序是否已启动。如果是这样的话,只需将新添加的回调安排在这个JS线程使用setTimeout(fn,1)
完成后立即启动即可document.addEventListener
,则使用.addEventListener()
为“DOMContentLoaded”
和“load”
事件安装事件处理程序。“负载”是出于安全考虑的备份事件,不需要document.addEventListener
不存在,则使用.attachEvent()
为“onreadystatechange”
和“onload”
事件安装事件处理程序onreadystatechange
事件中,检查document.readyState==“complete”
是否已完成,如果已完成,则调用函数以启动所有就绪的处理程序docReady()
注册的处理程序保证按注册顺序启动
如果在文档准备就绪后调用
docReady(fn)
,则将使用setTimeout(fn,1)
计划在当前执行线程完成后立即执行回调。这允许调用代码始终假定它们是稍后调用的异步回调,即使稍后JS的当前线程一结束就调用,并且保留调用顺序。在IE9中测试,最新的Firefox和Chrome也在IE8中支持
document.onreadystatechange = function () {
var state = document.readyState;
if (state == 'interactive') {
init();
} else if (state == 'complete') {
initOnCompleteLoad();
}
};
例如:
更新-可重用版本
我刚刚开发了以下内容。它相当于jQuery或Dom ready,没有向后兼容性。它可能需要进一步完善。在最新版本的Chrome、Firefox和IE(10/11)中进行测试,如评论所述,应该可以在较旧的浏览器中使用。如果发现任何问题,我会更新
window.readyHandlers = [];
window.ready = function ready(handler) {
window.readyHandlers.push(handler);
handleState();
};
window.handleState = function handleState () {
if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
while(window.readyHandlers.length > 0) {
(window.readyHandlers.shift())();
}
}
};
document.onreadystatechange = window.handleState;
用法:
docReady(function() {
// DOM is loaded and ready for manipulation here
});
// pass a function reference
docReady(fn);
// use an anonymous function
docReady(function() {
// code here
});
// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);
// use an anonymous function with a context
docReady(function(context) {
// code here that can use the context argument that was passed to docReady
}, ctx);
ready(function () {
// your code here
});
它是为处理JS的异步加载而编写的,但是您可能希望先同步加载此脚本,除非您正在缩小。我发现它在开发中很有用
现代浏览器还支持异步加载脚本,这进一步增强了体验。支持异步意味着可以同时下载多个脚本,同时仍然呈现页面。当依赖于异步加载的其他脚本时,请注意
document.addEventListener("DOMContentLoaded", function(event) {
// Your code to run since DOM is loaded and ready
});
$(document).ready(function() {
console.log("Ready!");
});
$(function() {
console.log("ready!");
});
Example:
(function() {
// Your page initialization code here - WRONG
// The DOM will be available here - WRONG
})();
function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}
ready(function(){
//some code
});
(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){
//Some Code here
//DOM is avaliable
//var h1s = document.querySelector("h1");
});
window.onload = function(){
// Code. . .
}
window.onload = main;
function main(){
// Code. . .
}
function onReady(yourMethod) {
var readyStateCheckInterval = setInterval(function() {
if (document && document.readyState === 'complete') { // Or 'interactive'
clearInterval(readyStateCheckInterval);
yourMethod();
}
}, 10);
}
// use like
onReady(function() { alert('hello'); } );
function onReady(yourMethod) {
if (document.readyState === 'complete') { // Or also compare to 'interactive'
setTimeout(yourMethod, 1); // Schedule to run immediately
}
else {
readyStateCheckInterval = setInterval(function() {
if (document.readyState === 'complete') { // Or also compare to 'interactive'
clearInterval(readyStateCheckInterval);
yourMethod();
}
}, 10);
}
}
// Use like
onReady(function() { alert('hello'); } );
// Or
onReady(functionName);