IE与firefox事件处理

  1. [1].在IE中,事件对象是作为一个全局变量来保存和维护的.所有的浏览器事件,不管是用户触发的,还是其他事件,都会更新window.event对象.所以在代码中,只要轻松调用window.event就可以轻松获取事件对象, 再event.srcElement就可以取得触发事件的元素进行进一步处理.
    [2].在FireFox中,事件对象却不是全局对象,一般情况下,是现场发生,现场使用,FireFox把事件对象自动传给事件处理程序.

    <input type="button" id="btn1" value="你"/>
    <input type="button" id="btn2" value="我"/>
    <input type="button" id="btn3" value="他"/>
    <script>
    var $=function(id) {
      if(!document.getElementById) return null;
      else return document.getElementById(id);
    }
    window.οnlοad=function() {
      $('btn1').οnclick=fun1;
      $('btn2').οnclick=fun2;
      $('btn3').οnclick=fun3;
    }
    function fun1(){
      ;//IE中, window.event使全局对象
                          //IE下,显示 "[object]" , FF下显示 "undefined"
      ;//FF中, 第一个参数自动从为 事件对象
                          //IE下,显示 "undefined", FF下显示 "[object]"
    }
    function fun2(e) {
      ; //IE下,显示 "[object]",FF下显示 "undefined"
      //注意,我从来没有给 fun2传过参数哦。
      //现在 FF自动传参数给 fun2, 传的参数e就是事件对象了
      ; // IE下,显示"undefined", FF下显示"[object]"
    }
    function fun3(){ //同时兼容IE和FF的写法,取事件对象
        ; // IE 和 FF下,都显示 "[object]"
        var evt=arguments[0] || window.event;
        var element=evt.srcElement || evt.target; //在IE和FF下取得btn3对象                   ;   // btn3
     }
    </script>

    到这里,我们似乎对IE和FF的事件处理方式都已经理解了,并找到了解决的办法。但是事情还没有结束。看代码

    <button id="btn" οnclick="fun">按钮</button>
    <script>
    function fun(){  
        ;
    }
    </script>

    很不幸,fun给我们的结果是undefined, 而不是期望的object!!!!!!!!

    原因在于事件绑定的方式:οnclick="fun()"就是直接执行了, fun() 函数,没有任何参数的,这种情况下firefox没有机会传递任何参数给fun,而btn.οnclick=fun这种情况, 因为不是直接执行函数,firefox才有机会传参数给fun.

    解决方法:
    方法一:比较笨的方法,既然 firefox没有机会传参数,那么自己勤快点,自己传 !!

    <button id="btn" οnclick="fun(event)">按钮</button>
    <script>
    function fun(){  
       ;      
       var evt=arguments[0] || window.event;
       var element=evt.srcElement || evt.target;
       ;
    }
    </script>

    方法二: 自动查找

    <button id="btn4" οnclick="fun4()">按钮4</button>
     <script>
    function fun4(){  
         var evt=getEvent();
         var element=evt.srcElement || evt.target;
         ;       
     }
     
     function getEvent(){     //同时兼容ie和ff的写法
             if(document.all)    return window.event;       
             func=getEvent.caller;           
             while(func!=null){   
                 var arg0=func.arguments[0];
                 if(arg0){
                     if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
                         || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){   
                         return arg0;
                     }
                 }
                 func=func.caller;
             }
             return null;
     }
    </script>

    方法三

    function SearchEvent()
    {
        //IE
        if(document.all)
            return window.event;
           
        func=SearchEvent.caller;
        while(func!=null)
        {
            var arg0=func.arguments[0];
            if(arg0)
            {
                if(arg0.constructor==Event)
                    return arg0;
            }
            func=func.caller;
        }
        return null;
    }
  2. 在ie中,事件对象是作为一个全局变量来保存和维护的。 所有的浏览器事件,不管是用户触发
    的,还是其他事件, 都会更新window.event 对象。 所以在代码中,只要轻松调用 window.event
    就可以轻松获取 事件对象, 再 event.srcElement 就可以取得触发事件的元素进行进一步处理
  3. 在ff中, 事件对象却不是全局对象,一般情况下,是现场发生,现场使用,ff把事件对象自动传
    递给对应的事件处理函数。        在代码中,函数的第一个参数就是ff下的事件对象了。


     以上是我个人对两个浏览器下的事件处理方法的粗浅理解,可能说得不是很明白,我写些代码来
     详细说明一下
   function SearchEvent() 
if(document.all)  
 
return window.event;        func=SearchEvent.caller;   
while(func!=null)    
{  var arg0=func.arguments[0]; 
 
if(arg0.constructor==Event||arg0.constructor==MouseEvent)
 

 
return arg0;
  }
   
 func
=func.caller;  }
  
return null;}
 
  

1 <button id="btn1">按钮1 button>
2 <button id="btn2">按钮2button>
3 <button id="btn3">按钮3button>
4
5 <script>
6
7 window.onload=function(){
8      document.getElementById("btn1").onclick=
foo1
9      document.getElementById("btn2").onclick=
foo2
10      document.getElementById("btn3").onclick=
foo3
11
}
12

13 function foo1(){
14      //ie中, window.event使全局对象

15      alert(window.event)   // ie下,显示 "[object]" ,   ff下显示 "undefined"
16     
17     //ff中,   第一个参数自动从为 事件对象

18      alert(arguments[0])   // ie下,显示   "undefined",   ff下显示 "[object]"
19 }
20

21 function foo2(e){
22      alert(window.event)  // ie下,显示 "[object]" ,   ff下显示 "undefined"

23     
24     //注意,我从来没有给   foo2传过参数哦。   现在 ff自动传参数给 foo2, 传的参数e 就是事件对象了

25      alert(e)               // ie下,显示   "undefined",   ff下显示 "[object]"
26 }
27

28 function foo3(){    //同时兼容ie和ff的写法,取事件对象
29      alert(arguments[0] || window.event)  // ie 和 ff下,都显示 "[object]"
30     var evt=arguments[0] || window.event
31     var element=evt.srcElement || evt.target  //在 ie和ff下   取得 btn3对象

32      alert(element.id)           //     btn3
33 }
34
script>
35

看到这里,我们似乎对 ie和ff的事件处理方式都已经理解了,并找到了解决的办法

 

 

☆ javascript 相关
    △ 这里也有部分总结
        http://www.cnitblog.com/joyboy/archive/2008/07/01/42429.html
       
    △  document.all("id")   -> document.getElementById("id")
        并且控件尽量用id,而不是name标识
        提示: form 内用于提交的元素必须定义name
       
        提示:
        如果控件只有name,没有id, 用getElementById时:
            IE:也可以找到对象
            FF:返回NULL
   
    △  获得form里某个元素的方法
        elForm.elements['name'];
   
    △  取集合元素时, ie支持  [],() 2种写法, 但是ff仅支持[],如:
        table.rows(5).cells(0)
        改为:
        table.rows[5].cells[0]
   
    △  判断对象是否是object的方法应该为
        if( typeof(obj) == "object")

   
    △  eval(对象名称)    ->  document.getElementById              
        FF支持eval函数
   

    △  在当前对象的前面插入节点
        obj.insertAdjacentElement("beforeBegin", elText); 
        改为用
        obj.parentNode.insertBefore(elText, obj);
   
   
    △  FF的createElement不支持HTML代码
        用document.write(esHTML);
   
        或者创建元素后再设置属性, 对input元素来说,需要先设置type再加入到dom里
        var elInput = createElement("input");
        elInput.type = "checkbox";
       
        var obj2 = document.getElementById("id2");
        obj2.parentNode.insertBefore(elInput, obj2);
   
        如果是直接插入html代码,则可以考虑用
        createContextualFragment
   
   
    △  innerText -> textContent
        FF 没有innerText
        如果确定没有html代码, 也可以统一用 innerHTML
   
    △  对象名称中的$不能识别, 建议改为_
        objName = "t1$spin"
        改为
        objName = "t1_spin"
       
    △  FF里设置Attribute为某个对象,然后再取出来,这时候对象的属性都丢失了?
        elText.setAttribute("obj", obj);
        alert(obj.id)   //正确的名字
       
        obj = objText.getAttribute("obj");
        alert(obj.id) //null
       
        在IE下没有问题, FF对setAttribute来说,第2个参数都是字符串型的!!!
        所以如果第2个参数是对象时,相当于调用对象的 toString() 方法了
       
        解决的方法是用下面的调用方式:
        elText.obj = obj;       
        obj = elText.obj
   
   
    △  在html里定义的属性,必须用getAttribute才行
        <input type="text" id="t1" isOBJ="true">
       
        获取时:
        document.getElementById("t1").isOBJ  总返回 undefined, IE下是可以的
       
        应该用:
        document.getElementById("t1").getAttribute("isOBJ")
        
            
    △  el.class -> el.className
        由于class是关键字, 所以需要用 className
        或者用 setAttribute/getAttribute
        setAttribute("class","css样式名称");
      
   
    △  FF里select控件不再是:总是在顶端显示
        需要设置控件的zIndex
        IE6 里select控件总在顶端显示, div不能盖住select
        覆盖select控件的方法是, 用 ifame 盖住 select, 再设置div元素的zIndex大于iframe的zIndex
   
    △  对于if ( vars == undefined ) 下面的值用于判断是等同的
        undefined
        null
        false
        0
   
   
    △  如果FF调用 el.focus(); 报错
        尝试改为:
        window.setTimeout( function(){ el.focus(); }, 20);
   
   
    △  FF下,keyCode是只读的, 那把回车转换为tab怎么办? 在录入时进行键值转换怎么办??
   
        解决方案:
        1. 回车跳转 -> 自己写跳转处理代码.
            遍历dom里所有的元素, 找到当前元素的下一个能够设置焦点的,当前可见的元素, 给其设置焦点
            如果该元素的父节点是不可见的, 则还是会报错, 所以设置焦点时, 需要try catch, 如果报错,则继续找下一个
       
        2. 录入时进行键值转换.
            利用selection,选中光标后面的内容,替换为新输入的内容
        
   
    △  <button> 会被firefox解释为提交form或者刷新页面???
        需要写上type <button type="button">按钮</button>
        或者在οnclick="原函数调用(); return false;"
   
   
    △  在firefox里, document.onfocus里获得不到实际获得焦点的控件?
        为什么document.keydown可以呢?
   
    △  children    -> childNodes      
   
    △  sytle.pixelHeight -> style.height
   
    △  判断函数或者变量是否存在,没有则创建
        if (!("funcA" in window)) var funcA = function() { alert("请覆写funcA方法"); };
       
   
    △  获得客户区尺寸
        IE里与doctype有关
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
       
        如果html包含上面的语句,则应该用下面的方法获取
        document.documentElement.clientWidth
        否则用
        document.body.clientWidth
       
       
    △  window.createPopup
        FF不支持
   
    △  document.body.onresize
        FF 不支持
        用window.onresize
       
        注意,页面打开时并不会触发onresize事件? 需要在onload里也调用一次才行
   
    △  box模型的问题
        IE下默认的是 content-box 为了统一,可用设置:
       
        div, td {-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding: 0;}
       
        而且要定义doctype
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
       
        但是对IE旧代码影响较大
   
    △  注册事件
        IE: el.attachEvent
        FF: el.addEventListener("blur", myBlur, false);
            第1个参数事件名称不需要带"on"
            第3个参数false代表事件传递从事件对象沿dom树往body方向传(与IE的方向一致)
           
            ff里如果不指定 el 则是给全局的事件注册?? 全局岂不是window?
           
           
   
    △  触发事件
        IE: el.fireEvent("onclick");
        FF:
        var e = document.createEvent("Events");  
        e.initEvent("click",   true,   false);  
        element.dispatchEvent(event)
   
    △  在自定义函数中获得对象句柄
        var oThis = this;
        obj.onfocus = function(evt){
            oThis.doOnFocus(evt);
        }
   
    △  统一事件处理框架代码
        function doOnFocus(evt){
            evt = evt || window.event;
            var el = evt.target || evt.srcElement;
           
            // 后续处理
        }
       
   
    △  FF不支持onpropertychange事件
        但是FF里可以定义属性的setter方法, 如下面的:
        HTMLElement.prototype.__defineSetter__("readOnly",
            function(readOnly){
                // 构造虚拟的event对象
                var evt = [];
                evt["target"] = this;
                evt["propertyName"] = "readOnly"
               
                //onpropertychange函数需要定义evt参数, 参考统一事件处理框架代码
                if ("onpropertychange" in this) this.onpropertychange(evt);
            }
        );

    △ document.activeElement
        用途: 在当前对象的 onblur 事件里, 可以通过 activeElement 获得下一个获得焦点的对象
       
        html5规范里加入
       
        firefox3里已经支持,与IE里效果一样
       
       
       
   
☆ css 相关
   
    △  cursor:hand  ->  cursor:pointer
           

    △  FILTER  firefox不支持
        filter: Alpha(Opacity=50);
        替换为
        -moz-opacity: 0.5;
   
    △  text-overflow
        不支持
   
    △  transparent
        firefox下 obj.setAttribute("bgColor","#ffffff") 只支持颜色
        必须用 obj.style.backgroundColor = "transparent" 才行
   
    △  FF下text控件高度与IE不同
        input[type=text] {
            height:20px;
        }
       
        注意input与[之间不能有空格!
   
    △  font在IE里不能对body和td等起作用
        统一用 font-family

       
    △  expression  firefox不支持
        expression的确能够解决IE6对css2支持不足的问题,这样只需要定义css就可以兼容IE和FF了
        在IE下expression非常消耗CPU, 所以不建议在大量的element上应用!!

       
    △  IE6 仅支持 a:hover, 不支持其它对象的 :hover
       
        1. 加入下面的css
            .ie-hover {
                behavior: expression(
                    this.onmouseover = new Function("this.className = 'hover';"),
                    this.onmouseout = new Function("this.className = 'ie-hover';"),
                    this.style.behavior = null
                );
            }
           
            上面必须用 this.style.behavior = null , 否则某些情况会有严重的性能问题
           
           
        2. 在需要 :hover 的元素上增加 class
            <li class="ie-hover">
           
        3. 定义 :hover 样式同时定义 .hover 样式
            ul li:hover , ul li.hover {
                xxx
            }
           

    △  IE6里 <a> 必须定义href属性  a:hover 才有效

 

http://www.cnblogs.com/winner/archive/2008/11/08/1329431.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值