网络编程 
首页 > 网络编程 > 浏览文章

jQuery 的 ready()的纯js替代方法

(编辑:jimmy 日期: 2024/11/19 浏览:3 次 )

ready 方法是 jQuery 实现的在 html 页面在 DOM(Document Object Model, 文档对象模型) 树完全加载完成后触发的一个方法. 因为它接收的方法在页面中所有的 DOM 都可访问时才执行, 所以此时你完全可以访问和操作 html 中的元素.

在 jQuery 3.0 之前, 典型的匿名函数方式的用法如下:

$(document).ready(function() {
 // 在 .ready() 被触发时执行.
});

在 jQuery 3.0 中 ready() 的变化

在 jQuery 3.0 发布之前, 有以下几种 ready 方法的使用方式:

在 document 对象上: $(document).ready(handler);

在一个空元素上: $().ready(handler);

或直接使用 (即: 不在一个指定的元素上): $(handler);

以上的几种方式是等价的. 传入的 handler 会在页面所有的 DOM 都加载完成后执行, 不管它被哪个指定元素执行. 也就是, 在 image 元素 $("img") 与 document 对象上调用 ready 方法不表明要等待这些元素加载完成后就触发 handler, 而是在整个 DOM 树加载完成后才触发.

在 jQuery 3.0 中, 除了 $(handler); 方法其它的都被弃用了. 官方的理由是:

因为这个选择与 .ready() 方法的行为没有关系, 它是低效的并且会误导用户猜测这个方法的行为.

Ready 和 Load 事件的不同点

ready 事件在页面 DOM 完全加载后触发并能正确的访问到元素. 而 load 事件在页面 DOM 及资源文件(图片,视频等)都加载完成后才触发.

load 事件可以像下面这样使用:

$(window).on("load", function(){
 // 当页面所有资源(图片,视频等)全加载完成后才加载执行
});

这会等待 DOM 加载完成以及图片加载完成(根据图片的大小, 需要加载一定的时间).

对于常规的 DOM 操作你多半不需要 load 事件, 但如果你想做一个等待页面所有资源加载的一个加载效果或者是计算图片的大小时这应该是一个不错的选择.

你可能并不需要 jQuery.ready()

ready 方法确保了其内部的代码都能正确的操作 DOM 元素. 这是什么意思"htmlcode">

<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>.ready() 教程</title>
  <script src="/UploadFiles/2021-04-02/jquery.min.js">

如果你把要执行的 JavaScript 放到 body 元素里面的最后位置, 你就不需要用 ready() 方法把代码包裹在里面了, 因为在 JavaScript 代码执行时页面中所有的元素都已经加载完成, 所以此时你就可以访问或操作元素了:

<!doctype html>
<html>
 <head>
  <meta charset="utf-8">
  <title>.ready() 教程</title>
 </head>
 <body>
  <p>I'm the content of this website</p>
  <script src="/UploadFiles/2021-04-02/jquery.min.js">

使用原生 JavaScript 替换 ready()
对于现代浏览器, 以及 IE9+, 你可以监听 DOMContentLoaded 事件:

document.addEventListener("DOMContentLoaded", function(){
 // 在 DOM 完全加载完后执行
});

在这里要记住当事件已经触发后回调方法不会执行(页面触发事件后才添加的这个事件监听). 为了确保回调函数始终能执行, jQuery 检测了document 的 readyState 属性(参考), 如果检测出的属性值是 complete 就立即执行回调函数:

var callback = function(){
 // 在 DOM 完全加载完后执行
};

if (
  document.readyState === "complete" ||
  (document.readyState !== "loading" && !document.documentElement.doScroll)
) {
 callback();
} else {
 document.addEventListener("DOMContentLoaded", callback);
}

你应该始终记得引入 domReady 库, 它已经实现了这个解决方案.

老版本的 IE

对于 IE8 及以下版本, 你可以使用 onreadystatechange 事件来检测 document 的 readyState 属性:

document.attachEvent("onreadystatechange", function(){
 // 检测 DOM 是否加载完全
 if(document.readyState === "complete"){
  // 为了确保在之后不会再触发 移除事件监听
  document.detachEvent("onreadystatechange", arguments.callee);
  // 实际处理程序...
 }
});

另外你可以使用 load 事件, 像 jQuery 那样, 这样就可以在所有的浏览器中正确的执行了. 这也导致有一定的时间延迟, 因为它会等所有的资源都加载完成. 记住在这个解决方案中你还是得去检测 readyState, 如上所述, 这是为了确保当事件已经触发后也能执行回调函数.

结论

如果你正在寻找一个原生 JavaScript 来代替 ready 方法你可以通过 DOMContentLoaded 事件来解决. 如果你的系统需要支持 IE 那么你就要确保 DOM 已经加载完全!

上一篇:解决前端跨域问题方案汇总
下一篇:node+experss实现爬取电影天堂爬虫
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?