十年专注于品牌网站建设 十年专注于品牌网站建设,低调、有情怀的网络应用服务商!
南昌百恒网络微信公众号 扫一扫关注
小程序
tel-icon全国服务热线:400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络微信小程序

百恒网络

南昌百恒网络

元素的加载状态判断readystatechange事件使用方法及注意事项

百恒网络 2017-01-02 6368

关于readystatechange 事件也是常用事件之一,为了提高用户的交互体,特别是在H5及移动端我们用得比较多,所以在此通过学习记录向大做一个详细介绍,希望对前端开发人员有所帮助。
       IE为 DOM文档中的某些部分提供了 readystatechange 事件。这个事件的目的是提供与文档或 元素的加载状态有关的信息,但这个事件的行为有时候也很难预料。支持 readystatechange 事件的 每个对象都有一个 readyState 属性,可能包含下列 5个值中的一个。
       uninitialized(未初始化):对象存在但尚未初始化。 
       loading(正在加载):对象正在加载数据。
       loaded(加载完毕):对象加载数据完成。
       interactive(交互):可以操作对象了,但还没有完全加载。
       complete(完成):对象已经加载完毕。
       这些状态看起来很直观,但并非所有对象都会经历 readyState 的这几个阶段。换句话说,如果某 个阶段不适用某个对象,则该对象完全可能跳过该阶段;并没有规定哪个阶段适用于哪个对象。显然, 这意味着 readystatechange 事件经常会少于 4次,而 readyState 属性的值也不总是连续的。
       对于 document 而言,值为"interactive"的 readyState 会在与 DOMContentLoaded 大致相 同的时刻触发 readystatechange 事件。此时,DOM树已经加载完毕,可以安全地操作它了,因此就会进入交互(interactive)阶段。但与此同时,图像及其他外部文件不一定可用。下面来看一段处理 readystatechange 事件的代码。 

EventUtil.addHandler(document, "readystatechange", function(event){
        if (document.readyState == "interactive"){ 
              alert("Content loaded"); 
       } 
       }); 

这个事件的 event 对象不会提供任何信息,也没有目标对象。 
       在与 load 事件一起使用时,无法预测两个事件触发的先后顺序。在包含较多或较大的外部资源的 页面中,会在 load 事件触发之前先进入交互阶段;而在包含较少或较小的外部资源的页面中,则很难 说 readystatechange 事件会发生在 load 事件前面。 
       让问题变得更复杂的是,交互阶段可能会早于也可能会晚于完成阶段出现,无法确保顺序。在包含 较多外部资源的页面中,交互阶段更有可能早于完成阶段出现;而在页面中包含较少外部资源的情况下, 完成阶段先于交互阶段出现的可能性更大。因此,为了尽可能抢到先机,有必要同时检测交互和完成阶 段,如下面的例子所示。 

EventUtil.addHandler(document, "readystatechange", function(event){
        if (document.readyState == "interactive" || document.readyState == "complete"){ 
              EventUtil.removeHandler(document, "readystatechange", arguments.callee);
               alert("Content loaded"); 
       } 
       }); 

对于上面的代码来说,当 readystatechange 事件触发时,会检测 document.readyState 的值, 看当前是否已经进入交互阶段或完成阶段。如果是,则移除相应的事件处理程序以免在其他阶段再执行。 注意,由于事件处理程序使用的是匿名函数,因此这里使用了 arguments.callee 来引用该函数。然 后,会显示一个警告框,说明内容已经加载完毕。这样编写代码可以达到与使用 DOMContentLoaded 十分相近的效果。
        支持 readystatechange 事件的浏览器有 IE、Firfox 4+和 Opera。 
       虽然使用 readystatechange 可以十分近似地模拟 DOMContentLoaded 事件, 但它们本质上还是不同的。在不同页面中,load 事件与 readystatechange 事件并 不能保证以相同的顺序触发。 
       另外, <script>(在 IE和 Opera中)和<link>(仅 IE中)元素也会触发 readystatechange 事件,可以用来确定外部的 JavaScript和 CSS文件是否已经加载完成。与在其他浏览器中一样,除非把 动态创建的元素添加到页面中,否则浏览器不会开始下载外部资源。基于元素触发的 readystatechange 事件也存在同样的问题,即 readyState 属性无论等于"loaded"还是 "complete"都可以表示资源已经可用。有时候,readyState 会停在"loaded"阶段而永远不会“完成”; 有时候,又会跳过"loaded"阶段而直接“完成”。于是,还需要像对待 document 一样采取相同的编码 方式。例如,下面展示了一段加载外部 JavaScript文件的代码。 
EventUtil.addHandler(document, "readystatechange", function(event){
       if (document.readyState == "interactive" || document.readyState == "complete"){
              EventUtil.removeHandler(document, "readystatechange", arguments.callee); 
              alert("Content loaded"); 
       }
       });
EventUtil.addHandler(window, "load", function(event){
       alert("Window loaded");
});

       这个例子为新创建的<script>节点指定了一个事件处理程序。事件的目标是该节点本身,因此当 触发 readystatechange 事件时,要检测目标的 readyState 属性是不是等于"loaded"或 "complete"。如果进入了其中任何一个阶段,则移除事件处理程序(以防止被执行两次),并显示一个 警告框。与此同时,就可以执行已经加载完毕的外部文件中的函数了。
        同样的编码方式也适用于通过<link>元素加载 CSS文件的情况,下面由南昌网站制作公司百恒网络前端开发工程师提供一个完整实例,代码如下所示。
 <html>
<head>
       <title>ReadyStateChange Event Example</title>
       <script type="text/javascript" src="EventUtil.js"></script>
</head>
<body>
       <p>This example loads a JavaScript file and a CSS file dynamically. The script code works in IE and Opera while the CSS code works only in IE.</p>
<script type="text/javascript">
       EventUtil.addHandler(window, "load", function(){

       //create a new <script/> element.
       var script = document.createElement("script");
       EventUtil.addHandler(script, "readystatechange", function(event){
              event = EventUtil.getEvent(event);
              var target = EventUtil.getTarget(event);
              if (target.readyState == "loaded" || target.readyState == "complete"){
                     EventUtil.removeHandler(target, "readystatechange", arguments.callee);
                     alert("Script Loaded");
              }
       });
       script.src = "example.js";
       document.body.appendChild(script);

       //create a new <link/> element
       var link = document.createElement("link");
       link.type = "text/css";
       link.rel= "stylesheet";

       EventUtil.addHandler(link, "readystatechange", function(event){
       event = EventUtil.getEvent(event);
       var target = EventUtil.getTarget(event);
       if (target.readyState == "loaded" || target.readyState == "complete"){
              EventUtil.removeHandler(target, "readystatechange", arguments.callee);
              alert("CSS Loaded");
       }
       });
              link.href = "example.css";
              document.getElementsByTagName("head")[0].appendChild(link);
       });
</script>
</body>
</html>
       同样,重要的是要一并检测 readyState 的两个状态,并在调用了一次事件处理程序后就将其移除。
       。       
  本文仅限内部技术人员学习交流,不得作于其他商业用途.希望此文对广大技人员有所帮助。原创文章出自:南昌网站建设公司-百恒网络http://www.jxbh.cn/如转载请注明出处!

400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络小程序

欢迎您的光顾,我们将竭诚为您服务×

售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售后服务 售后服务
 
售后服务 售后服务
 
备案专线 备案专线
 
×