zoukankan      html  css  js  c++  java
  • 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.onload=function() {
        $('btn1').onclick=fun1;
        $('btn2').onclick=fun2;
        $('btn3').onclick=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" onclick="fun">按钮</button>
      <script>
      function fun(){  
          ;
      }
      </script>

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

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

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

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

      方法二: 自动查找

      <button id="btn4" onclick="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">按钮1button>
    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>
            或者在onclick="原函数调用(); 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 才有效

  • 相关阅读:
    链接收藏:bullet物理引擎不完全指南
    设计模式的六大原则
    链接错误 2038
    玄天宝录
    第二章 期中架构
    第一章 Linux基础
    13 代理与负载均衡基础
    12 LNMP搭建
    11 搭建博客
    10 Nginx模块介绍
  • 原文地址:https://www.cnblogs.com/winner/p/1329431.html
Copyright © 2011-2022 走看看