很久没有更新自己的博客了,最近在忙公司的手机浏览器项目的开发工作,我会用学习笔记的方式记录下该项目的开发过程,今天这偏文章是比较综合性的,随意记录一下近2个月来开发这项目的一些感想,可能会写的比较乱。

叽歪一下 ---真的非常喜欢这个项目

  手机浏览器目前做的比较好的有UCWeb、GO浏览器、YOYO浏览器、Opera Mini浏览器,还有NOKIA、iphone等手机自带的浏览器。

  公司的浏览器借鉴了上面浏览器中优秀的部分,支持html、css2.0和部分js功能,目前正在扩展对WML的支持,另外扩展了部分css3.0的功能如背景拉伸,圆角等效果,浏览器以插件的形式应用到j2me的应用中,并且给相应的接口和j2me进行交互,手机的菜单可以自定义,能在页面中增加菜单的子项,支持数据和结构分离,和API接口连接功能。目前已经实现了基本的功能,做为产品还需进行优化和完善。

  在项目中我主要负责功能文档的整理,html标签支持以及css解析部分。

  首先整理了关于CSS和html和js的功能文档,在整理的过程中将以前熟悉的标签和属性好好的熟悉了一遍,同时一些比较冷门的属性和标签也过了一遍,2 篇近百页的功能文档就出来了,html的功能文档包含在了jsDom里了。

  html标签支持以及css解析部分这个需要java来做,因为之前没有接触过java这些底层的代码,现在还在学习阶段……后面会写一些关于java学习的相关笔记;

  浏览器的介绍先写到这里, 还有很多功能亟待优化和完善……

posted @ 2010-03-28 17:17 花生乐园 阅读(44) 评论(0) 编辑

这几天一直在研究xslt转换xml为xhtml,前面文章有介绍 使用xslt将xml解析成xhtml 的文章,

由于前面的方法xslt需要在xml文件内部直接导入,而项目中用到的xml文件是系统生成的,只能提供路径,而没有办法改写xml里面的内容,所以需要找一个方法能够在外部将xml和xslt关联在一起,这样既达到了目的,也可以应用于多个xml文件,方便管理。

先上代码,系统中使用module这个js进行打包,module这个工具是专门用来将js进行打包,这个工具以后的文章再做介绍,我自己现在只会使用,还没研究其底层的代码;这边我们将js写在一个文件里面,包括类以及类实现的方法,

下面是js代码:transform.js

Code

 

下面是html代码:XSLTtransform.htm

Code

 

 分析一下transform.js:

xmlDom这个构造函数是用来创建xml的dom元素,对于IE和FF,创建dom的方法不一样,IE是用window.ActiveXObject这个方法来创建,而FF用document.implementation.createDocument这个方法来创建,我们用这两个属性来判断是IE还是FF。

IE下针对不同版本的xml["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument","Microsoft.XmlDom"],用for循环进行遍历查找到对应的版本再new ActiveXObject(arrSignatures[i])建立dom;

FF下用document.implementation.createDocument("", "", null);直接创建dom ;

如果浏览器不支持 XML DOM object则throw错误 。

 

transformXSLT这个构造函数用XSLT将xml转换成html,FF下没有transformNode这个方法,所以我们自己构造了一个方法,

Code

然后用这个方法实现转换,在处理错误上IE和FF又有不同的处理方法,IE比较简单,有一个parseError属性装载错误信息,errorCode是错误的代码,reason是错误原因,line是错误的行号,还有其他一些信息,这里只要显示主要的错误信息就可以了,如果出错了就显示出错内容,如果没有出错则显示转换的结果sResult。FF下就比较复杂一点,用XMLSerializer和XMLSerializer.serializeToString()将xmlDom转换为字符串,再将字符串转换成dom对象,在转换的过程中如果报错,就能得到包含有parsererror的信息,判断得到的字符串的tagName是不是parsererror,如果是则将dom对象再转换成字符串抛出字符串中的内容,如果不是则显示转换的结果sResult

这里有几个注意点:

a.IE能检验出XML的DTD错误,而FF下只能检验出XML本身的语法错误

b.因为需要在浏览器下判断错误,最终的结果不好合并,可能代码结构上看起来不太合理,这也是无奈之举

 

用TransformBinder这个类进行封装,便于扩展和修改。TransformBinder.prototype.registerAction这个原型用于注册事件,再用TransformBinder.prototype.bind将事件进行绑定,需要使用这个类的时候,只需要new TransformBinder(XML,XSL),注册transformXSLT事件,再bind进行绑定,这样就实现这个效果了。如果需要扩展,再创建新的构造函数,注册并绑定到这个类上就可以实现效果。
 

 

 

posted @ 2009-11-24 13:20 花生乐园 阅读(163) 评论(0) 编辑

使用xslt进行解析的基本格式是这样的:如

 

Code

 XSL 指扩展样式表语言(EXtensible Stylesheet Language),xsl是xml的样式表,xsl 包括3部分,分别是:xslt(一种用于转换 XML 文档的语言)、x-path(一种用于在 XML 文档中导航的语言)、xsl-fo(一种用于格式化 XML 文档的语言),可以在http://www.w3cschool.cn/这个网站中找到相关内容的教程。

像前面代码描述的那样,xslt以xml的版本作为开始,用<xsl:style-sheeet ...>...</xsl:style-sheeet>的格式进行转换。

由于是初次接触xslt,对它了解并不是很透彻,下面只是罗列一些我在学习和使用它的时候碰到的一些要点;

一、递归以及传参数方法:

以一颗家族树为例子,xml文件是这样的:

Code

 现在要写一个xslt把家族的关系给表达出来,其实家族的关系就是一颗家族树,所以我们通过输出不同层次的缩进来表达这样的关系,最大的祖宗,然后按辈份分别进行缩进,最小辈份的排在最后面,缩进最多,这样一颗树的层次就出来了;下面是xsl文件的代码:

 

Code

在这里我们先在模板中定义了一个叫level的参数,用<xsl:param name="level"/>这样的语法,然后在主template(<xsl:template match="/">...</xsl:template>)添加模板的时候给参数赋值,

<xsl:apply-templates select="person">  <xsl:with-param name="level" select="'0'"/>  </xsl:apply-templates>,参数level的值一开始赋值为“0”,而我们用参数level的值($level)来作缩进的值,如text-indent:{$level}em,所以渲染xml内容的时候,第一层没有缩进,渲染完第一层后,我们通过

<xsl:apply-templates select="person">
<xsl:with-param name="level" select="$level + 2"/>
</xsl:apply-templates> 

这样的方法将参数level的值进行了累加从而实现了递归,这样每渲染一层,参数值就加上2,从而实现了不同层次的缩进来实现家族树的结构;这里还要说一下,我们通过@+属性如@name来取节点属性的值。

 二、用参数实现隔行换色:

还是引用上面的例子,以及参数level,我们在递归的时候给参数+1(奇数)而不是+2 (偶数),通过(.. test="$level mod 2 = 0")或(.. test="$level mod 2 = 1")就可以实现选取奇数行还是偶数行,我们用<xsl:choose> <xsl:when test="$level mod 2 = 0">...</xsl:when> <xsl:otherwise>...</xsl:otherwise> </xsl:choose>给奇数行和偶数行不同的background-color,从而实现了隔行换色的效果,具体代码如下:

Code

 

 三、符号转义以及CDATA语法:

目前碰到的只有“<”和“>” 要转义成&lt;和&gt;如果在表达式里出现这两个符号,页面在预览的时候就会报错;

另外我们需要将原文件的内容原封不动的输出来,包括换行或上面的大于和小于号等页面元素,这时候就需要CDATA这个标签, CDATA全称character data,翻译为字符数据,数据不进行转义直接输出。语法格式如下:

<![CDATA[这里放置需要显示的字符]]>

例如:

<![CDATA[<person name="ason"></person>]]>

在页面上显示的内容将是"<person name="ason"></person>";

四、几个教程中并没有提到的名词:

1、local-name();例子:<xsl:value-of select="local-name()"/>,这里所表达的意思就是当前节点的名字。

2、<xsl:call-template name="" mode="">...</xsl:call-template>,call-template和apply-template的区别,简单说apply是应用,call是调用。  
用apply时,引擎自动搜索与当前select指定xpath的匹配节点相匹配的template(该template必须有属性match)并使用该template进行处理,此时需要指定的是select的path。  
用call时就跟其它语言调用函数一样,必须指定name属性,相应的,该template必须有name属性,当然,也可以在这时with-param(当然相应的模板中有对应的param才行,不过这个不强制要求)。通过设置mode属性可以调用同一内容的不同表现形式,这个由自己去定义。

3、count(ancestor::*)这种写法是计算当前节点有多少个祖先节点,当然 ancestor也可以用child,following-sibling等xpath关系。

五、对于要符合多条件的判断,xslt不能很好的支持:

以家族树为例,我要取一个位于第二层的,名字叫Lichao的人,如果按字面理解我们可以写成<xsl:when test="count(ancestor::*) =2 && *[@name] = 'Lichao'">...</xsl:when>,但是这样写在预览xml的时候就会报错,我也想用条件里面套条件这样的写法,也不符合语法,查了很多相关的资料,没有找到很好的解决办法。

 

以上是在学习和使用xslt对xml进行解析的过程中的一些感想和记录,xslt很强大,有很多功能都没有涉及,当然,我还要继续学习和研究。

 

 

 

 

 

 

 

posted @ 2009-11-04 13:38 花生乐园 阅读(203) 评论(0) 编辑
Code

先上一段用js写的面向对象的代码,先建立一个ActionBinder的类,写法上也类似于java;因为js是基于html的dom对象来操作html的内容,在类中定义一个注册dom的方法registerDOM,用prototype将该方法原型化,方便调用;另外再增加一个注册事件的方法registerAction,也用prototype方法原型化;最后再用一个原型化的动作bind将已注册的dom和已注册的事件绑定在了一起,并执行。

再上一段原始的js代码片段:
Code

代码也实现了要的效果,对于一些简单的应用,上面那段效果能够满足,但对于比较复杂的一些程序,应用起来就比较麻烦,代码上写起来也较繁琐;如代码片段
Code

或者
Code

当然上面两段代码也有其他一些更简单的写法,总的来说还是出现很多冗余的代码。
用面向对象的方法写就比较灵活,如
Code

这样就不会有冗余的代码,而且js逻辑上也比较清爽,对于多个事件的绑定还有待研究。







posted @ 2009-09-28 14:05 花生乐园 阅读(81) 评论(0) 编辑

寂寞的hasLayout

hasLayout 是IE特有的一个属性,它很寂寞,正因为寂寞所以搞出很多莫名其妙的事情,很多的ie下的css bug都与其息息相关。查读了很多网上关于haslayout相关的文章,其中“haslayout-Sinab-搜狐博客”,链接地址:http://sinab365.blog.sohu.com/107239414.html这里的文章概括的比较全面,以及涉及的知识也比较丰富。


zoom: 1; 可以让 IE5.5+ 的任何元素(包括内联元素)获得 layout,但是在 IE5.0 中无效。
没有其他附带效果(内联元素会变成 inline-block,这个当然)。
如果需要通过验证,应该用条件注释将 zoom 隐藏起来。

其实当我们考虑到“向后兼容”时是很自相矛盾的,我们强烈建议页面设计者回过头看一下自己页面中用的到的明显的或是不明显的“hacks”,并用条件注释针对不同浏览器重新处理以保万无一失。



关于IE Mac 的小问题


IE Mac 和 windows 下的 IE 是完全不同的两个东西,它们各自拥有自己的渲染引擎,IE Mac 就全然不知“hasLayout”(或contenteditable)所谓何物。相比之下 IE Mac 的渲染引擎要更标准兼容一点,比如 height 就是被当作 height 处理,没有别的效果。因此针对“hasLayout”的 hacks 和别的解决方法(特别是通过使用 height 或 width 属性的)往往对 IE Mac 来说是有害的,所以需要对其隐藏。更多的关于 IE Mac 相关的问题可以在 IE Mac, bugs and oddities pages http://www.l-c-n.com/IE5tests/找到。


MSDN 文档


MSDN 中涉及到 hasLayout 这个 MS 属性的地方寥寥无几,而具体解释 layout 和 IE 渲染模型之间关系的则少之又少。
在IE4的时候,除了未经绝对定位也未指定宽高的内联元素,几乎所有元素都有某种 layout(MSDN)。http://msdn.microsoft.com/worksh ... mentandlocation.asp在这种早期的layout概念中,像 border, margin, padding 这些属性被称作“layout属性”,它们是不能应用到一个简单的内联元素上的。换句话说,“拥有layout”就可以粗略理解成:“可以拥有这几个属性”。
MSDN 上仍然使用 layout 属性这种说法, 只是含义变了,它们和拥有 layout 的元素已经没有什么关系了。在 IE5.5 中方才引入了 MS 的这个专有属性 hasLayout,http://msdn.microsoft.com/worksh ... rties/haslayout.asp也只是某种内部的标志位而已。
在 IE5.5 中,MSHTML Editing Platform(即可以通过设置来允许用户实时编辑、拖动 layout 元素以及调整其尺寸等)的文档中描述了三个和 layout 相关的重要特性:
如果一个 layout 元素中有内容,内容的排版布局将由它的边界矩形框决定。
拥有 layout 的意思基本上就是表示某元素是一个矩形。
从内部来说,拥有 layout 意思就是一个元素将自己负责绘制其内部内容。

(Editing Platform) http://msdn.microsoft.com/librar ... mshtmleditplatf.asp

和 layout 自身相关的内部工作机制直到2005年8月才有相应文档描述,当时由于 The Web Standards Project http://www.webstandards.org/和微软的特别工作小组的原因,Markus Mielke [MSFT] 打开了深入讨论的大门:
一般来说,在 Internet Explorer 的 DHTML 引擎中,元素是不对自己的位置安排负责的。虽然一个 div 或者一个 p 元素都在源码中有一个位置,在文档流有一个位置,但是它们的内容却是由它们最近的一个 layout 祖先(经常是 body)控制安排的。这些元素依赖它们祖先的 layout 来为他们处理诸如决定大小尺寸和测量信息等诸多繁重的工作。

(HasLayout概述)http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp


分析



我们的分析试图解释在已知案例下发生了什么事情,这种分析也应该可以作为未知案例下的指导。但我们这种试图利用种种测试案例投石探路的黑箱测试方法,是注定无法消除黑箱的神秘感的——我们无法回答“为什么”的问题。我们只能去尝试了解整个“hasLayout”模式的工作框架,以及它会怎样影响网页文档的渲染。因此,最终我们只能提供一些指导方针(而且只能是指导方针,而不是绝对的解决方案)。
我们认为他们所指的是一个小窗体。一个 layout 元素的内部内容是完全独立的,而且也无法影响其边界外的任何内容。
而 MS 属性 layout 只是某种标志位:一旦它被设定,这个元素就会拥有 layout“特性”,这包括体现在其自身以及其非 layout 孩子元素身上的特殊性能——比如浮动和层叠等。
这种独立性也许正可以解释为什么 layout 元素通常比较稳定,而且它们可以让某些 bug 消失。这种情况的代价有二,一是偏离了标准,二是它没有考虑到今后可能因此出现的 bug 和问题。
MS 的“页面”模式,从符号学角度考虑,可以看做是由很多互不相关的小的区块构成,而 HTML 和 W3C 的模式则认为“页面”模式应该是叙述完备的,故事性的相关信息区块构成的。



各种情况的详细说明



清除浮动和自动扩展适应高度
浮动元素会被 layou 元素自动包含。这是很多新手经常遇到的问题:在 IE 下完成的页面到了标准兼容浏览器下所有未清除的浮动元素都伸出了其包含容器之外。
Containing Floats http://www.complexspiral.com/publications/containing-floats
how to clear floats without structural markup http://positioniseverything.net/easyclearing.html

相反的情况:如果确实需要一个浮动元素伸出其包含容器,也就是自动包含不是想要的效果时,该怎么办?你很可能也会遇到这种头疼的问题,下面的深入讨论就是一个例子:
acidic float tests http://www.satzansatz.de/cssd/acidicfloat.html

在IE中,一个浮动元素总是“隶属于”它的 layout 包含容器。而后面的元素会受这个 layout 包含容器影响而不是这个浮动元素影响。
这个特性和IE6的那个自动扩展以适应内部内容宽度的特性,都可以看成是受这个规则影响的:“由它的边界矩形框决定”。
更糟的问题:clear 无法影响其 layout 包含容器之外的 float 元素。如果依赖这个 bug 在 IE 中布局的页面要转到标准兼容浏览器中,只有全部重做。
IE 的自动包含浮动元素也是经常需要的效果,它在其他浏览器中也可以达到:参考我们的 “和 CSS 规范类似的地方” 这一部分来了解一下包含浮动元素的相关内容。
浮动元素旁边的元素
当一个块级元素紧跟在一个左浮动元素之后时,它应该——作为一个块级元素——忽略这个浮动元素,而它的内容则应该因这个浮动元素而移位:一个紧跟在左浮动元素后的块级元素内的文字内容,应该沿着浮动元素的右边顺序排列并会(如果它的长度超过浮动元素)继续排列到浮动元素下方。但是如果这个块级元素有 layout,比如由于某种原因被设置了宽度,那么这整个元素则会因浮动元素而移位,就好像它自己也是一个浮动元素一样,因此其中的文字就不再环绕这个左浮动元素了(而会形成一个矩形区域,保持在它的右边。)
在 IE5 中一个块级元素的百分比宽度是基于浮动元素旁边的剩余空间计算的,而在 IE6 中则是依照整个父块级元素的可用空间计算的。所以在 IE6 中设置 width: 100% 会导致某种浮动元素旁边的溢出现象,于是各种布局问题也会因此而来。
一些关于浮动块旁边的 hasLayout 块的测试案例:
by using width http://dev.l-c-n.com/IEW2-bugs/float-layout.php
by using min-width (IE 7) and zoom (IE 6) http://dev.l-c-n.com/IEW2-bugs/float-adjecant.php

与此类似,和浮动元素相邻的相对定位元素,它的位置偏移量应该参照的是父元素的补白(padding)边缘(例如,left: 0; 应该将一个相对定位元素叠放于它前面的浮动元素之上)。在 IE6 中,偏移量 left: value; 是从浮动元素的右边距(margin)边缘开始算起的,这会因浮动元素所占的宽度变化导致水平方向的错位(一个解决方法是用 margin-left 代替,但是也要注意如使用百分值时会有一些怪异问题)。
layout blocks with relative positioning adjacent to floated blocks http://dev.l-c-n.com/IEW2-bugs/float-layout2-rp.php

根据规范所述,浮动元素应该与其后的盒子交织在一起。而对于没有交叉的二维空间中的矩形而言这是无法实现的。
如果谁真的需要向 IE 的这种不当行为屈服,那么如何让标准兼容浏览器中的盒子也有类似行为——即类似于 layout 盒子会自动“收缩”而给其前置的浮动元素让出空间的行为——就是一个问题了。我们给出的方法是跟着一个浮动元素创建一个新的块级格式化范围(block formatting context),这在我们的“和 CSS 规范类似的地方” 有讨论。
可以(再次)访问下面这个页面:
three pixel text-jog http://positioniseverything.net/explorer/threepxtest.html

我们可以看到跟在一个浮动元素后的 layout 元素不会显示这个3px间隙的 bug,因为浮动元素外围的3px硬边无法影响一个 layout 元素的内部内容,所以这个硬边将整个 layout 元素右推了3px。好比一个防护罩,layout 可以保护其内部内容不受影响,但是浮动元素的力量却将整个防护罩推了开来。
列表
无论是列表本身(ol, ul) 还是单个的列表元素(li),拥有 layout 后都会影响列表的表现。不同版本 IE 的表现又有不同。最明显的效果就体现在列表符号上(如果你的列表自定义了列表符号则不会受这个问题影响)。这些符号很可能是通过某种内部机制附到列表元素上的(通常是附着在它们外面)。不幸的是,由于是通过“内部机制”添加的,我们无法访问它们也无法修正它们的错误表现。
最明显的效果有:
列表获得 layout 后,列表符号会消失或者被放置在不同的或者错误的位置。

有时它们又可以通过改变列表元素的边距而重新出现。这看起来似乎是以下事实导致的结果:layout 元素会试图裁掉超出其边界的内部内容。
列表元素获得 layout 之后,会有和上面一样的问题出现,更多参考 (extra vertical space between list items)http://www.brunildo.org/test/IEWlispace.php

进一步又有一个问题就是(在有序列表中)任何具有 layout 的列表元素似乎都有自己独立的计数器。比如我们有一个含五个列表元素的有序列表,只有第三个列表元素有 layout。我们会看到这样:
1… 2… 1… 4… 5…
此外,如果一个有 layout 的列表元素跨行显示时,列表符号会底部对齐(而不是按照预料的顶部对齐)。
以上某些问题还是无法解决的,所以如果需要列表符号的时候最好避免让列表和列表元素获得 layout。如果需要限定尺寸,最好给别的元素设定尺寸,比如给整个列表外面套一个元素并设定它的宽度,又或者比如给每个列表元素中的内容设定高度等等。
另一个IE中列表的常见问题出现在当某个 li 中的内容是一个 display: block 的锚点(anchor)时。在这种情况下,列表元素之间的空格将不会被忽略而且通常会显示成额外的一行夹在每个 li 之间。一种避免这种竖直方向多余空白的解决方法是赋予这些锚点 layout。这样还有一个好处就是可以让整个锚点的矩形区域都可以响应鼠标点击。
表格
table 总是有 layout 的,它总表现为一个已定义宽度的对象。在IE6中,table-layout: fixed http://msdn.microsoft.com/worksh ... ies/tablelayout.asp通常和一个宽度设为100%的表格相同,同时这也会带来很多问题(一些计算方面的错误)。另外在IE5.5和IE6的quirks模式下还有一些别的需要注意的情况。http://dev.l-c-n.com/tables_2/
相对定位元素(r.p.)
注意,由于 position: relative 并不触发 hasLayout,所以很多诸如内容消失或错位的渲染错误就会因此而起。这些现象可能会在刷新页面、调整窗口大小、滚动页面、选中内容等情况下出现。原因是 IE 在据这个属性对元素做偏移处理时,却似乎忘了发出信号让其 layout 孩子元素进行“重绘”(而如果是一个layout元素,那么在其重绘事件的信号链中,这个传给其孩子的信号是会正常发出的)。
r.p. parent and disappearing floated child http://www.satzansatz.de/cssd/rpfloat.html
disappearing list-background bug http://positioniseverything.net/explorer/ie-listbug.html

以上是一些相关问题的描述。作为经验之谈,相对定位一个元素时最好给予其 layout。再有,我们也需要检查拥有这种结构的父元素是否也需要 layout 或者position: relative亦或二者都需要,如果涉及到浮动元素这点就十分重要。
绝对定位元素(a.p.):
包含区块,什么是包含区块?
理解 CSS 的包含区块概念很重要,它回答了绝对定位元素是相对哪里定位的问题:包含区块决定了偏移起点,包含区块定义了百分比长度的计算参考。
对于绝对定位元素,包含区块是由其最近的定位祖先决定的。如果其祖先都没有被定位,那么就使用初始包含区块 html。
通常情况下我们会用 position: relative 来设定任意包含区块。这就是说,我们可以让一个绝对定位元素所参考的原点和长度等不依赖于元素的排列顺序,这可以满足诸如“内容优先”这种可访问性概念的需要,也可以给复杂的浮动布局带来方便。
但是由于 layout 概念的存在,这种设计理念的效果在IE中就要打个问号了:因为在IE中绝对定位只有当其包含元素拥有 layout 时才会计算正确,而且绝对定位元素的百分比宽度参考也搞错了对象。这里 IE5 和 IE6 的行为不同但都有问题。IE7b2 的行为就要好很多,虽然有些小地方还是有错误。总之尽可能的让绝对元素的包含区块拥有 layout,而且尽量让其就是绝对定位元素的父级元素(也就是说这个包换元素和绝对定位元素之间没有绝对定位元素的别的祖先了)。
假设一个无 layout 的父元素被相对定位了——我们就得给它赋予 layout 才能使偏移量起作用:
Absolutely Buggy II http://www.positioniseverything.net/abs_relbugs.html

假设一个未定位的父元素需要特定尺寸,而且页面设计是基于百分比宽度的——我们就可以放弃这个想法了,因为浏览器支持不佳:
absolutely positioned element and percentage width http://www.satzansatz.de/cssd/tmp/apboxpercentagewidth.html
滤镜
MS专有的滤镜属性 filter http://msdn.microsoft.com/workshop/author/filter/filters.asp是只适用于 layout 元素的。有些滤镜扩展了对象的边界。它们会显示出自身特有的缺陷。http://www.satzansatz.de/cssd/tmp/alphatransparency.html
对已渲染元素的重排(re-flow)
当所有元素都已渲染完成时,如果有一个因鼠标经过而引起的变化产生(比如某个链接的 background 有变化),IE会对其 layout 包含区块进行重排。有时一些元素就会因此被排到了新的位置,因为当这个鼠标经过发生时,IE已经知道了所有相关元素的宽度、偏移量等数据了。这在文档首次载入时则不会发生,那时由于自动扩张的特性,宽度还无法确定。这种情况会导致在鼠标经过时页面出现跳变。
Jump on :hover http://www.satzansatz.de/cssd/pseudocss.html#hoverjump
quirky percentages: the reflow http://www.positioniseverything.net/explorer/percentages.html

这些和重排问题相关的 bug 会给百分比边距和补白使用较多的流动布局带来不少麻烦。
背景原点
MS专有的这个 hasLayout 还会影响背景的定位和扩展。比如,根据 CSS 规范,http://www.w3.org/TR/CSS21/colors.html#q2background-position: 0 0 应该指元素的“补白边缘(padding edge)”。而在 IE/Win 下,如果 hasLayout = false 则指的是“边框边缘(border edge)”,当 hasLayout=true 时指的才是补白边缘:
Background, Border, hasLayout http://www.brunildo.org/test/BackgroundBorderLayout.html

边距重叠
hasLayout 会影响一个盒子和其子孙的边距重叠。根据规范,一个盒子如果没有上补白和上边框,那么它的上边距应该和其文档流中的第一个孩子元素的上边距重叠:
Collapsing Margins http://www.w3.org/TR/CSS21/box.html#collapsing-margins
Uncollapsing Margins http://complexspiral.com/publications/uncollapsing-margins

在 IE/Win 中如果这个盒子有 layout 那么这种现象就不会发生了:似乎拥有 layout 会阻止其孩子的边距伸出包含容器之外。此外当 hasLayout = true 时,不论包含容器还是孩子元素,都会有边距计算错误的问题出现。
Margin collapsing and hasLayout http://www.brunildo.org/test/IEMarginCollapseLayout.html

块级别的链接
hasLayout 会影响一个块级别链接的鼠标响应区域(可点击区域)。通常 hasLayout = false 时只有文字覆盖区域才能响应。而 hasLayout = true 则整个块状区域都可响应。添加了 onclick/onmouseover 等事件的任意块级元素也有同样的现象。
Block anchors and hasLayout http://www.brunildo.org/test/IEABlock1.html

在页面内使用键盘浏览:探索中
当使用 tab 在页面中浏览时,如果进入了一个页内链接(in-page link),那么接下来再按的 tab 键就不会正常继续了:
hasLayout Property Characterizes IE6 Bug http://jimthatcher.com/news.htm#haslayout
Keyboard Navigation and Internet Explorer http://juicystudio.com/article/ie-keyboard-navigation.php
tab 键会把用户带到(这通常是错误的)其最近的 layout 祖先中的第一个目标(如果这个祖先是由 table, div, span 或某些别的标签构成)。

收缩包围(shrink-wrapping)现象
给已经有 width: auto 的元素添加某些属性会导致它们在计算自身宽度时使用一种收缩包围的算法。比如这些属性 float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table.
这些属性造成的现象在IE/Win中也存在,当然这是只对那些它支持的属性而言。但是当一个应该收缩包围的元素中包含一个拥有“layout”的块级元素时,在绝大多数情况下,这个孩子元素的宽度会尽可能地扩展而与其中包含的内容无关,同时也阻止了父元素的收缩包围现象。
例子: http://dev.l-c-n.com/IEW2-bugs/shrinkwrap.php
一个浮动的纵向导航无序列表并没有收缩包围,因为其中的链接为了消除列表的多余空白bug并扩展可点击区域而拥有了 layout:a {display: block; zoom: 1;}。

这时收缩包围现象只有在以下情况仍然有效:拥有 layout 的孩子元素同时也被赋予了一个特定宽度,或者这个孩子元素本身也是一个具有收缩包围特性的元素,比如浮动元素。
边缘裁切
通常而言,当一个盒子包含了诸如伸出其边缘的内容这种更复杂的结构时,这个容器就经常需要“hasLayout”来避免一些渲染错误。但使用这种常用方法又会在边界处理时左右为难,因为一个获得“layout”的元素会变成某种自封闭的盒子。
内部的内容盒子会被裁切,比如使用负边距向外移动时。
Clipping of negative margined blocks in a hasLayout container http://dev.l-c-n.com/IEW2-bugs/min-width-clip.php

被裁掉的部分当内容盒子触发了“layout”时可以再次出现,但在 IE6 中需要同时拥有 position: relative 才行。IE7 在这方面要略有改观,它不再需要额外的 position: relative 了。



堆叠,分层和 layout


IE/Win 中似乎有两种分层和堆叠顺序:
一种是(伪)试图采用CSS的模式:Effect of z-index value to RP and AP blocks http://www.aplus.co.yu/css/z-pos/
还有一种是由“hasLayout”及其孪生兄弟“contenteditable”的行为产生的堆叠顺序。正如在上面相对定位的例子中展现的那样,在 layout 影响下的堆叠现象就好像 Harry Houdini (译者注:魔术师,以纸牌魔术成名)的拿手戏法儿一样。

两种堆叠模式虽互不相容,但却共存于IE的渲染引擎中。经验之谈:调试的时候,两种情况都要考虑到。我们可能会有规律地在下拉菜单或者类似的复杂菜单中看到相关问题,因为它们往往牵涉到堆叠,定位和浮动等诸多令人头疼的问题。给那些 z-index 定位的元素 layout 是一种可能的修正方法,不过也不限于此,这里只是提醒一下。
混乱的 contenteditable
如果给一个 HTML 标签设定 contenteditable=true 属性,比如,将会允许对该元素以及其 layout 子元素进行实时的编辑、拖动改变尺寸等操作。你可以把这属性用在浮动元素或者一个有序列表中的 layout 列表元素上看看效果。
为了对元素进行操作(编辑它们),“contenteditable”和“hasLayout”为那些 hasLayout 返回 true 的元素引入了一套单独的堆叠顺序。
Editing Platform http://msdn.microsoft.com/librar ... mshtmleditplatf.asp继承了 layout 概念,对 layout 的误解多是因 contenteditable 而起即可作为证明(那些某种程度上集成了IE编辑引擎的应用软件多暗含着对layout概念的某种强制向后兼容性)。
More on contenteditable http://annevankesteren.nl/2005/07/more-contenteditable



和 CSS 规范类似的地方



你的 MSIE 页面在别的浏览器中一团糟?我们可没必要让这种事情发生。如果使用恰当,任何好的浏览器都能摆平 MSIE 的页面——只要你使用一些正确的 CSS。
利用 hasLayout 和“新的块级格式化范围”http://www.w3.org/TR/CSS21/visuren.html#q15之间的细微相似之处,我们可以有几种方法在标准兼容浏览器中重新实现 hasLayout 的“包含浮动元素”http://www.w3.org/TR/CSS21/visudet.html#root-height效果,和一些“浮动元素旁边的元素”http://www.w3.org/TR/CSS21/visuren.html#floats所特有的效果。
Reverse engineering series http://www.gunlaug.no/contents/wd_example_01.html
Simulations http://dev.l-c-n.com/IEW/simulations.php


Quirks 模式


关于这种渲染模式的的信息,请参考我们的 quirks 模式 http://www.satzansatz.de/cssd/quirksmode.html章节。
Layout ——结论
整个 layout 概念和一些基本 CSS 概念是不兼容的,即包含,排列,浮动,定位和层叠等。
由于页面中元素或有或没有 layout,会导致 IE/Win 的行为和 CSS 规范相违背。



拥有 layout ——另外一个引擎?



IE 的对象模型看起来是文档模型和他们传统的应用程序模型的糅合。我之所以提到这点是因为它对于理解IE如何渲染页面很重要。而从文档模型切换到应用程序模型的开关就是给一个元素“layout”。

(Dean Edwards)

有时候要解释清楚某种行为是不可能的:就比如 hasLayout,会根据它的状态选择两种不同渲染引擎的一种使用,而且每一种都有其自己的 bug 和怪异之处。



不可消除的 bug



软件 bug 是由于在制作过程中对完整性和逻辑问题考虑不周等人为错误而导致的。这是人类的固有缺陷,目前还没有什么好的解决方法。
同样由于这种缺陷,任何试图不重写软件而修复 bug 的做法,都将会不可避免的导致软件中出现更复杂的bug。
所有依赖别的软件的软件——当然包括依赖操作系统,也会同样依赖他们的 bug。于是我们会从所有关联的软件中得到一连串的 bug,这也更说明找到一个无 bug 软件是几乎不可能的。

(Molly, the cat?)

本文创建于2005年6月30日,最后一次修改于2006年4月2日。
编者:
Holly Bergevin http://positioniseverything.net/
Ingo Chao http://www.satzansatz.de/css.html
Bruno Fassino http://www.brunildo.org/
John Gallant http://positioniseverything.net/
Georg Sørtun http://www.gunlaug.no/
Philippe Wittenbergh http://emps.l-c-n.com/

特别致谢给予此项目支持的:
Dean Edwards, and Molly ‚the cat?

各种语言版本:
Original(English)
Brazilian   Portuguese by                         Mauricio Samy   Silva
中文版本 by old9
Italian by Gabriele Romanato

相关讨论:
dean.edwards.name/weblog/

[url=mailto:spam.layout@satzansatz.de]联系作者:[/url]

版权说明:
本文基于创作共用协议发布。



目录



介绍
hasLayout —— 定义
术语
问题种种
Layout 从何而来
默认 layout 元素
属性
有关内联级别元素
脚本属性 hasLayout
CSS hacks
Hack整理
关于 IE Mac 的小问题
MSDN文档
分析
各种情况的详细说明
清除浮动和自动扩展适应高度
浮动元素旁边的元素
列表
表格
相对定位元素(r.p.)
绝对定位元素(a.p.):包含区块,什么是包含区块?
滤镜
对已渲染元素的重排(re-flow)
背景原点
边距重叠
块级别的链接
在页面内使用键盘浏览:探索中
收缩包围(shrink-wrapping)现象
边缘裁切
堆叠,分层和 layout
混乱的 contenteditable
和 CSS 规范类似的地方
Quirks 模式
Layout —— 结论
拥有 layout —— 另外一个引擎?
不可消除的 bug

因为考虑到IE6、IE7浏览器的兼容性,所以haslayout这个属性不得不被重视,有那么多前端开发的人和你打交道,相信你此刻也并不会寂寞了!

posted @ 2009-09-01 21:44 花生乐园 阅读(68) 评论(0) 编辑
摘要: css Sprites原理CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景 图片的...阅读全文
posted @ 2009-08-25 10:22 花生乐园 阅读(103) 评论(0) 编辑
摘要: 如果你经常浏览一些国外的网站,你会发现他们的网站是非常简洁、清爽、干净的,版面内容也非常简短,跟中文网站的版面截然不同的,而且他们的版面改变很少,一般几年才会改动一次,版面也没有蹦蹦跳跳的广告。一方面可能跟西方人文化思维习惯有关,另一方面,在国外(像美国、澳大利亚等),国家有颁布相应的法律来约束大众信息传播网站,这就是 section 508法案,大体上来描述就相当于:如果某个大众信息传播网站,如...阅读全文
posted @ 2009-07-29 10:33 花生乐园 阅读(89) 评论(2) 编辑
摘要: 用jq实现的仿163首页头部广告的下拉效果:下面是代码:[代码]在ie6.0、FF和Opera浏览器进行测试的时候,就是FF浏览器在滑动到最底端时有个跳动的情况,待解决!问题已经解决了~只要给p定义样式:div#ad p {height:25px; padding:0;margin:0;line-height:150%;}这样在ie6.0、FF和Opera浏览器下显示效果一致;FF下还有点小问题,...阅读全文
posted @ 2009-07-28 12:21 花生乐园 阅读(485) 评论(3) 编辑
摘要: 好几天前就知道了日全食将在7月22日这一天来临,杭州刚好处在观测带上,对于我们来说是件幸运再加幸运的事情,更加幸运的是今天杭州的天气还行,在日全食到来之前,天空就出现了太阳;我不是专业的天文爱好者,没有一些专业的观测设备,我和同事就用废弃的胶卷底片遮着对着太阳观看,由于光线还是太亮,就叠多层的底片,终于能对着太阳看了,从底片上看出去太阳已经变成芽形,隔一段时间看一下,那个芽形慢慢变小,而我周围的环...阅读全文
posted @ 2009-07-22 13:06 花生乐园 阅读(100) 评论(0) 编辑
摘要: 1、官方的检查机制有些问题。背景色与字体色相同的情况下会有错误提示。这是不合理的检测报错机制。2、图片的 alt="" 属性必须每张图片都加上,而且对齐属性用CSS来定义。不加不能通过XHTML 1.0的验证。3、每个文档必须加上DTD声明。<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN" "http://www.w3...阅读全文
posted @ 2009-07-21 13:19 花生乐园 阅读(139) 评论(1) 编辑