几个兼容相关的重要函数

几个兼容相关的重要函数

1. 创建XMLHttpRequest对象

 1 function createXHR() {
 2     if (typeof XMLHttpRequest != "undefined") {
 3         return new XMLHttpRequest(); //IE7+和其他浏览器支持的
 4     }else if (typeof ActiveXObject != "undefined") { //IE7-支持的
 5             if (typeof arguments.callee.activeXString != "string") {
 6                 var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
 7                 i, len;
 8                 for (i = 0, len = versions.length; i < len; i++) {
 9                 try {
10                         new ActiveXObject(versions[i]);
11                         arguments.callee.activeXString = versions[i];
12                         break;
13                 } catch (e) {
14                     //跳过
15                 }
16             }
17         }
18         return new ActiveXObject(arguments.callee.activeXString); //返回ActiveXObject对象
19     } else { //全部不支持,抛出错误
20     throw new Error("don't support XMLHttpRequest");
21     }
22 }
23 
24 var xhr = createXHR();//在所有浏览器中创建XHR对象

2. 原生js实现跨浏览器的事件对象和事件处理程序

2.1 获取事件对象

1 var event=event || window.event;

2.2 获取事件源

event.srcElement是[IE8-]唯一的方式,IE9+未知,其它浏览器都支持标准的event.target方式

2.3 阻止事件默认行为

event.preventDefault()是标准方法,但[IE8-]不支持,IE自己的方式是event.returnValue = false;

2.4 阻止事件冒泡

event.stopPropagation()是标准方法,IE:event.cancelBubble = true;

小结一下:

  1. DOM中的事件对象
    (1) type:获取事件类型
    (2) target:事件目标
    (3) stopPropagation() 阻止事件冒泡
    (4) preventDefault() 阻止事件的默认行为
  2. IE中的事件对象
    (1) type:获取事件类型
    (2) srcElement:事件目标
    (3) cancelBubble=true阻止事件冒泡
    (4) returnValue=false阻止事件的默认行为

2.5 事件处理程序的添加和移除

DOM0级方式

1 ele.onclick = handler;//事件的绑定
2 ele.onclick=null;//事件的移除

注意:
1)要使用javascript指定事件处理程序,首先必须取得一个要操作的对象的引用;

2)程序中的this引用当前元素;(这一点与IE不同,要格外注意)
优点: 简单,全浏览器兼容
缺点:同一事件只能绑定/解绑一个事件处理程序

DOM2级方式

1 ele.add/removeEventListener(eventType, handler, catch);

接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。布尔值为true,表示在捕获阶段调用事件处理程序;false表示在冒泡阶段调用事件处理程序(一般在冒泡阶段)。

IE

1 ele.attach/detachEvent(‘on'+eventType, handler);

接受2个参数:事件处理程序名称和事件处理程序函数。(与DOM2级相比,少一个布尔值,IE不支持事件捕获,所以也就没有第三个参数了)

注意:
1)通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除;
2)IE添加事件名称是“onclick”,而非DOM的“click”;
优点: 支持绑定/解绑多个事件处理程序
缺点:需要做兼容性判断。

格外留意!!在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this会等于window。(JavaScript高级程序设计352页)

1 var btn = document.getElementById("mybtn");
2 btn.attachEvevt("onclick",function(){
3     alert(this == window);//true
4 })

2.6 跨浏览器的事件处理

//elem事件目标元素, type事件类型, handler事件处理程序
var EventUtil = {
  addHandler : function(elem, type, handler){
    if(elem.addEventListener){  //DOM2级事件处理程序,添加多个同一类型的handler时,按顺序触发
      elem.addEventListener(type, handler, false);
    }
    else if(elem.attachEvent){  //IE
      elem.attachEvent("on" + type, handler);//添加多个同一类型的handler时,IE方式的规则是最后添加的最先触发
    }
    else{
        elem["on" + type] = handler;//DOM0级
      }
    },

  getEvent : function(event){
    return event ? event : window.event;
  },

  getTarget : function(event){
    return event.target || event.srcElement;
  },

  preventDefault : function(event){
    if(event.preventDefault){
      event.preventDefault();
    }
    else{
      event.returnValue = false;
    }
  },

removeHandler : function(elem, type, handler){
    if(elem.removeEventListener){
      elem.removeEventListener(type, handler, false);
    }
    else if(elem.detachEvent){
      elem.detachEvent("on" + type, handler);
    }
    else{
      elem["on" + type] = null;
    }
  },

  stopPropagation : function(event){
    if(event.stopPropagation){
      event.stopPropagation();
    }
    else{
      event.cancelBubble = true;
    }
  }

};

乱入几个面试中问到的问题:

1.解释一下事件冒泡和事件捕获。

待续。。。。。。。