精华帖 (0) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (0)
|
|||
---|---|---|---|
作者 | 正文 | ||
发表时间:2010-09-01
最后修改:2010-09-08
【注意】 之前的 YUI 分析都是针对 YUI 2.8 版本。
关于动态加载 先来说说关于动态加载有哪些个方法,以及动态加载有什么作用。 有时页面的开发,需要加载很多 js 文件。每个 js 文件加载需要消耗很多时间,而动态加载机制可以使 js 文件在需要的时候加载,加快页面的呈现速度。其本质还是将 script element 添加到 Dom 树里面。 Google 搜出很多动态加载的文章,其实有提到 4 个方法,其实都是添加一个 script 元素到 head 里面。然而都是异步加载。而第四种方法使用 XHR 去请求,可以同步,不过得声明其同步。且这个只能是在同源策略下。
关于YUI Get Utility 看看 Get Utility 通用使用的地方: 翻译自 YUI/Get Utility 官方网站。 1 ,跨域资源的获取:因为 XMLHttpRequest 是遵守严格的同源策略,通过 XHR 来获取第三方数据需要服务端的代理。如果是能控制或者完全信任的跨域资源,可以不通过服务端代理而直接加载 script 数据从不同源的地方;而 script 文件,可能是典型 json 格式化的数据,在 load 的时候会立马执行。有一点至关重要,如果你加载的 script file 有恶毒的代码,没有安全的机制可以保证用户不受到恶毒代码的影响,因为浏览器会以完全的权限来执行这些代码。所以记住这一点:不要让用户接触到那些不能彻底信任的数据源。
2 ,先进的加载方法: 在富客户端应用中,基于用户动态加载需要的 js 文件和 css 文件变得非常有用, Get utility 提供了动态加载资源的功能。(注意:如果是加载 YUI 里面资源,可以使用 YUIloader 来加载, YUILoader 使用 Get Utility 来加载 YUI 组件,并且对解决 YUI 组件依赖问题)
现在分析一下 YUI 关于动态加载, 首先 YUI Get Utility 是闭包形式实现,只暴露了部分方法和数据。重点使用到的就是 API 里面看到的。 说说闭包的形式,其实就是域的控制灵活使用。
YUI 使用的也是通过 createElement ,然后 append script 节点或 node 节点来达到加载,然而不同之处在于有对节点onload事件的监听,且是通过监听来达到同步的效果,使script node按照顺序同步加载完 。 YUI2.8 里面在关于节点加载onload事件监听上有 bug ,也不怪 YUI ,是各浏览器之战留下的后果。这个放到后面说说。
加载原理: YUI 对 script 和 css 的加载 ,可以一次函数里面多个资源 url 加载, 都还是同步的。对于加载而言, YUI 作为事务来处理,当整个发生中止的时候,会调用定制的 onFailure 方法。 YUI Get 按照 url 定义的顺序一个一个的加载,这个的设计流程是对上一次资源 url 进行 onload 监听,当加载完 才又开始加载下一个 url 资源。 一个是 _next function 另一个是 _track function 。在 next function 中 调用一次,就对 url 数组 shift 一下,去掉第一个元素,且调用 _track 来监听。而在 _track function 监听中, url 的 onloaded 事件处理中对 _next 进行调用,亦是调用下一个 url 。
再来说说 YUI2.8 中的 bug 存在地方。 先说说关于动态加载中 append node 后,对 node 进行onload监听。 script node 和 css link node 的监听不同,且在各个浏览器中也不同。
此图来源 http://www.zachleat.com/web/2010/07/29/load-css-dynamically/ 上图解释: 在 javascript 和 css 这些资源同源的情况下,可以通过 XHR 的方式来获取数据,浏览器都为 onreadystatechange Event ; 而在不同源的情况下,加载 script node 且进行监听, firefox 和 ie 的 事件名ie为onreadystatechange,firefox为onload ; css node的监听ie 做的不错,还是和script一样,而firefox却没有 此监听。
用firefox和ie这样来区别说明有点浅薄了,在YUI源码中是针对其浏览器所用内核来各个区别对待, if (ua.ie) { n.onreadystatechange = function() { 。。。。。。 }; } else if (ua.webkit) { if (type === "script") { if (ua.webkit >= 420) { n.addEventListener("load", function() { 。。。。。。 }); //这里使用轮询的方法来确认script资源加载上去 } else { var q = queues[id]; if (q.varName) { var freq=YAHOO.util.Get.POLL_FREQ; q.maxattempts = YAHOO.util.Get.TIMEOUT/freq; q.attempts = 0; q._cache = q.varName[0].split("."); q.timer = lang.later(freq, q, function(o) { var a=this._cache, l=a.length, w=this.win, i; for (i=0; i<l; i=i+1) { w = w[a[i]]; if (!w) { // if we have exausted our attempts, give up this.attempts++; if (this.attempts++ > this.maxattempts) { var msg = "Over retry limit, giving up"; q.timer.cancel(); _fail(id, msg); } else { } return; } } q.timer.cancel(); f(id, url); }, null, true); } else { lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]); } } } // FireFox and Opera support onload (but not DOM2 in FF) handlers for // script nodes. Opera, but not FF, supports the onload event for link // nodes. } else { n.onload = function() { f(id, url); }; } 下面代码截至 YUI Get源码 _track function 里面
图来源的文章 是对 css node 进行伪监听。有兴趣的去看看。 YUI 2.8 中并没有对firefox的css link node实现监听,实现同步,所以一次加载中仅仅能加载一个css资源,在API中YAHOO.util.Get.css的url参数仅为<string> 而不像script 方法中的url参数为<string|string[]>
以上仅个人浅见,有错误的地方欢迎指正。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||
返回顶楼 | |||
发表时间:2011-07-05
yui3 io-xdr 也可以做跨域请求,和get有什么区别
|
|||
返回顶楼 | |||
浏览 3271 次