多浏览器兼容的动态加载 JavaScript 与 CSS第1/2页

 更新时间:2008年09月03日 00:09:38   作者:  
Omar AL Zabir这位MVP总是喜欢搞些稀奇古怪同时又很实用的小东西,并且还十分值得参考。最近他就做了一个叫做ensure的小工具用于动态加载JavaScript、CSS与HTML,而且IE、Firefox、Opera、Safari都支持了,那么我们就来看看ensure是如何做到动态加载JavaScript与CSS的。
在介绍ensure内部的实现之前,让我们先来看看其功能:

ensure({
html: "popup.html",
javascript: "popup.js",
css: "popup.css"
}, function() {
Popup.show("hello world");
}
);
在这段代码中,ensure首先会确保popup.html、popup.js、popup.css这3个文件的加载,如果都没加载过ensure就会动态加载它们;如果已经加载过了,ensure不会再次加载。在确保这3个文件都加载后,ensure会调用后面的匿名函数,也就是执行Popup.show("hello world");。

接下来,就让我们看看ensure是如何动态加载JavaScript与CSS的。

加载JavaScript
在ensure当中,加载JavaScript分两种情况来执行,也就是Safari与非Safari这两种情况。

在IE、Firefox、Opera中加载JavaScript
在这三款浏览器中加载JavaScript,其实只需要创建一个script元素,把src指向要加载的URL,最后把script元素追加到head元素上,那就搞掂了。此项工作是在HttpLibrary.createScriptTag()中完成的。不过我们不仅仅要加载JavaScript,同时还需要知道它什么时候完成加载,这可以通过script元素的onload事件或onreadystatechange事件来实现。

在Safari中加载JavaScript
因为Safari 2不支持onload或者onreadystatechange,所以只能手动通过XHR把URL读去过来,然后再手动eval这段代码,这就带来了一个限制──只能加载本域的JavaScript文件。在ensure当中,eval的工作是通过HttpLibrary.globalEval()来完成的。为了让JavaScript代码在全局(global)上下文中eval,ensure还是使用了创建script元素的方法,并将要eval的JavaScript置于其内,最后把script元素追加到head元素内。

细心的人肯定要问,为什么HttpLibrary.globalEval()要如此设计,而非直接window.eval或者eval.call。这是因为,window.eval和eval.call都无法在IE6中实现和script标签加载JavaScript代码一模一样的效果,这两种做法的eval在IE6下仍然不是在全局上下文中执行的。搜索一下你就会发现一些相关的讨论,例如jQuery就曾经使用window.execScript()来完成此项任务。不过最终大家都发现添加script元素才是最好的跨浏览器解决方案,所以现在的jQuery和ensure都是如此实现的了。

加载CSS
相对于加载JavaScript而言,加载CSS就简单多了,而且方法也是类似的:在head元素内直接加入link元素就可以了。这也正是loadCSS()所完成的工作。

实际上,ensure没有确保CSS完成加载后再执行下去。这估计是因为浏览器都能够在CSS加载完成后自动应用到页面上,因此Omar AL Zabir就认为CSS的加载顺序是无关紧要的,不过假如CSS加载速度实在太慢,其实还是会影响显示效果的。

在IE6中加载CSS
这次需要特别照顾的是IE6,而非Safari。IE6在往head元素添加link元素时,必须在window的上下文中完成,因此添加link的函数通过call调用切换了上下文。

总结
实际上动态加载JavaScript与CSS都并不难,在大多数情况下只需要向head元素追加对应的子元素就可以了,只有Safari2和IE6这两款古老的浏览器是需要特殊照顾的。
官方地址
ensure

相关文章

  • 解决layui弹框失效的问题

    解决layui弹框失效的问题

    今天小编就为大家分享一篇解决layui弹框失效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JS发起HTTP请求的多种方式总结

    JS发起HTTP请求的多种方式总结

    这篇文章主要为大家详细介绍了JavaScript发起HTTP请求的多种方式,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • JS 加入收藏夹的代码(主流浏览器通用)

    JS 加入收藏夹的代码(主流浏览器通用)

    所有浏览器通用的js添加收藏夹代码,本文整理了多种方法实现加入收藏夹功能,下面为大家详细介绍下实现代码,感兴趣的朋友可以参考下哈
    2013-05-05
  • 解决ie img标签内存泄漏的问题

    解决ie img标签内存泄漏的问题

    下面小编就为大家带来一篇解决ie img标签内存泄漏的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • JavaScript 私有成员分析

    JavaScript 私有成员分析

    JavaScript是世界上最受误解的语言。有人认为它缺少信息隐藏的属性(封装),因为JavaScript对象不能拥有私有变量和函数。但这是误解。JavaScript对象可以有私有成员。下面进行说明。
    2009-01-01
  • 前端图片懒加载的原理与3种实现方式举例

    前端图片懒加载的原理与3种实现方式举例

    图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力,下面这篇文章主要给大家介绍了关于前端图片懒加载的原理与3种实现方式的相关资料,需要的朋友可以参考下
    2023-03-03
  • 详解用webpack的CommonsChunkPlugin提取公共代码的3种方式

    详解用webpack的CommonsChunkPlugin提取公共代码的3种方式

    本篇文章主要介绍了详解用webpack的CommonsChunkPlugin提取公共代码的3种方式,具有一定的参考价值,有兴趣的可以了解一下
    2017-11-11
  • js中数组(Array)的排序(sort)注意事项说明

    js中数组(Array)的排序(sort)注意事项说明

    本篇文章主要是对js中数组(Array)的排序(sort)注意事项进行了说明介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • JavaScript立即执行函数的三种不同写法

    JavaScript立即执行函数的三种不同写法

    这篇文章主要介绍了JavaScript立即执行函数的三种不同写法,需要的朋友可以参考下
    2014-09-09
  • JavaScript设计模式之迭代者模式详情

    JavaScript设计模式之迭代者模式详情

    这篇文章主要介绍了JavaScript设计模式之迭代者模式详情,迭代器设计模式能够可以让我们更方便的且有规矩的进行访问复合数据的每一项,也可以通过迭代器进行完成一些流线式操作
    2022-06-06

最新评论