多浏览器支持的积累

 

一、一些基本知识:

  1. 如何区分不同浏览器;
  • 在CSS中区分不同浏览器的方法

  a)  Hack方式:采用了CSS覆盖原理,CSS hack书写顺序一般为FF IE6 IE7 ,

    *html-----IE6,7,8

    *+html----IE7  需要特殊的头部(过渡模式)

         !important-----IE7,FF,IE8

       例如:

       .inner { width: 120px; } /* FF */

  * html .inner { width: 80px; } /* IE6 */

  *+html .inner { width: 60px; } /* IE7 */

 

  • 在JS脚本中区分不同浏览器的方法:

  window.navigator.userAgent,

  是否含有msie、Gecko、Safari等

  例如:

  window.navigator.userAgent.toLowerCase().indexOf("msie")>=1

 

  1. 关于HTML的DOCTYPE;
  • 严格模式:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

  必须与层叠样式表(CSS)配合使用,不能使用任何表现层的标识和属性,例如<br>。表现层的标识、属性"是指那些纯粹用来控制表现的tag,例如用于排版的表格、背景颜色标识等,推荐用这种模式的头解决多浏览器的问题。

  • 过渡模式:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">

     加入了W3C 所期望移入样式表的呈现属性和元素。

  • 基于框架模式:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

  一般用于框架frameset结构的文档中

 

  1. 不同的盒模型;

  IE6.0 采用的是非标准盒模型, IE6.0 在解释双盒嵌套 中,子Div 宽度被

  设置为100% 时其真实宽度为父Div 宽度– 父Div 边线宽度- 父Div 内补丁宽度。父Div 真实宽度为设置宽度。

  Firefox 采用标准盒模型。现在的IE7.0\Opera\Safari 都可以非常好的遵循

  标准盒模型。标准盒模型在解释双盒嵌套中,子Div 宽度被设置为100% 时其真实宽度为父Div 的设置宽度。父Div 真实宽度为设置宽度+ 父Div 内补丁宽度+ 父Div 边线宽度。也就是说父Div 的盒被撑大了。并且在标准盒模型中通常height 属性是无效的。

    所以,FF指定padding会给div增加高度和宽度,而IE不会。

示例如下:

<style type="text/css">
 .outer{
       width:100px;
       height:100px;
       padding:10px;
       background:blue;
 }
 .inner{
       width:100%;
       height:100%;
       background:red;
 }
 .Reference{
       width:100px;
       height:100px;
       background:green;
 }
</style>
<body>
<div class="outer">
    <div class="inner">ssss</div>
</div>
   <div class="Reference">aaa<div>
</body>      
        在ie6下的展示效果为:
        

             


 
        在firefox下的效果如下:
        

             


        但这里也是需要注意html的头部DOCTYPE的影响.

 

  1. 脚本中有些不是W3C标准的方法需要注意,最好不要使用;

可以多查看手册,看到有如下的说明的方法就需要注意了,

There is no public standard that applies to this method

获取元素对象尽量用标准方法,不要使用document.all 等这些只有IE下才能识别的方法;获取一些元素的非自有属性,应该通过getAttribute方法,而不要通过对象.属性的方法。

 

  1. 区分内联对象和块对象,以及float和position的灵活使用;

 

二、常见问题及解决办法:

  1. TABLE布局的问题;
  • 当内容超长,table的列宽度固定不了的问题;

需要给table指定table-layout:fixed

  • 滚动条的问题

比如需要对td内的内容出滚动条,一般的处理方式是在里面套2个div,让里面的那个div出滚动条。

 

  1. SPAN元素指定宽度无效的问题;

Span元素的宽度在非strict模式下,用ie6看是有效的,但其他浏览器无效,

因为span元素是内联对象,指定宽度无效,要想宽度有效,可以指定它的display:inline-block,目的是将对象呈递为内联对象,但是对象的内容作为块对象呈递。

 

  1. 使用 window.event 无法在 FF 上运行,FF 的 event 只能在事件发生的现场使用,可以这样变通:

原代码(可在IE中运行):

 

新代码(可在IE和MF中运行):

                           

 此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。

以下是我采用的一种处理方式:(在tr上点击事件)

 

  1. FF下任意的BUTTON的onclick都会触发form的submit,所以要return false;本质原因是IE下的button默认的type是button,而在FF下默认的type是submit,所以也可以通过在FF下指定button的type=‘button’;

 

  1. FF不支持fireEvent,用click(),但FF默认不支持非input元素的click()方法。就是说在FF中,div,image...等元素的click()方法是无效的;

 

 

  1. 通过JavaScript Mozilla __defineGetter__ ,__defineSetter__ 去扩展一些我们需要的方法;

Getter是一种获取一个属性的值的方法,Setter是一种设置一个属性的值的方法。

可以为任何预定义的核心对象或用户自定义对象定义getter和setter方法,从而为现有的对象添加新的属性。 这两个函数要求第一个参数是getter或setter的名称,以string给出,第二个参数是作为getter或setter的函数。

例如:

 

 

  1. 多块布局的情况下,如何使跨块的显示是漂在上面bubble,如果只是对当前要漂的这个容器指定z-index是无效的,对于跨块的内容,需要在同一级上面指定z-index,因为z-index是相对于父的。
  2. 对于父容器是div,里面的块(如float的table)需要分行显示,对父容器指定宽度是不太好的方式,只要对里面的子指定为块对象就可以,然后通过指定父容器的背景色和子的背景色一致,就能达到视觉上宽度是一致的效果。
  3. 关于getAttribute()和setAttribute()方法,从DHTML文档中的说明来看,setAttribute的值可以是字符串、数字、布尔型,getAttribute()方法返回的值也可以是字符串、数字、布尔型;下面是说明中的片段:

setAttribute的参数:

vValue  Required. Variant that specifies the string, number, or Boolean to assign to the attribute.

 

getAttribute的返回值:

Variant that returns a String, number, or Boolean value as defined by the attribute. If the attribute is not present, this method returns null.

本以为setAttribute的时候设的是布尔型,然后getAttribute的时候返回的也是布尔型,确实,在ie6下得到的是布尔型,但在ie8和firefox下得到的却是字符串,而且只会得到字符串,这一点需要引起注意,具体的还没有找到官方的文档说明。

 

  1. 循环中的带有“g”标记的正则表达式问题,下面看个例子:

有时候我们可能要对一些input中输入的值做校验,会有类似的逻辑,现模拟如下:

var arr = [2,3];
      for (var i = 0; i < arr.length; i++){
            //var patt = new RegExp(/\d+/g);
            var patt = /\d+/g;
            //patt.lastIndex=0;
            alert(patt.test(arr[i]));
      }

 

这段代码在IE6下,输出的结果是:true  true

而在firefox下,输出的结果是:true  false

原因是lastIndex在第二匹配的时候已经变成了1,大家可以自己测试一下啊,详细解释可参看w3cSchool里面对lastIndex的描述。

所以;解决办法有2种,见上面注释的代码,一种是每次都new RegExp,另一种方法是手动的把lastIndex置为0;

下面是w3cSchool里面对lastIndex的描述:

说明

该属性存放一个整数,它声明的是上一次匹配文本之后的第一个字符的位置。

上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。

该属性是可读可写的。只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动把 lastIndex 属性重置为 0。

提示和注释

重要事项:不具有标志 g 和不表示全局模式的 RegExp 对象不能使用 lastIndex 属性。

提示:如果在成功地匹配了某个字符串之后就开始检索另一个新的字符串,需要手动地把这个属性设置为 0

 

 

 

posted on 2013-05-15 21:58  golden_wind  阅读(240)  评论(0编辑  收藏  举报