这个问题在这里已有答案:
好吧,这可能只是一个愚蠢的问题,但我确信还有很多其他人不时会问同样的问题 . 我,我只是想以任何方式100%确定 . 有了jQuery,我们都知道这很精彩
$('document').ready(function(){});
但是,假设我想运行一个用标准JavaScript编写的函数,没有库支持它,并且我想在页面准备好处理它时立即启动一个函数 . 接近这个的正确方法是什么?
我知道我能做到:
window.onload="myFunction()";
...或者我可以使用 body
标签:
<body onload="myFunction()">
...或者我甚至可以在所有内容之后尝试在页面底部,但结束 body
或 html
标记如:
<script type="text/javascript">
myFunction();
</script>
什么是以jQuery的 $.ready()
方式发布一个或多个函数的跨浏览器(旧/新)兼容方法?
10 回答
如果您在没有jQuery的情况下执行 VANILLA plain JavaScript ,则必须使用(Internet Explorer 9或更高版本):
以上是jQuery
.ready
的等价物:哪个也可以像这样编写SHORTHAND,jQuery将在准备就绪后运行occurs .
下面不要混淆(这不是DOM准备好的):
请勿使用自动执行的IIFE:
这个IIFE不会等你的DOM加载 . (我甚至在谈论最新版的Chrome浏览器!)
您的方法(在关闭正文标记之前放置脚本)
是一种支持新旧浏览器的可靠方法 .
这是一个清理过的,非eval-using版本的Ram-swaroop's "works in all browsers"品种 - 适用于所有浏览器!
它会等待额外10毫秒来运行,但是,这是一个更复杂的方式,不应该:
另见How to check if DOM is ready without a framework? .
在IE9中测试过,最新的Firefox和Chrome也在IE8中得到了支持 .
示例:http://jsfiddle.net/electricvisions/Jacck/
UPDATE - reusable version
我刚开发了以下内容 . 这是一个相当简单的等价于jQuery或Dom准备,没有向后兼容性 . 它可能需要进一步完善 . 在最新版本的Chrome,Firefox和IE(10/11)中进行了测试,并且可以在旧版浏览器中使用,如评论所述 . 如果我发现任何问题,我会更新 .
用法:
它是为处理JS的异步加载而编写的,但您可能希望首先同步加载此脚本,除非您正在缩小 . 我发现它在开发中很有用 .
现代浏览器还支持脚本的异步加载,这进一步增强了体验 . 支持异步意味着可以同时下载多个脚本,同时仍然可以呈现页面 . 根据异步加载的其他脚本或使用minifier或类似browserify来处理依赖项时,请注意 .
准备好了
使用像
用于自调用代码
支持:IE9
我想在这里提到一些可能的方法和 pure javascript trick which works across all browsers :
正如original author所解释的,这里的技巧是我们正在检查 document.readyState 属性 . 如果它包含字符串
in
(如uninitialized
和loading
,前5个中的前两个DOM ready states),我们设置超时并再次检查 . 否则,我们执行传递的函数 .这是jsFiddle的伎俩 works across all browsers.
感谢Tutorialzine将其包含在他们的书中 .
HubSpot的好人有一个资源,你可以找到纯Javascript方法来实现很多jQuery的好处 - 包括
ready
http://youmightnotneedjquery.com/#ready
示例内联用法:
在没有为您提供所有跨浏览器兼容性的框架的情况下,最简单的方法就是在正文末尾调用代码 . 这比
onload
处理程序执行起来更快,因为它只等待DOM准备好,而不是所有图像都要加载 . 而且,这适用于每个浏览器 .如果你真的不想等待
window.onload
,那么你可能应该去看看像jQuery这样的框架如何实现它的$(document).ready()
方法 . 根据浏览器的功能,它相当复杂 .为了让您了解jQuery的功能(在脚本标记放置的任何位置都可以使用) .
如果支持,它会尝试标准:
回落:
或者对于旧版本的IE,它使用:
回落:
并且,在IE代码路径中有一些我不太关注的解决方法,但看起来它与帧有关 .
这是用简单的javascript编写的jQuery的
.ready()
的完全替代:最新版本的代码在GitHub上公开分享https://github.com/jfriend00/docReady
用法:
这已经过测试:
工作实施和试验台:http://jsfiddle.net/jfriend00/YfD3C/
以下是它的工作原理摘要:
创建一个IIFE(立即调用的函数表达式),这样我们就可以拥有非公共状态变量 .
声明一个公共函数
docReady(fn, context)
调用
docReady(fn, context)
时,检查就绪处理程序是否已经触发 . 如果是这样,只需在JS的这个线程完成setTimeout(fn, 1)
后立即安排新添加的回调 .如果尚未触发就绪处理程序,则将此新回调添加到稍后要调用的回调列表中 .
检查文档是否已准备就绪 . 如果是,请执行所有就绪处理程序 .
如果我们尚未安装事件监听器但尚未知道文档何时准备就绪,那么现在就安装它们 .
如果
document.addEventListener
存在,则使用.addEventListener()
为"DOMContentLoaded"
和"load"
事件安装事件处理程序 . "load"是安全的备份事件,不需要 .如果
document.addEventListener
不存在,则使用.attachEvent()
为"onreadystatechange"
和"onload"
事件安装事件处理程序 .在
onreadystatechange
事件中,检查是否document.readyState === "complete"
以及如果是,调用函数来触发所有就绪处理程序 .在所有其他事件处理程序中,调用函数来触发所有就绪处理程序 .
在调用所有就绪处理程序的函数中,检查一个状态变量以查看我们是否已被调用,然后循环遍历就绪函数数组并按照它们被添加的顺序调用每个函数 . 设置一个标志以指示这些都已被调用,因此它们永远不会被执行多次 .
清除函数数组,以便释放它们可能正在使用的任何闭包 .
注册
docReady()
的处理程序保证按其注册顺序解雇 .如果在文档准备就绪后调用
docReady(fn)
,则将在使用setTimeout(fn, 1)
完成当前执行线程后立即执行回调 . 这允许调用代码总是假设它们是稍后将调用的异步回调,即使稍后在JS的当前线程完成并且它保留调用顺序之后 .我不太确定你在问什么,但也许这有助于:
要么:
document.ondomcontentready=function(){}
应该做的伎俩,但它没有完全的浏览器兼容性 .好像你应该只使用jQuery min