西红柿爱番茄

Feed Rss

文章标签 ‘document.body’

2010-6-18 updates: surfing的时候发现了个非常不错的关于浏览器如何构建DOM树的工具:Live DOM Viewer。通过它可以非常直观的测试不同浏览器对解析HTML内容的差异。 2010-6-17 updates: 在跟番茄讨论这个问题的时候,他举例用CSS的样式来证明了body元素也会自动渲染的事实,这点本人没有想到,也没有经过测试就说了下面的文章(内容已经修改过了),惭愧……但是还存在这样的一个问题:就如下面的出现的情况,如果页面没有声明body标签的时候,为什么CSS可以渲染body的样式,而javascrpt无法直接调用document.body的引用?《测试用例》 经过一番测试和狂搜,大概明白了其中的原因,这需要了解javascrpt解析引擎和CSS渲染引擎是在什么时候介入页面起作用了。在浏览器解析HTML并生成DOM树的时候,是按从上至下的顺序解析的,浏览器最先会生成DOM树的根节点(HTMLDocument)和HTMLHEADElement(不知可否这样说),不管页面有没有声明html和head标签都会自动最先生成。之后再往下解析HTML标签,如果在遇到body标签(或者布局性标签)之前先遇到script标签的时候,就会在DOM树中生成该节点,但是这时这个script节点是head元素的子元素,而且这时候javascrpt解析引擎就会执行其中的代码(如果此时页面还没有解析到body的时候,或者还没有解析到如下面所说的布局性的标签的时候,DOM树中还不存在body节点,调用document.body就会出错),如果在body(或者其他布局性标签)之前,解析到link或者style标签,也会生成相应的节点,也是head的子节点,但是CSS渲染引擎并不会立即渲染页面的样式,它会在DOM树解析完成的时候才开始渲染页面,这就是上面的问题中所说的情况:CSS可以渲染body,而JS无法调用body的引用。《测试用例》,用firebug查看该实例生成的HTML结构。 所以,应该记住一点:如果在页面中使用script标签外联的js文件或者是行内脚本,当浏览器解析HTML内容的过程中遇到script标签的话,就会立即加载并且执行script的代码,之后才会继续解析后续的HTML的内容,除非是通过异步、动态加载js文件或者给script标签加上了defer、async属性。 但是如果在script或者link、style标签之前,有布局性的标签的时候,这就有两种情况了:没有文本内容的布局性标签和有文本内容的布局性标签。 当没有文本内容的时候。Chrome、Safari、Opera会将布局性标签下面的link、style、script等标签也渲染到body元素里(自动补全了该元素),这样通过script获取document.body的引用就没问题了。可是Firefox、IE会将link、style、script等标签都渲染到head元素里,先于body元素先在DOM树中生成,这样在js代码里直接获取document.body的引用就会出错。《测试用例》 当有文本内容的时候。各个浏览器都显示一致了。都会把link、style、script都渲染到body里,这样body元素就先于link、style、script标签等先在DOM树中生成,获取body的引用就没问题了。《测试用例》 ============================================================================ 正如题目中所说,一个正常的包含html、head、body的标签是不会出现这个问题的,页面都有声明了,浏览器它就省事多了。但是当页面没有html、head、body标签的时候,浏览器就有点发狂了,它惩罚偷懒的人的时候到咯。 在开始叙述之前,先来测试几个在不同的条件下的样例(这个测试主要是针对下面将要叙述的关于动态加载js来说的),下面将会提到一个暂时不知道怎么表达的词,就是我说的“布局性的标签”,它主要是指p、span、div等这些具有布局性质的元素,因此script、link、style等就不是了。 当页面无html、head、body标签,而且也没有其他的布局性的标签,只有一个script:《测试用例》。document.body出错了 当页面无html、head、body标签,有布局性的标签,而且带有文本内容(比如:<p>hello</p>,嵌套的空标签也不行),当这些标签在当前script标签前面的时候:《测试用例》。可以获得document.body的引用,它变好了。但是如果前面不是布局性的元素,或者是嵌套没有文本内容的布局性元素,《前面是link元素》,《嵌套空布局性元素》,在空布局性标签的情况下,IE、Firefox都挂了,chrome,safari,opera正常。前面是link元素的话全挂鸟。 当页面无html、head、body标签,有布局性的标签,而且不管有没有内容,当这些标签在当前script标签后面的时候:《测试用例》。document.body出错,它纠结了。 跟上面相同的条件,document.documentElement和document.getElementsByTagName(“head”)都可以获得引用:《documentElement》,《document.getElementsByTagName(“head”)》 … 了解更多