13 标准网页布局的兼容性处理
标准网页设计的最大挑战不在于技术本身,而在于浏览器兼容性处理。所谓浏览器兼容问题,就是当我们使用不同的浏览器(如IE 7、IE 6、Firefox等)访问同一个页面时,可能会出现不一致的情况,出现这种现象的原因有很多种,但根本原因就是浏览器对于技术支持的标准不同造成的。
IE浏览器对于标准技术的支持是很不完善的,这些问题可以分为两种:一种是IE支持某种技术或功能,但是实现该功能的方法和途径与标准技术不同;另一种是IE浏览器自身的解析机制存在很多Bug,导致页面解析效果与标准不同。
本章将兼顾IE 6、IE 7和FF三种主流版本或类型浏览器进行讲解,其中IE 6浏览器用户数最多,IE 7的用户将逐步超越和代替IE 6,而FF浏览器代表了标准浏览器的主流。
1 兼容不同类型浏览器的基本方法
不同类型浏览器对于CSS技术的支持是不完全统一的,如果再加上浏览器对于CSS解析时存在各种Bug,CSS兼容性处理就变得异常复杂。
解决浏览器兼容问题的方法,这些方法被称之为Hack(即补丁的意思)。所谓Hack,就是利用各种过滤方法专门为特定类型浏览器定义样式,即称之为过滤器(Filter),从而实现在不同类型浏览器中呈现相同的渲染效果。
过滤器是一种形象的称呼,实际上它就是各种浏览器支持或不支持某种声明或样式的特殊用法。例如,IE 6以下版本浏览器不支持!important关键字,我们就可以利用这个关键字专门为IE 6及其以上版本浏览器或者非IE浏览器定义样式,从而过滤掉IE 6以下版本浏览器在解析时存在的问题。
2
1 标准网页布局的兼容性处理
1.1 常用过滤器
目前全球设计师发现并总结出来的过滤器非常多,要记住这些过滤器是很繁琐的,读者可以参阅http://centricle.com/ref/css/filters/
3
1 标准网页布局的兼容性处理
1.1 常用过滤器
http://www.communis.co.uk/dithered/css_filters/css_only/index.html
4
1 标准网页布局的兼容性处理
1.1 常用过滤器
IE 7版本浏览器专用过滤器
如果专门为IE 7版本浏览器定义样式,则可以使用如下过滤器。该过滤器还可以兼容即将上市的IE 8版本浏览器。
<style type="text/css">
*+html body {
background:blue;
}
</style>
兼容原理:
“*”符号在IE浏览器中被认为是根节点,所以它可以包含html元素,而对于非IE浏览器来说,文档根节点应该是html,而不是“*”,所以当使用“*”通用符号包含html元素时,非IE浏览器会认为它是非法的,从而忽略这个选择器所定义的样式。同时IE 6及其以下版本浏览器不支持相邻选择器(+),所以也会忽略该选择器定义的样式。
5
1 标准网页布局的兼容性处理
1.1 常用过滤器
IE 6及其以下版本浏览器专用
<style type="text/css">
* html body {
background:red;
}
</style>
不过从语法角度分析,IE 7应该支持*通用符号包含html元素,但事实上并不支持,所以这也是一个很有趣的过滤器。
6
1 标准网页布局的兼容性处理
1.1 常用过滤器
IE 7和非IE浏览器专用
<style type="text/css">
html>body {
background:green;
}
</style>
兼容原理:
因为IE 6及其以下版本浏览器不支持子选择器,所以会忽略该过滤器定义的样式。
7
1 标准网页布局的兼容性处理
1.1 常用过滤器
非IE浏览器专用
style type="text/css">
html>/**/body {
background:yellow;
}
</style>
在IE 8中存在问题,需要使用其他方法。
8
1 标准网页布局的兼容性处理
1.2 使用IE条件语句过滤
IE条件语句是IE浏览器自定义的一套逻辑语句,利用这些语句可以更加有效的为IE系列版本浏览器定义样式。
IE条件语句实际上就是HTML注释语句,只不过在注释标识符中增加了一组关键字,这一组关键字对于IE浏览器来说是有效的,但是对于其他浏览器来说,则被视为注释信息完全忽略。由于IE浏览器能够根据条件语句中设置的条件决定解析的版本,从而实现利用条件为不同IE版本浏览器定义样式的目的。
<!--[if IE]>
<h1>所有IE版本浏览器可识别</h1>
<![endif]-->
9
1 标准网页布局的兼容性处理
1.2 使用IE条件语句过滤
IE条件语句以中括号([])为起止标识符,其中包含一个条件语句。条件语句放在注释标识符内,且与注释标识符内部相邻,语法格式如上面示例。
在条件语句中可以增加修饰性关键字,如lte、lt、gte、gt和!,这些关键字作用说明如下:
lte:小于或等于某个版本的IE浏览器。
lt:小于某个版本的IE浏览器。
gte:大于或等于某个版本的IE浏览器。
gt:大于某个版本的IE浏览器。
!:不等于某个版本的IE浏览器。
10
2 流动布局的兼容性处理
不同浏览器对于CSS的解析是不同的,这种不同源自不同浏览器的解析机制不同,所以在设计之初读者就应该养成良好的兼容处理习惯,学会直面主流浏览器存在不不兼容性问题,避免后面兼容处理的难度和成本。
目前市场上不同类型或版本的浏览器很多,但是如果从用户数、标准度等方面来比较,其实浏览器市场仅包括两大类型:IE类型和非IE类型浏览器。当大家提及某个页面不兼容,或者出现布局问题,多因为它无法兼容标准浏览器,或者仅支持IE浏览器。而非IE浏览器多建立在标准解析机制之上,所以它们都能够很好支持标准。
本章将以FF(Firefox)浏览器作为非IE的代表,
11
2 流动布局的兼容性处理
2.1 关于不同浏览器的默认值问题
提及页边距,IE浏览器默认为body元素的margin-left属性进行定义,默认值约为10像素;而对于FF浏览器来说,默认为body元素的padding-left属性进行定义,默认值约为8像素。与此类似的默认值差异设置还包括:
列表样式:IE默认使用margin-left属性定义,值约为40像素;而FF默认使用padding-left属性定义,值约为40像素。
网页居中样式:IE默认使用text-align属性,值为center;而FF默认使用margin属性,设置左右边界为auto。
鼠标指针样式:IE默认使用cursor属性定义,值为hand;而FF默认使用cursor属性,值为pointer。
12
2 流动布局的兼容性处理
2.2 列表兼容性处理—有序列表高度问题
所谓有序列表高度问题:就是当为有序列表定义高度时,列表序号将显示无效。该现象存在于所有版本的IE浏览器中,非IE浏览器不存在该问题。
如果定义项目符号为拉丁字母等其他有序符号,在IE中会统一显示为点号项目符号,而在非IE下会显示为定义的字母序号显示。
解决方法:
避免使用height定义列表项的高度,改为line-height属性间接定义高度。
2 流动布局的兼容性处理
2.3 列表兼容性处理—列表宽度问题
这个问题存在于所有版本的IE浏览器中。当为列表框定义一个宽度时,在某种情况下,项目符号会突然消失,而在非IE下却能够正常显示。
方法一,定义项目符号位置在内部显示。
方法二,为列表项定义左侧边界大小为2个字体宽度。
方法三,为列表框定义左侧补白为2个字体宽度。
2 流动布局的兼容性处理
2.4 列表兼容性处理—项目符号变异问题
这个问题存在于所有版本的IE浏览器中。当为列表结构中某列表项定义宽度或高度等特殊属性时,有序项目符号会发生混乱,而在非IE下却能够正常显示。
对于此类问题目前还没有好的方法,不过可以通过间接方法来实现。也就是说如果要定义列表项的宽度,不妨给列表项包裹一个外套,然后为外套定义宽度来实现。但是这样做会破坏列表结构的语义性,最佳方法应该是避免为列表项定义高度和宽度,除非不隐藏项目符号的显示。
还有一种方法:取消列表结构的默认项目符号,使用背景图像来定义项目符号,这种做法会更为灵活和个性。
2 流动布局的兼容性处理
2.5 列表兼容性处理—列表行双倍高度问题
个问题存在于IE 6及其以下版本浏览器中。当为列表项中嵌套超链接元素,且定义超链接(a元素)为块状显示(块状显示的目的是可以定义超链接的大小),这时在IE 6及其以下版本浏览器中列表行会显示双倍高度,而在IE 7和非IE下却能够以正常行高显示。
方法一,为列表项定义宽度、高度或边框。
li {border-bottom:1px solid #CCC;} /* 增加底边线 */
或者
li { width:100%;} /* 满宽显示 */
或者
li { height:1.1em;} /* 以行高大小定义高度 */
16
2 流动布局的兼容性处理
2.5 列表兼容性处理—列表行双倍高度问题
方法二,使用zoom属性。
zoom是IE的私有属性,它能够定义元素的缩放比列。但是它也能够使列表项恢复到正常行高。例如,下面代码可以轻松修正列表项的双倍行高问题,且对于其他版本浏览器没有副作用。
17
2 流动布局的兼容性处理
2.6 列表兼容性处理—列表项错行问题
这个问题存在于FF浏览器中。当为列表项中嵌套块状元素,且项目符号在内部显示时,FF浏览器中会出现错行问题,而在IE等其他浏览器中却不会出现这类问题。
方法一,定义项目符号显示在列表项的外面。
如果显示在列表项内部,FF会根据块状元素仅能够在一行内显示的原则,从而错行显示。此时即使定义块元素宽度不为100%,它也会错行显示。
li a{/* 列表项包含的块元素 */
display:block; /* 块状显示 */
width:80%; /* 宽度 */
}
18
2 流动布局的兼容性处理
2.6 列表兼容性处理—列表项错行问题
方法二,定义块元素为行内块状显示,可以清除块状占据一行的问题。
li a{/* 列表项包含的块元素 */
display:inline-block; /* 行内块状显示,清除满行显示 */
}
19
2 流动布局的兼容性处理
2.7 默认高度问题
这个问题存在于IE 6及其以下版本浏览器中。当定义元素的高度小于元素默认行高时,高度将始终保持默认行高。
解决方法:
定义元素内字体大小为0,这样就清除了行高对于高度的影响。但是不能够定义行高为0,因为字体大小默认为16像素,所以还会影响高度设置,而当字体大小为0时,行高也就没有了。
#bar {font-size:0;}
20
2 流动布局的兼容性处理
2.7 默认高度问题
如果就这个问题继续探索。当我们定义元素高度为1像素时,则你又会发现:在IE 6及其以下版本中显示为2像素高度,而IE 7和非IE下显示为1像素。
使用CSS定义的overflow属性来裁切多出的高度,代码如下。
#bar {overflow:hidden;} /* 裁切多出区域 */
21
2 流动布局的兼容性处理
2.8 盒模型高和宽的计算问题
这个问题存在于IE 5.5及其以下版本浏览器中。IE 5.5及其以下版本浏览器认为height和width属性应该包含内容区域的大小、补白区域大小和边框区域大小,通俗说就是元素实际显示的大小。而根据CSS标准,height和width属性值不应该包含补白区域大小和边框区域大小,它仅代表内容区域的大小。
解决此问题方法有多种,但最安全、有效的方法就是使用IE条件语句。把IE条件语句放在原来样式表的底部即可(代码如下),这样就在IE 5.5及其以下版本浏览器中显示与IE 6等其他版本浏览器相同的大小效果。
22
2 流动布局的兼容性处理
2.9 最小高度和宽度问题
这个问题存在于IE 6及其以下版本浏览器中,准确说这个问题不是Bug,而只是暂时功能不支持,或者说不完善,即IE 6及其以下版本浏览器不支持min-height和min-width属性的问题。
所以,解决方法是:专门为IE 6及其以下版本浏览器定义一个高度,具体代码如下:
* html #box {/* IE6及其以下版本浏览器过滤器 */
height:100px; /* 定义高度为100像素 */
}
23
2 流动布局的兼容性处理
2.10 超链接兼容处理—失控的子标签问题
这个问题存在于IE 6及其以下版本浏览器中。当在超链接中嵌套一个子标签时,如果希望利用超链接来动态控制子标签的显示样式,就会出现控制失效问题。
这个问题是IE 6及其以下版本浏览器解析超链接的机制造成的,解决方法是:在超链接的鼠标经过状态时定义一个高度,由于a元素默认为行内元素,定义高度后不会影响其显示,但定义高度之后能够触发它正确解析子标签<span>的显示或隐藏。
24
2 流动布局的兼容性处理
2.11 超链接兼容处理—背景图像代替文本问题
超链接a元素默认为行内显示,由于行内元素不识别盒模型的宽度和高度,所以当为它定义大小时是无效的。如果我们希望使用背景图像来代替超链接文本就会存在很大的问题,实际上设计师经常要面临这样的问题,因为使用背景图像能够设计更具个性的超链接效果。
这种方法利用补白来间接定义元素的大小,并借助font-size属性来间接隐藏字体,从而实现背景图像代替文本的设计效果。
25
3 浮动布局的兼容性处理
3.1 浮动被流动包含问题
这是所有浏览器都存在的问题,即当一个自然流到的元素包含一个浮动的元素时,则包含元素会自动收缩,而不是被浮动元素撑开。既然所有浏览器都有这个问题,那么法不责众,这个问题也就算不上问题了,或者说它仅是一种现象。
解决方法:
可以使用增加清除浮动元素,强制包含框张开以包含浮动的子元素。
26
3 浮动布局的兼容性处理
3.1 浮动被流动包含问题
但是如果在IE 6及其以下版本中不完全支持这种方法。而更有趣的是,如果在IE 7浏览器中改变窗口宽度小于包含的浮动元素所定义的宽度时,你会发现包含框所定义的背景色突然没有了,真是让人莫名其妙。
方法:
#wrap { /* 包含框样式 */
background:#FFCCFF;
zoom:1; /* 使用私有属性缩放100%来触发布局 */
}
或者:
#wrap { /* 包含框样式 */
background:#FFCCFF;
border:solid 1px red; /* 定义边框来触发布局 */
}
27
3 浮动布局的兼容性处理
3.2 包含框不能自适应高度的问题
这个现象本应属于流动布局问题,因为与上一节示例存在问题有点类似,故放在这儿进行讲解。该问题存在于所有浏览器中。当为包含框内的元素定义上下边界时,包含框不能够自适应高度以包含子对象。
存在原因:
如果嵌套元素的边界没有被相互阻隔,则就会出现边界重叠现象。例如,被包含元素的上边界会自动与包含框的上边界重叠,被包含元素的下边界会自动与包含框的下边界重叠。
解决方法:
为包含框定义边框或者补白,从而阻断相互嵌套元素的上下边界接触,防止发生重叠现象,则阻断边界接触。
28
3 浮动布局的兼容性处理
3.3 浮动布局中栏目内容被隐藏的问题
这个问题存在于IE 6及其以下版本浏览器中。有人把这个问题称之为躲猫猫或捉迷藏。之所以这样称呼,是因为在特定条件下栏目内容看起来消失了,只有重新刷新页面时才能够出现,或者用鼠标拖选可以使其显示。
29
3 浮动布局的兼容性处理
3.3 浮动布局中栏目内容被隐藏的问题
出现这个Bug的原因比较特殊,一般需要几个前提条件:
第一,包含框中包含有浮动元素和流动元素,且包含框定义了背景色。
第二,浮动元素后面为一些流动元素,浮动元素的高度应该大于后面流动元素的高度。
第三,在流动元素的下面是一个清除元素(即元素定义清除浮动属性),或者是一个被定义了宽度且宽度足以促使元素只能够显示在浮动元素的底部,而不是环绕在浮动元素的两侧。
当满足上面三个条件,则中间的流动元素(环绕在浮动元素两侧的元素)看起来似乎消失了,原来它们都隐藏到了父元素的背景后面,只有在刷新页面时才重新出现。
3 浮动布局的兼容性处理
3.3 浮动布局中栏目内容被隐藏的问题
方法一,学会在浮动元素后面增加清除元素。所谓清除元素,就是定义了clearr属性的元素,这样就可以避免浮动元素对后面布局的影响。
方法二,在结构嵌套中应遵循最少的层次来满足页面设计需要,使页面结构简单,容易控制与管理,尽可能的减小由于不必要的嵌套引来的Bug。
3 浮动布局的兼容性处理
3.4 同时设置边界和浮动布局的问题
这个问题存在于IE 6及其以下版本浏览器中。出现这个问题需要具备两个前提条件:
第一,元素同时被定义了边界和浮动显示,且浮动方向和定义边界方向在一个方向。
第二,浮动边相邻的是一个流动元素或包含框,而不是浮动元素。
当满足这两个条件之后,所定义的边界会加倍显示。
解决该问题方法比较简单:
3 浮动布局的兼容性处理
3.5 半个像素问题
这个问题存在于所有IE浏览器版本中。我们知道像素值是没有小数值的,但是当在布局中使用百分比设置单位,就会存在计算的像素值出现小数部分。对于小数值问题,不同类型浏览器取舍方法不同:
IE将根据四舍五入的方法进行计算。例如,假设值为10.5像素,则IE在解析时会根据四舍五入的方法,计算为11像素,而对于值为10.4像素,则计算结果为10像素。
FF等标准浏览器对于小数值一般采取忽略不计的方法,多出的值将按元素顺序进行分配。例如,包含框宽度为11像素,平分为3个子元素,则每个子元素平分3像素,多出的2像素按顺序分给第1、2个子元素。如果包含框宽度为10像素,则每个子元素平分3像素,多出的1像素分给第1个子元素。
3 浮动布局的兼容性处理
3.5 半个像素问题
解决方法:
这是一个比较特殊的问题,最佳方法当然是避免此类问题的出现,即不要设置包含框宽度为一个奇数值。不过在布局中很多取值是无法预定的,所以使用下面这个方法是最安全的。即为包含的子元素定义清除右侧浮动。
13-44.html
这样它就能够强迫所有的子元素并列显示。其实clear:right;声明是一个比较神奇的工具,对于IE浏览器来说,不管所包含的子元素宽度有多大,它都能够强迫子元素在同一行内显示。
3 浮动布局的兼容性处理
3.6 3像素问题
这个问题存在于IE 6及其以下版本浏览器中。当浮动元素与流动元素并列显示时,它们之间会存在3像素的间距。
解决方法:
利用IE 6及其以下版本浏览器的过滤器,专门为它们定义样式实现与标准浏览器的兼容。
3 浮动布局的兼容性处理
3.7 多出字符问题
这个问题存在于IE 6版本浏览器中。当多个浮动元素中间夹杂有HTML注释语句时,如果浮动元素宽度为100%,则就会在下面一行多显示一个上一行最后一个字符。
解决方法:可以清除注释语句即可。
4 定位布局的兼容性处理
4.1 定位参照物的问题
这个问题存在于IE 6及其以下版本浏览器中。当定义行内元素为包含块时,且包含块包含的绝对定位元素以百分比为单位进行定位时,就会出现参照物混乱现象。
解决此类问题的方法很简单,直接为span增加zoom属性,该属性能够触发span自动布局,而从促使绝对定位元素以span元素为参照物进行定位。
4 定位布局的兼容性处理
4.2 定位元素的结构与层叠问题
这个问题存在于所有IE版本中。当定位元素位于不同的结构中时,它们之间的层叠顺序就不能够简单使用z-index属性来控制。定位元素的层叠顺序还要受结构关系的影响。
问题原因:
IE浏览器能够根据相同结构层次的定位元素进行比较,如果不在同一个结构层次,则先比较相同层级的父元素,谁的父元素z-index属性值大谁就在上面,而不管其子元素的z-index属性值有多大。
在上面示例中,蓝盒子的层叠顺序为1,而红盒子的包含块层叠顺序为0(默认值),由于蓝盒子与红盒子的包含块属于同一个层级,所以蓝盒子就会覆盖红盒子的包含块。这样即使红盒子的层叠顺序值为多大都将被覆盖在下面。这个规则对于非IE浏览器来说是无效的。
解决方法:为红盒子的包含块定义较大的层叠值。
4 定位布局的兼容性处理
4.3 定位元素丢失问题
这个问题存在于IE 6及其以下版本浏览器中。当在一个包含块内并列浮动几个元素,它们的宽度之和整好等于包含块的宽度,这时如果在包含块内嵌入绝对定位元素,则该定位元素就会丢失。
方法一,通过为每个栏目收缩一个像素边界,从而显示丢失的绝对定位元素。
方法二,受上面方法的启发,我们也可以不定义负边界,而直接为包含块定义多出3像素。这个3像素是根据所包含的栏目块来定的,如果仅包含两个栏目块,则应该是2像素。
4 定位布局的兼容性处理
4.3 定位元素丢失问题
方法三,上面两种方法都是通过加宽或收缩边界的方法,为定位元素腾出一点空间,从而诱发它显示出来。我们也可以为包含的最后一个子栏目使用绝对定位,从而避免浮动元素占满整个包含块的空间。
方法四,我们也可以在浮动元素和绝对定位元素之间增加一个清除浮动元素,从而强迫定位元素与浮动元素位于不同行中,从而显示出来。
PC端多行文本慎用,火狐IE不支持。
不兼容浏览器 | 问题概要 | 问题描述 | 解决方法 |
IE6,IE7 | 3px |
并列一行的元素左侧第一个元素没浮动,第二个元素左浮动,
则两个元素之间会多3像素空隙
| 并在一行的元素如果有一个元素有浮动,则都加浮动 |
IE6,IE7 | 下折行 | 并列一行的元素左侧元素没浮动,右侧元素右浮动,则右侧浮动元素向下折行 | 并在一行的元素如果有一个元素有浮动,则都加浮动 |
IE6 | 双边距 | 块属性标签浮动,并且有横向margin值,横向margin加倍 | 块元素添加display:inline |
IE6,IE7 | li | li无浮动,li内部元素有浮动,li下会多出来3px左右的间隙 | 给li添加vertical-align:top 或给li添加浮动 |
IE6 | 最小高度 | 最小高度不小于19px | 设置 overflow:hidden得到高度为设置的height |
IE6 | 最小高度+li | 当最小高度问题和 li 的间隙问题共存的时候 | 只能给li添加浮动,且添加overflow:hidden |
IE6,IE7 | 图片间隙 | 图片下有间隙 | 给图片添加vertical-align |
IE6 | margin消失 | 当一行子元素占有的宽度之和,和父级的宽度相差超过3px,或者有不满行状态的时候,最后一行子元素的下margin在IE6下就会失效 | 尽量避免该情况 |
IE6 | 文字溢出 | 子元素的宽度和父级的宽度相差小于3px的时候,两个浮动元素中间有注释或者内嵌元素文字莫名其妙多出几个 | 用div把注释或者内嵌元素包起来 |
IE6 | 浮动与绝对定位 | 当浮动元素和绝对定位元素是并列关系的时候,在IE6下绝对定位元素会消失 | 把绝对定位元素套个div,或在添加zoom:1;触发layout |
IE6 | Fiexd | 不支持固定定位 position:fiexd; | 需要配合JS计算滚动尺寸实现兼容 |
IE6 | 溢出 | 父级的 overflow:hidden; 包不住子级的relative; | 给父级也添加relative |
IE6 | 1px | 定位元素的父级宽高都为奇数那么定位元素的 right 和 bottom 都有1像素的偏差。 | 尽量避免改情况 |
IE6,IE7 | 表单高度 | 表单元素select/option 下拉选框 对高度的支持不兼容 | 通常不设置高度 |
IE6,IE7 | textarea | 各个浏览器下的默认滚动条显示不兼容 | 添加 overflow:auto; |
IE6,IE7 | textarea | css3新增 resize 调整尺寸属性; | resize:none; 不能自由拖动改变尺寸, |
IE6 | input背景滚动 | input背景随着内容增多而移动 | 在input外面添加一个div,div上设置背景,或者添加给其父级,input全部透明 |
IE6 | 撑开父级宽度 | 子级宽度如果超过父级宽度,会撑开父级宽度,而其它浏览器不会撑开父级宽度 | 需要精确计算好 |
IE6 | Fiexd | 不支持固定定位 position:fiexd; | 需要配合JS计算滚动尺寸实现兼容 |
IE6 | 溢出 | 父级的 overflow:hidden; 包不住子级的relative; | 给父级也添加relative |
IE6 | 1px | 定位元素的父级宽高都为奇数那么定位元素的 right 和 bottom 都有1像素的偏差。 | 尽量避免改情况 |
IE6,IE7 | 表单高度 | 表单元素select/option 下拉选框 对高度的支持不兼容 | 通常不设置高度 |
IE6,IE7 | textarea | 各个浏览器下的默认滚动条显示不兼容 | 添加 overflow:auto; |
IE6,IE7 | textarea | css3新增 resize 调整尺寸属性; | resize:none; 不能自由拖动改变尺寸, |
IE6 | input背景滚动 | input背景随着内容增多而移动 | 在input外面添加一个div,div上设置背景,或者添加给其父级,input全部透明 |
IE6 | 撑开父级宽度 | 子级宽度如果超过父级宽度,会撑开父级宽度,而其它浏览器不会撑开父级宽度 | 需要精确计算好 |
IE6 | 子集宽度撑满父级 | 父级元素浮动,如果要求子集元素宽度内容撑开,就给里面的子集块元素都加浮动,不然子集元素会撑到父级设置的宽度 | |
IE6 | dotted | 1px dotted 在IE6下不支持 | 切图片背景平铺 |
IE6 | margin消失 | 父级有边框的时候,子元素的margin值消失 | 触发父级的haslayout |
IE6 | margin传递 | 有时候子级的margin值会传递到父级上 | 触发父级的haslayout |
IE6,IE7 | 表单背景 | 如果tr于thead或tbody同时有背景,则thead和tbody的背景会消失 | 尽量避免 |
IE6,IE7 | input border | 输入类型的表单控件加border:none;无效,,依然会有边框。 | 重置input的背景 |
IE6 | PNG半透明 | PNG半透明图片在IE6下不起作用 |
解决方案:采用专属IE6的js插件
DD_belatedPNG_0.0.8a.js
|
PNG半透明图片会有从整个页面左上角掉下划入的情况 | 在其父级添加 相对定位 position:relative; | ||
PNG半透明背景图尽量不要处理鼠标移入的背景图,会出现闪动的情况, | 移入之前都设定PNG半透明背景图,不过位置需要移出标签外,当鼠标移入后,将背景图移回原位。 | ||
IE6 | !important | 在!Important 后边再加一条同样的样式,会破坏掉 !important的作用,会按照默认的优先级顺序来走。 | 尽量避免 |
1. children与childNodes
IE提供的children、childNodes和firefox下的childNodes的行为是有区别的,firefox下childNodes会把换行和空白字符都算作父节点的子节点,而IE的childNodes和children不会。比如:
1
2
3
|
<div id=
"dd"
>
<div>yizhu2000</div>
</div>
|
d为dd的div在IE下用childNodes查看,其子节点数为1,而ff下为三,我们可以从firefox的dom查看器里面看到他的childNodes为["\n ", div, "\n"]。
要在firefox下模拟children的属性我们可以这样做:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
if
(
typeof
(HTMLElement) !=
"undefined"
&& !window.opera) {
HTMLElement.prototype.__defineGetter__(
"children"
,
function
() {
for
(
var
a = [], j = 0, n, i = 0; i <
this
.childNodes.length; i++) {
n =
this
.childNodes[i];
if
(n.nodeType == 1) {
a[j++] = n;
if
(n.name) {
if
(!a[n.name])
a[n.name] = [];
a[n.name][a[n.name].length] = n;
}
if
(n.id)
a[n.id] = n;
}
}
return
a;
});
}
|
2. firefox和ie的事件
window.event只能在IE下使用,而不能用在Firefox下,这是因为Firefox的event只能在事件发生的现场使用。 Firefox必须从源处加入event作参数传递。IE忽略该参数,用window.event来读取该event。
比方说下面这个在ie下获得鼠标位置的方法:
1
2
3
4
5
6
|
<button onclick=
"onClick()"
>获得鼠标点击横坐标</button>
<script type=
"text/javascript"
>
function
onclick(){
alert(event.clientX);
}
</script>
|
需要改成
1
2
3
4
5
6
7
|
<button onclick=
"onClick(event)"
>获得OuterHTML</button>
<script type=
"text/javascript"
>
function
onclick(event){
event = event || window.event;
alert(event.clientX);
}
</script>
|
才能在两种浏览器下使用
3.HTML对象获取问题
FireFox获取方式document.getElementById("idName")
ie使用document.idname或者document.getElementById("idName")
解决办法:统一使用document.getElementById("idName");
4. const问题
在Firefox下,可以使用const关键字或var关键字来定义常量;
IE下,只能使用var关键字来定义常量;
解决方法:统一使用var关键字来定义常量。
5.frame问题
以下面的frame为例:
1
|
<frame src=
"xxx.html"
id=
"frameId"
name=
"frameName"
/>
|
a)访问frame对象
IE:使用window.frameId或者window.frameName来访问这个frame对象,frameId和frameName可以同名;
Firefox:只能使用window.frameName来访问这个frame对象;
另外,在IE和Firefox中都可以使用window.document.getElementById("frameId")来访问这个frame对象;
b) 切换frame内容
在 IE和Firefox中都可以使用
window.document.getElementById("testFrame").src = "xxx.html"或window.frameName.location = "xxx.html"
来切换frame的内容;
如果需要将frame中的参数传回父窗口(注意不是opener,而是parent),可以在frame中使用parent来访问父窗口。例如:
parent.document.form1.filename.value="Aqing";
6. body问题
Firefox的body在body标签没有被浏览器完全读入之前就存在;而IE的body则必须在body标签被浏览器完全读入之后才存在;
7. firefox与IE的父元素(parentElement)的区别
IE:obj.parentElement
firefox:obj.parentNode
解决方法:因为firefox与IE都支持DOM,因此全部使用obj.parentNode
8.innerText的问题
innerText在IE中能正常工作,但是innerText在FireFox中却不行,需用textContent;
解决方法:
1
2
3
4
5
|
if
(navigator.appName.indexOf(
"Explorer"
) > -1) {
document.getElementById(
'element'
).innerText =
"my text"
;
}
else
{
document.getElementById(
'element'
).textContent =
"my text"
;
}
|
9.AJAX获取XMLHTTP的区别
1
2
3
4
5
6
|
var
xmlhttp;
if
(window.XMLHttpRequest) {
xmlhttp =
new
XMLHttpRequest();
} elseif (window.ActiveXObject) {
// IE的获取方式
xmlhttp =
new
ActiveXObject(
"Microsoft.XMLHTTP"
);
}
|
注意:在IE中,xmlhttp.send(content)方法的content可以为空,而firefox则不能为null,应该用send(""),否则会出现411错误。
原文链接:http://caibaojian.com/js-ie-different-from-firefox.html
10.window.event
表示当前的时间对象,IE有这个对象,FF没有,FF通过给事件处理函数传递事件对象·
2.获取事件源
IE用srcElement获取事件源,而FF用target获取事件源
以上两个兼容通常会这么写:
var evt = e||event; var el = evt.srcTarget || evt.srcElement;
3.添加、去除事件
4.获取标签的自定义属性
IE:div1.value或div1['value']
FF:可用div1.getAttribute("value")
5.document.getElemntByName()和document.all[name]
IE不可以,
FF可以
6.input.type的属性
7.IE支持innerText、outerHTML
FF:支持textContent
8.窗口的位置
IE、chrome、safari:支持使用window.screenLeft和window.screenTop
IE8以上、chrome、safari、firefox:支持使用window.screenX和window.screenY
兼容代码可以使用下面这段代码:
var leftX = typeof window.screenLeft == 'number' ? window.screenLeft : window.screenX; ver topY = typeof window.screenTop == 'number' ? window.screenTop : window.screenY;
9.窗口的大小
firefox、chrome、IE9和safari:window.innerWidth和window.innerHeight
IE系列:document.body.clientWidth和document.body.clientHeight
不是IE6:document.documentElement.clientWidth和document.documentElement.clientHeight
兼容代码可以这样子写
//code from http://caibaojian.com/js-ie-different-from-firefox.html var width = window.innerWidth; var height = window.innerHeight; if(typeof width != 'number'){ if(document.compatMode == 'CSS1Compat'){ width = document.documentElement.clientWidth; height = document.docuementElement.clientHeight; }else{ width = document.body.clientWidth; height = document.body.clientHeight; }
1.关于获取行外样式 currentStyle 和 getComputedStyle 出现的兼容性问题
我们都知道js通过style不可以获取行外样式,当我们需要获取行外样式时:
我们一般通过这两个方法获取行外样式:
IE下: currentStyle
Chrome,FF下: getComputedStyle(oDiv,false)
兼容两个浏览器的写法:
if(oDiv.currentStyle){
alert(oDiv.currentStyle.width);
}else{
alert(getComputedStyle(oDiv,false).width);
}
*注:在解决很多兼容性写法时,都是用if..else..
封装一个获取行外样式的函数:(兼容所有浏览器,包括低版本IE6,7)
funtion getStyle(obj,name){
if(obj.currentStyle){
//IE
return obj.currentStyle[name];
}else{
//Chrom,FF
return getComputedStyle(obj,false)[name];
}
}
调用:getStyle(oDiv,'width');
2.关于用“索引”获取字符串每一项出现的兼容性问题:
对于字符串也有类似于 数组 这样的通过 下标索引 获取每一项的值,
var str="abcde";
aletr(str[1]);
但是低版本的浏览器IE6,7不兼容
兼容方法:str.charAt(i) //全部浏览器都兼容
var str="abcde";
for(var i=0;i<str.length;i++){
alert(str.charAt(i)); //放回字符串中的每一项
}
3.关于DOM中 childNodes 获取子节点出现的兼容性问题
childNodes:获取子节点,
--IE6-8:获取的是元素节点,正常
--高版本浏览器:但是会包含文本节点和元素节点(不正常)
解决方法: 使用nodeType:节点的类型,并作出判断
--nodeType=3-->文本节点
--nodeTyPE=1-->元素节点
例: 获取ul里所有的子节点,让所有的子节点背景色变成红色
获取元素子节点兼容的方法:
var oUl=document.getElementById('ul');
for(var i=0;i<oUl.childNodes.length;i++){
if(oUl.childNodes[i].nodeType==1){
oUl.childNodes[i].style.background='red';
}
}
注:上面childNodes为我们带来的困扰完全可以有children属性来代替。
children属性:只获取元素节点,不获取文本节点,兼容所有的浏览器,
比上面的好用所以我们一般获取子节点时,最好用children属性。
var oUl=document.getElementById('ul');
oUl.children.style.background="red";
4.关于使用 firstChild,lastChild 等,获取第一个/最后一个元素节点时产生的问题
--IE6-8下: firstChild,lastChild,nextSibling,previousSibling,获取第一个元素节点
(高版本浏览器IE9+,FF,Chrome不兼容,其获取的空白文本节点)
--高版本浏览器下: firstElementChild,lastElementChild,nextElementSibling,previousElementSibling
(低版本浏览器IE6-8不兼容)
--兼容写法: 找到ul的第一个元素节点,并将其背景色变成红色
var oUl=document.getElementById('ul');
if(oUl.firstElementChild){
//高版本浏览器
oUl.firstElementChild.style.background='red';
}else{
//IE6-8
oUl.firstChild.style.background='red';
}
5.关于使用 event对象,出现的兼容性问题
如: 获取鼠标位置
IE/Chrom: event.clientX;event.clientY
FF/IE9以上/Chrom: 传参ev--> ev.clientX;ev.clientY
获取event对象兼容性写法: var oEvent==ev||event;
document.oncilck=function(ev){
var oEvent==ev||event;
if(oEvent){
alert(oEvent.clientX);
}
}
6.关于为一个元素绑定两个相同事件:attachEvent/attachEventLister 出现的兼容问题
事件绑定:(不兼容需要两个结合做兼容if..else..)
IE8以下用: attachEvent('事件名',fn);
FF,Chrome,IE9-10用: attachEventLister('事件名',fn,false);
多事件绑定封装成一个兼容函数:
function myAddEvent(obj,ev,fn){
if(obj.attachEvent){
//IE8以下
obj.attachEvent('on'+ev,fn);
}else{
//FF,Chrome,IE9-10
obj.attachEventLister(ev,fn,false);
}
}
myAddEvent(oBtn,'click',function(){
alert(a);
});
myAddEvent(oBtn,'click',function(){
alert(b);
});
7.关于获取滚动条距离而出现的问题
当我们获取滚动条滚动距离时:
IE,Chrome: document.body.scrollTop
FF: document.documentElement.scrollTop
兼容处理:var scrollTop=document.documentElement.scrollTop||document.body.scrollTop
一、document.formName.item(”itemName”) 问题
问题说明:IE下,可以使用 document.formName.item(”itemName”) 或 document.formName.elements ["elementName"];Firefox 下,只能使用document.formName.elements["elementName"]。
解决方法:统一使用document.formName.elements["elementName"]。
二、集合类对象问题
问题说明:IE下,可以使用 () 或 [] 获取集合类对象;Firefox下,只能使用 [ ]获取集合类对象。
解决方法:统一使用 [] 获取集合类对象。
三、自定义属性问题
问题说明:IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用 getAttribute() 获取自定义属性;Firefox下,只能使用 getAttribute() 获取自定义属性。
解决方法:统一通过 getAttribute() 获取自定义属性。
四、eval(”idName”)问题
问题说明:IE下,可以使用 eval(”idName”) 或 getElementById(”idName”) 来取得 id 为 idName 的HTML对象;Firefox下,只能使用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。
解决方法:统一用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。
五、变量名与某HTML对象ID相同的问题
问题说明:IE下,HTML对象的ID可以作为 document 的下属对象变量名直接使用,Firefox下则不能;Firefox下,可以使用与HTML对象ID相同的变量名,IE下则不能。
解决方法:使用 document.getElementById(”idName”) 代替 document.idName。最好不要取HTML对象ID相同的变量名,以减少错误;在声明变量时,一律加上var关键字,以避免歧义。
六、const问题
问题说明:Firefox下,可以使用const关键字或var关键字来定义常量;IE下,只能使用var关键字来定义常量。
解决方法:统一使用var关键字来定义常量。
七、input.type属性问题
问题说明:IE下 input.type 属性为只读;但是Firefox下 input.type 属性为读写。
解决办法:不修改 input.type 属性。如果必须要修改,可以先隐藏原来的input,然后在同样的位置再插入一个新的input元素。
八、window.event问题
问题说明:window.event 只能在IE下运行,而不能在Firefox下运行,这是因为Firefox的event只能在事件发生的现场使用。
解决方法:在事件发生的函数上加上event参数,在函数体内(假设形参为evt)使用 var myEvent = evt?evt:(window.event?window.event:null)
示例:
1
2
3
4
5
6
|
<input type=
"button"
onclick=
"doSomething(event)"
/>
<script language=
"javascript"
>
function
doSomething(evt) {
var
myEvent = evt?evt:(window.event?window.event:
null
)
...
}
|
九、event.x与event.y问题
问题说明:IE下,even对象有x、y属性,但是没有pageX、pageY属性;Firefox下,even对象有pageX、pageY属性,但是没有x、y属性。
解决方法:var myX = event.x ? event.x : event.pageX; var myY = event.y ? event.y:event.pageY;
如果考虑第8条问题,就改用myEvent代替event即可。
十、event.srcElement问题
问题说明:IE下,even对象有srcElement属性,但是没有target属性;Firefox下,even对象有target属性,但是没有srcElement属性。
解决方法:使用srcObj = event.srcElement ? event.srcElement : event.target;
如果考虑第8条问题,就改用myEvent代替event即可。
十一、window.location.href问题
问题说明:IE或者Firefox2.0.x下,可以使用window.location或window.location.href;Firefox1.5.x下,只能使用window.location。
解决方法:使用 window.location 来代替 window.location.href。当然也可以考虑使用 location.replace()方法。
十二、模态和非模态窗口问题
问题说明:IE下,可以通过showModalDialog和showModelessDialog打开模态和非模态窗口;Firefox下则不能。
解决方法:直接使用 window.open(pageURL,name,parameters) 方式打开新窗口。
如果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用window.opener来访问父窗口。如果需要父窗口控制子窗口的话,使用 var subWindow = window.open(pageURL,name,parameters); 来获得新开的窗口对象。
十三、frame和iframe问题
以下面的frame为例:
(1)访问frame对象
IE:使用window.frameId或者window.frameName来访问这个frame对象;
Firefox:使用window.frameName来访问这个frame对象;
解决方法:统一使用 window.document.getElementById(”frameId”) 来访问这个frame对象;
(2)切换frame内容
在IE和Firefox中都可以使用 window.document.getElementById(”frameId”).src = “webjx.com.html”或 window.frameName.location = “webjx.com.html”来切换frame的内容;
如果需要将frame中的参数传回父窗口,可以在frame中使用parent关键字来访问父窗口。
十四、body载入问题
问题说明:Firefox的body对象在body标签没有被浏览器完全读入之前就存在;而IE的body对象则必须在body标签被浏览器完全读入之后才存在。
[注] 这个问题尚未实际验证,待验证后再来修改。
[注] 经验证,IE6、Opera9以及FireFox2中不存在上述问题,单纯的JS脚本可以访问在脚本之前已经载入的所有对象和元素,即使这个元素还没有载入完成。
十五、事件委托方法
问题说明:IE下,使用 document.body.onload = inject; 其中function inject()在这之前已被实现;在Firefox下,使用 document.body.onload = inject();
解决方法:统一使用 document.body.οnlοad=new Function('inject()'); 或者 document.body.onload = function(){/* 这里是代码 */}
[注意] Function和function的区别
十六、访问的父元素的区别
问题说明:在IE下,使用 obj.parentElement 或 obj.parentNode 访问obj的父结点;在firefox下,使用 obj.parentNode 访问obj的父结点。
解决方法:因为firefox与IE都支持DOM,因此统一使用obj.parentNode 来访问obj的父结点。
十七、innerText的问题.
问题说明:innerText在IE中能正常工作,但是innerText在FireFox中却不行。
解决方法:在非IE浏览器中使用textContent代替innerText。
示例:
1
2
3
4
5
|
if
(navigator.appName.indexOf(
"Explorer"
) >-1){
document.getElementById(
'element'
).innerText =
"my text"
;
}
else
{
document.getElementById(
'element'
).textContent =
";my text"
;
}
|
[注] innerHTML 同时被ie、firefox等浏览器支持,其他的,如outerHTML等只被ie支持,最好不用。
十八、Table操作问题
问题说明:ie、firefox以及其它浏览器对于 table 标签的操作都各不相同,在ie中不允许对table和tr的innerHTML赋值,使用js增加一个tr时,使用appendChild方法也不管用。document.appendChild在往表里插入行时FIREFOX支持,IE不支持
解决办法:把行插入到TBODY中,不要直接插入到表
解决方法:
1
2
3
4
5
6
|
//向table追加一个空行:
var
row = otable.insertRow(-1);
var
cell = document.createElement(
"td"
);
cell.innerHTML =
""
;
cell.className =
"XXXX"
;
row.appendChild(cell);
|
[注] 建议使用JS框架集来操作table,如JQuery。
• 获取table的行数和列数
在IE中,获取行列数可以使用下面的代码:
1
2
3
4
5
|
var
detailT= grid.gettable(
"11"
);
//获取行的长度
var
r=detailT.rows.length;
//获取列的长度
var
l=detailT.cells.length;
|
而在火狐或谷歌中获取列的长度就是无效的。
解决方案:
1
2
3
4
5
|
var
detailT= grid.gettable(
"11"
);
//获取行的长度
var
r=detailT.rows.length;
//获取列的长度
var
l=detailT.rows[0].cells.length;
|
十九、对象宽高赋值问题
问题说明:FireFox中类似 obj.style.height = imgObj.height 的语句无效。
解决方法:统一使用 obj.style.height = imgObj.height + ‘px';
二十、setAttribute('style','color:red;')
FIREFOX支持(除了IE,现在所有浏览器都支持),IE不支持
解决办法:不用setAttribute('style','color:red')
而用object.style.cssText = ‘color:red;'(这写法也有例外)
最好的办法是上面种方法都用上,万无一失
二一、类名设置
setAttribute('class','styleClass')
FIREFOX支持,IE不支持(指定属性名为class,IE不会设置元素的class属性,相反只使用setAttribute时IE自动识CLASSNAME属性)
解决办法:
1
2
3
4
5
|
setAttribute(
'class'
,
'styleClass'
)
setAttribute(
'className'
,
'styleClass'
)
或者直接 object.className=
'styleClass'
;
|
IE和FF都支持object.className。
二二、用setAttribute设置事件
var obj = document.getElementById('objId');
obj.setAttribute('onclick','funcitonname();');
FIREFOX支持,IE不支持
解决办法:
IE中必须用点记法来引用所需的事件处理程序,并且要用赋予匿名函数
如下:
1
2
|
var
obj = document.getElementById(
'objId'
);
obj.onclick=
function
(){fucntionname();};
|
这种方法所有浏览器都支持
二三、建立单选钮
IE以外的浏览器
1
2
3
4
|
var
rdo = document.createElement(
'input'
);
rdo.setAttribute(
'type'
,
'radio'
);
rdo.setAttribute(
'name'
,
'radiobtn'
);
rdo.setAttribute(
'value'
,
'checked'
);
|
IE:
1
|
var
rdo =document.createElement(”<input name=”radiobtn” type=”radio” value=”checked” />”);
|
解决办法:
这一点区别和前面的都不一样。这次完全不同,所以找不到共同的办法来解决,那么只有IF-ELSE了
万幸的是,IE可以识别出document的uniqueID属性,别的浏览器都不可以识别出这一属性。问题解决。
常遇到的关于浏览器的宽高问题:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//以下均可console.log()实验
var
winW=document.body.clientWidth||document.docuemntElement.clientWidth;
//网页可见区域宽
var
winH=document.body.clientHeight||document.docuemntElement.clientHeight;
//网页可见区域宽
//以上为不包括边框的宽高,如果是offsetWidth或者offsetHeight的话包括边框
var
winWW=document.body.scrollWidth||document.docuemntElement.scrollWidth;
//整个网页的宽
var
winHH=document.body.scrollHeight||document.docuemntElement.scrollHeight;
//整个网页的高
var
scrollHeight=document.body.scrollTop||document.docuemntElement.scrollTop;
//网页被卷去的高
var
scrollLeft=document.body.scrollLeft||document.docuemntElement.scrollLeft;
//网页左卷的距离
var
screenH=window.screen.height;
//屏幕分辨率的高
var
screenW=window.screen.width;
//屏幕分辨率的宽
var
screenX=window.screenLeft;
//浏览器窗口相对于屏幕的x坐标(除了FireFox)
var
screenXX=window.screenX;
//FireFox相对于屏幕的X坐标
var
screenY=window.screenTop;
//浏览器窗口相对于屏幕的y坐标(除了FireFox)
var
screenYY=window.screenY;
//FireFox相对于屏幕的y坐标
|
event事件问题:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//event事件问题
document.onclick=
function
(ev){
//谷歌火狐的写法,IE9以上支持,往下不支持;
var
e=ev;
console.log(e);
}
document.onclick=
function
(){
//谷歌和IE支持,火狐不支持;
var
e=event;
console.log(e);
}
document.onclick=
function
(ev){
//兼容写法;
var
e=ev||window.event;
var
mouseX=e.clientX;
//鼠标X轴的坐标
var
mouseY=e.clientY;
//鼠标Y轴的坐标
}
|
DOM节点相关的问题,我直接封装了函数,以便随时可以拿来使用:
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
|
//DOM节点相关,主要兼容IE 6 7 8
function
nextnode(obj){
//获取下一个兄弟节点
if
(obj.nextElementSibling) {
return
obj.nextElementSibling;
}
else
{
return
obj.nextSibling;
};
}
function
prenode(obj){
//获取上一个兄弟节点
if
(obj.previousElementSibling) {
return
obj.previousElementSibling;
}
else
{
return
obj.previousSibling;
};
}
function
firstnode(obj){
//获取第一个子节点
if
(obj.firstElementChild) {
return
obj.firstElementChild;
//非IE678支持
}
else
{
return
obj.firstChild;
//IE678支持
};
}
function
lastnode(obj){
//获取最后一个子节点
if
(obj.lastElementChild) {
return
obj.lastElementChild;
//非IE678支持
}
else
{
return
obj.lastChild;
//IE678支持
};
}
|
document.getElementsByClassName问题:
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
|
//通过类名获取元素
document.getElementsByClassName(
''
);
//IE 6 7 8不支持;
//这里可以定义一个函数来解决兼容问题,当然别在这给我提jQuery...
//第一个为全局获取类名,第二个为局部获取类名
function
byClass1(oClass){
//全局获取,oClass为你想要查找的类名,没有“.”
var
tags=document.all?document.all:document.getElementsByTagName(
'*'
);
var
arr=[];
for
(
var
i = 0; i < tags.length; i++) {
var
reg=
new
RegExp(
'\\b'
+oClass+
'\\b'
,
'g'
);
if
(reg.test(tags[i].className)) {
arr.push(tags[i]);
};
};
return
arr;
//注意返回的也是数组,包含你传入的class所有元素;
}
function
byClass2(parentID,oClass){
//局部获取类名,parentID为你传入的父级ID
var
parent=document.getElementById(parentID);
var
tags=parent.all?parent.all:parent.getElementsByTagName(
'*'
);
var
arr=[];
for
(
var
i = 0; i < tags.length; i++) {
var
reg=
new
RegExp(
'\\b'
+oClass+
'\\b'
,
'g'
);
if
(reg.test(tags[i].className)) {
arr.push(tags[i]);
};
};
return
arr;
//注意返回的也是数组,包含你传入的class所有元素;
}
|
获取元素的非行间样式值:
1
2
3
4
5
6
7
8
|
//获取元素的非行间样式值
function
getStyle(object,oCss) {
if
(object.currentStyle) {
return
object.currentStyle[oCss];
//IE
}
else
{
return
getComputedStyle(object,
null
)[oCss];
//除了IE
}
}
|
设置监听事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//设置监听事件
function
addEvent(obj,type,fn){
//添加事件监听,三个参数分别为 对象、事件类型、事件处理函数,默认为false
if
(obj.addEventListener) {
obj.addEventListener(type,fn,
false
);
//非IE
}
else
{
obj.attachEvent(
'on'
+type,fn);
//ie,这里已经加上on,传参的时候注意不要重复加了
};
}
function
removeEvent(obj,type,fn){
//删除事件监听
if
(obj.removeEventListener) {
obj.removeEventListener(type,fn,
false
);
//非IE
}
else
{
obj.detachEvent(
'on'
+type,fn);
//ie,这里已经加上on,传参的时候注意不要重复加了
};
}
|
元素到浏览器边缘的距离:
1
2
3
4
5
6
7
8
9
10
|
//在这里加个元素到浏览器边缘的距离,很实用
function
offsetTL(obj){
//获取元素内容距离浏览器边框的距离(含边框)
var
ofL=0,ofT=0;
while
(obj){
ofL+=obj.offsetLeft+obj.clientLeft;
ofT+=obj.offsetTop+obj.clientTop;
obj=obj.offsetParent;
}
return
{left:ofL,top:ofT};
}
|
阻止事件传播:
1
2
3
4
5
6
7
8
9
|
//js阻止事件传播,这里使用click事件为例
document.onclick=
function
(e){
var
e=e||window.event;
if
(e.stopPropagation) {
e.stopPropagation();
//W3C标准
}
else
{
e.cancelBubble=
true
;
//IE....
}
}
|
阻止默认事件:
1
2
3
4
5
6
7
8
9
|
//js阻止默认事件
document.onclick=
function
(e){
var
e=e||window.event;
if
(e.preventDefault) {
e.preventDefault();
//W3C标准
}
else
{
e.returnValue=
'false'
;
//IE..
}
}
|
关于EVENT事件中的target:
1
2
3
4
5
6
7
|
//关于event事件中的target
document.onmouseover=
function
(e){
var
e=e||window.event;
var
Target=e.target||e.srcElement;
//获取target的兼容写法,后面的为IE
var
from=e.relatedTarget||e.formElement;
//鼠标来的地方,同样后面的为IE...
var
to=e.relatedTarget||e.toElement;
//鼠标去的地方
}
|
鼠标滚轮滚动事件:
1
2
3
4
5
6
7
8
9
|
//鼠标滚轮事件
//火狐中的滚轮事件
document.addEventListener(
"DOMMouseScroll"
,
function
(event){
alert(event.detail);
//若前滚的话为 -3,后滚的话为 3
},
false
)
//非火狐中的滚轮事件
document.onmousewheel=
function
(event){
alert(event.detail);
//前滚:120,后滚:-120
}
|
节点加载:
1
2
3
|
//火狐下特有的节点加载事件,就是节点加载完才执行,和onload不同
//感觉用到的不多,直接把js代码放在页面结构后面一样能实现。。
document.addEventListener(
'DOMContentLoaded'
,
function
( ){},
false
);
//DOM加载完成。
|