Home > JavaScript > JavaScript 初始化装载方法

JavaScript 初始化装载方法

November 16th, 2008

说到 JavaScript 的初始化装载, 可能 onload 是被立刻想到的方法. 但很遗憾, 这是最坏的选择, 我以前也一直犯过这样的错误. 为什么说它不好呢? 因为 onload 不是在 document 加载完成的时候调用的, 而是在页面所有元素 (包括图片等) 全部加载完成才会调用. 也就是说, 如果你的页面上有个尺寸很大的图片, 下载需要很长时间, 那么你的脚本就一直不能被初始化, 直到图片装载完成, 严重影响用户体验.

幸运的是, 在 W3C 中有个叫 DOMContentLoaded 的事件, 故名思意, 它会在 DOM (文档对象模型) 被加载完成的时候触发. 那么我们就可以通过下面的方法调用初始化脚本的方法了.

1
document.addEventListener("DOMContentLoaded", init, false);

但很遗憾, 现在很多浏览器并不玩 W3C 这一套, 支持 DOMContentLoaded 事件的只有 Firefox, Opera 9 等一些 "现代" 浏览器, 而被集成到两大商业桌面系统的 IE 和 Safari 都不支持. 尽管如此, 我们可以用别的一些方法进行处理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 如果支持 W3C DOM2, 则使用 W3C 方法
if (document.addEventListener) {
	document.addEventListener("DOMContentLoaded", init, false);
 
// 如果是 IE 浏览器
} else if (/MSIE/i.test(navigator.userAgent)) {
	// 创建一个 script 标签, 该标签有 defer 属性, 当 document 加载完毕时才会被载入
	document.write('<script id="__ie_onload" defer src="javascript:void(0)"></script>');
	var script = document.getElementById("__ie_onload");
	// 如果文档确实装载完毕, 调用初始化方法
	script.onreadystatechange = function() {
		if (this.readyState == 'complete') {
			init();
		}
	}
 
// 如果是 Safari 浏览器
} else if (/WebKit/i.test(navigator.userAgent)) {
	// 创建定时器, 每 0.01 秒检验一次, 如果文档装载完毕则调用初始化方法
	var _timer = setInterval( function() {
		if (/loaded|complete/.test(document.readyState)) {
			clearInterval(_timer);
			init();
		}
	}, 10);
 
// 如果以上皆不是, 使用最坏的方法 (本例中, Opera 7 将会跑到这里来)
} else {
	window.onload = function(e) {
		init();
	}
}

补充一下, JavaScript 中的 defer 属性是 IE 特有的. 它告诉浏览器, 这是一段不需要立即执行的代码, 在文档装载完毕时才被执行. 如果 src 等于 example.js, 那么 example.js 会在文档装载完成后才被装载.

其实绝大多数 JavaScript 框架已经为我们处理好了, 例如 jQuery 的 ready 方法, 只是实现方法不同而已.

用了 JavaScript 有段时间了, 却没有系统的学过, 知识点零零散散的, 所以最近买了本相关的书. 书中谈到了上述问题和解决办法, 我觉得这个方法很实用, 就简单介绍一下. 现在卖个关子, 等我看完这本书再向大家介绍一下书中的内容和知识点.

JavaScript ,

声明: 本站遵循 署名-非商业性使用-相同方式共享 3.0 共享协议. 转载请注明转自 NeoEase

  1. November 16th, 2008 at 01:15 | #1

    又是沙发哟~
    隐约记得以前貌似给你提到过这个问题的哟~

  2. November 16th, 2008 at 01:18 | #2

    @JAY
    嗯, 我以前只兼顾了 W3C 和 IE, 觉得有必要拿出来讲讲, 免得忘了. 哈哈~

  3. November 16th, 2008 at 07:15 | #3

    这么早都没抢到沙发

  4. November 16th, 2008 at 11:17 | #4

    "知道图片装载完成",哈哈,发现错别字一个!~~ :smile:
    对精益求精的MG来说这可是比应该的哦! :cool:

  5. November 16th, 2008 at 11:56 | #5

    @leojn
    没我早...

    @patrick
    更正了, 谢谢!

  6. November 16th, 2008 at 12:50 | #6

    对了,一直有一个问题。主题样式里似乎没有关于图片的caption的定义,我每次都需要自己去添加。建议check一下

  7. November 16th, 2008 at 13:20 | #7

    什么书哈?呵呵,可以推荐下!!

  8. November 16th, 2008 at 15:04 | #8

    莫非是那本很厚很厚的……封面是一只犀牛?

  9. November 16th, 2008 at 16:19 | #9

    @David
    什么是图片的 Caption?

    @xiaorsz
    好吧, 我承认! 书落在公司并且我忘记书名了, 下周告诉各位.

    @cool8jay
    不是, O'Reilly 的书不太适合我.

  10. November 16th, 2008 at 17:24 | #10

    很好很强大。学习了。

  11. November 16th, 2008 at 19:38 | #11

    jquery确实降低了js门槛,比如ready还有冒泡,哈

  12. November 17th, 2008 at 00:25 | #12

    @bigCat
    嗯, 这门书也说到冒泡了...

  13. November 17th, 2008 at 08:43 | #13

    jquery里的ready很好用~ :grin:

  14. November 17th, 2008 at 10:43 | #14

    @mg12
    例如http://simplife.org/2008/09/16/bankruptcy-of-lehman-and-financial-crisis.html这篇里面,图片下面的文字“雷曼兄弟员工纷纷卷“铺盖”回家”就是caption,wordpress2.6新增加的。

  15. November 17th, 2008 at 21:51 | #15

    @David
    这个怎么支持? 就是框在一起?
    下次试试吧, 呵呵~

  16. November 18th, 2008 at 15:18 | #16

    搜到的一篇http://www.digglife.cn/articles/about-wordpress26-image-caption.html,应该就是样式里多加段代码

  17. November 18th, 2008 at 20:45 | #17

    @David
    好的, 谢谢!

  18. November 22nd, 2008 at 00:47 | #18

    研究了半天你上面的RSS Feed的代码,没发现有鼠标时间啊。怎么就能将隐藏的div展现出来的呢?希望指点一下

  19. November 22nd, 2008 at 11:54 | #19

    使用setTimeout函数来初始化不好吗

  20. November 22nd, 2008 at 22:12 | #20

    @romotc
    因为我将页面代码和 JavaScript 分离处理了.

    @aobject
    如果你喜欢那样, 当然可以.

  21. November 24th, 2008 at 21:56 | #21

    mg12 :@romotc因为我将页面代码和 JavaScript 分离处理了.
    @aobject如果你喜欢那样, 当然可以.

    但是没发现有onxxx的方法啊。太神奇了...现在你把这个效果给删掉了,没办法研究了

  22. November 25th, 2008 at 00:06 | #22

    @romotc
    没删除, 我的 Reader Menu 和评论翻页都是用这个实现的.

  1. January 7th, 2009 at 01:31 | #1