兼容瀏覽器原生DOM的各類特性總結

原生DOM兼容特性

瀏覽器主要也就是IE有點獨特,因此把IE重點區分開javascript

名稱 主流 IE
內文本 innerText textContent
請求對象 XMLHttpRequest ActiveXObject
["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"]
監聽事件添加 addEventListener(DOM2),
['on'+eventName](DOM0)
attachEvent
監聽事件移除 removeEventListener(DOM2),
['on'+eventName]=null(DOM0)
detachEvent
事件對象 function(e) e window.event(IE7以前)
阻止默認事件 preventDefault e.returnValue=false
阻止冒泡 stopPropagation e.cancelBubble=true
鍵盤事件鍵盤編碼 e.charCode e.keyCode
獲取剪貼板的文本 e.clipboardData window.clipboardData
設置剪貼板文本 e.clipboardData.setData("text/plain",value); window.clipboardData.setData("text",value);
觸發事件的元素 e.target e.srcElement
獲取樣式 getComputedStyle(obj,false)[attr];(Firefox瀏覽器)
obj.style.attr(只對filter,opacity等有效)
obj.style[attr]
obj.currentStyle[attr];
窗口左邊的位置 window.screenLeft window.screenX
頁面視口大小 window.innerHeight if(document.compatMode=="CSS1Compat")window.documentElement.clientHeight;
if(document.compatMode=="BackCompat")window.body.clientHeight
獲取元素 document.getElementById(id); document.all[id];(IE5)
返回指定的屬性 ele.getAttribute(attr) ele.attribute[attr]
ele是否存在指定屬性 attr ele.hasAttribute(attr) ele.attributes[attr].specified;
鼠標滾動,正數表示向上滾動 function getWheelDelta(e){
if(e.wheelData){
return (client.engine.opera&&client.engine.opera<9.5)?
-e.wheelData:e.wheelData;
}else {
return -e.detail*40;//firefox
}
}
提取選中的文本 textbox.value.subString(textbox.selectionStart,textbox.selectionEnd); document.selection.createRange().text;
(IE8以前沒有selectionStart,selectionEnd屬性
設置文本選中 textbox.setSelectionRange(startIndex,stopIndex); var range=textbox.createTextRange();
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",stopIndex-startIndex);
range.select()

下面是積累下來的一些兼容函數,能夠當作模板用php

添加多個onload事件

function addLoadEvent(func){
   var oldonload=window.onload;
   if(typeof window.onload!= 'function'){
       window.onload=func;
   }
   else{
       window.onload=function(){
           oldonload();
           func();
       }
   }

}

處理ActiveXObject/XMLHttpRequest問題

//第一種寫法,《js高級程序設計》的寫法  惰性載入技巧
function createXHR(){
   if(typeof XMLHttpRequest!="undefined"){//XMLHttpRequest
       createXHR=function(){
           return new XMLHttpRequest();
       };
   }else if(typeof ActiveXObject!="undefined"){//IE ActiveXObject
       createXHR=function(){
           if(typeof arguments.callee.activeXString!="string"){
               var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],//IE
                   i,len;
                for(i=0,len=versions.length;i<len;i++){
                   try{
                       new ActiveXObject(versions[i]);
                       arguments.callee.activeXString=version[i];
                       break;
                   }catch(ex){}
                }
               
           }
           return new ActiveXObject(arguments.callee.activeXString);
       };
   }else{
       createXHR=function(){
           throw new Error("fail");
       }
   }
   return createXHR();
}

//第二種寫法
function createXHR(){
   if(typeof XMLHttpRequest=="undefined"){
       XMLHttpRequest= function () {
           try{
               return new ActiveXObject("Msxml2.XMLHTTP.6.0");
           }
           catch (e){}

           try{
               return new ActiveXObject("Msxml2.XMLHTTP.3.0");
           }
           catch (e){}

           try{
               return new ActiveXObject("Msxml2.XMLHTTP");
           }
           catch (e){}

           return false;
       }
   }
   return new XMLHttpRequest();
}

請求對象的屬性和方法設置

var xhr=createXHR();
xhr.onreadystatechange=function(){//firfox引入onlaod,readyState==4時觸發,代替onreadystatechange
    if(xhr.readyState==4){
        try{
            if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                alert(xhr.responseText);
            }else {
                alert("unsuccessful");
            }
        }catch(ex){}
    }
}
xhr.onload=function(){
    if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                alert(xhr.responseText);
            }else {
                alert("unsuccessful");
            }
}
xhr.onprogress=function(event){
    if(event.lengthComputable){//進度信息是否可用
        console.log("Received"+event.position+"of"+event.totalSize);
    }
}
xhr.onerror=function(){
    alert("error");
}
xhr.timeout=1000;
xhr.ontimeout=function(){
    alert("timeout");
}
xhr.open("get","example.php",true);
xhr.overrideMimeType("text/xml");
xhr.send(null);//GET

發送表單數據

var form=document.getElementById("info");
xhr.send(serialize(form));//第一種寫法
xhr.send(new FormData(form));//第二種寫法

跨瀏覽器的CORS

function createCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    if("withCredentials" in xhr){
        xhr.open(method,url,true);
    }else if(typeof XDomainRequest !="undefined"){
        xhr=new XDomainRequest();
        xhr.open(method,url);
    }else {
        xhr=null;
    }
    return xhr;
}
var request=createCORSRequest("get","http://www.somewhere");
if(request){
    request.onload=function(){};
    request.send();
}

跨瀏覽器事件處理程序

var eventUtil={
   // 頁面加載完成後
   readyEvent : function(fn) {
       if (fn==null) {
           fn=document;
       }
       var oldonload = window.onload;
       if (typeof window.onload != 'function') {
           window.onload = fn;
       } else {
           window.onload = function() {
               oldonload();
               fn();
           };
       }
   },

   addEventHandler: function (obj, eventName, handler) {
       if (document.attachEvent) {//IE
           obj.attachEvent("on" + eventName, handler);
       } else if (document.addEventListener) {//DOM2級
           obj.addEventListener(eventName, handler, false);//false- 默認。事件句柄在冒泡階段執行
       }
       else{//DOM0級
           obj['on'+eventName]=handler;
       }
   },

   removeEventHandler:function(obj, eventName, handler){
       if (document.attachEvent) {//IE
           obj.detachEvent("on" + eventName, handler);
       } else if (document.addEventListener) {//DOM2級
           obj.removeEventListener(eventName, handler, false);
       }
       else{//DOM0級
           obj['on'+eventName]=null;
       }
   },
  //獲取event對象的引用,取到事件的全部信息,確保隨時能使用event;
   getEvent: function (e) {
       var ev = e || window.event;
       if (!ev) {
           var c = this.getEvent.caller;
           while (c) {
               ev = c.arguments[0];
               if (ev && Event == ev.constructor) {
                   break;
               }
               c = c.caller;
           }
       }
       return ev;
   },
   //事件類型
   getType: function (e) {
       return e.type;

   },
   //調用事件的元素
   getElement: function (e) {
       return e.target|| e.srcElement;
   },
   //阻止默認事件
   preventDefault: function (e) {
       e= this.getEvent(e);
       if(e.preventDefault){
           e.preventDefault();
       }
       else {
           return e.returnValue=false;//IE
       }
   },
   //阻止冒泡
   stopPropagation:function(e) {
     if(e.stopPropagation){
         e.stopPropagation();
     }
       else {
         e.cancelBubble=true;//IE
     }

   },
   //鍵盤事件鍵盤的編號
   getCharCode:function (e){
       if(typeof e.charCode=="number")return e.charCode;
       else return e.keyCode;
   },
   //獲取剪貼板的文本
   getClipbordText:function(e){
       var clipboardData=(e.clipboardData||window.clipboardData);
       return clipboardData.getData("text");
   },
   //設置剪貼板文本
   setClipboardText:function(e,value){
       if(e.clipboardData){
           return e.clipboardData.setData("text/plain",value);
       }else if(window.clipboardData){
           return window.clipboardData.setData("text",value);
       }
   },

}

處理target/srcelemnt問題,代替this

function getActivatedObject(e) {
   var obj;
   if (!e) {
       // early version of IE
       obj = window.event.srcElement;
   } else if (e.srcElement) {
       // IE 7 or later
       obj = e.srcElement;
   } else {
       // DOM Level 2 browser
       obj = e.target;
   }
   return obj;
}

實現insertAfter

/**
* 把newElement插在targetElement後面 ,js的API只有insertBefore,沒有insertAfter
*/
function insertAfter(newElement,targetElement) {
   var parent = targetElement.parentNode;
   if (parent.lastChild == targetElement) {
       parent.appendChild(newElement);
   } else {
       parent.insertBefore(newElement,targetElement.nextSibling);
   }
}

給element加上類名

function addClass(element,value) {
   if (!element.className) {
       element.className = value;
   } else {
       newClassName = element.className;
       newClassName+= " ";
       newClassName+= value;
       element.className = newClassName;
   }
}

判斷是否是數組

function isArray(arg) {
   //return Object.prototype.toString.call(arr)=='[Object Array]';這種方法也能夠
   if (typeof arg == 'object') {
       //全部數組都有一個包含單詞'arry'的constructor,最後的i表示不區分大小寫
       var criteria = arg.constructor.toString().match(/array/i);
       return (criteria != null);
   }
   return false;
}

IE10以前不支持docunment.getElementByClassName

function getByClass(clsName,parent){
   if(docunment.getElementByClassName) return docunment.getElementByClassName(clsName);
   //IE10以前
   var oParent=parent?document.getElementById(parent):document,
       eles=[],
       elements=oParent.getElementsByTagName('*');

   for(var i=0,l=elements.length;i<l;i++){
       if(elements[i].className==clsName){
           eles.push(elements[i]);
       }
   }
   return eles;
}

獲取css樣式

function getStyle(obj,attr){
   if(obj.currentStyle) {//IE 瀏覽器
       return obj.currentStyle[attr];
   }else{//Firefox瀏覽器
       return getComputedStyle(obj,false)[attr];
   }
}

手寫動畫

//動畫 startMove(oLi,{width:400,height:200,opacity:100})
function startMove(obj,json,fn){
   clearInterval(obj.timer);
   obj.timer=setInterval(function () {
       for(var attr in json){
           var cur=0;
           if(attr=='opacity'){
               cur=Math.round(parseFloat(getStyle(obj,attr))*100);
           }
           else {
               cur=parseInt(getStyle(obj,attr));
           }
           var speed=(json[attr]-cur)/8;
           speed=speed>0?Math.ceil(speed):Math.floor(speed);
           var flag=true;
           if(cur!=json[attr]){//使得全部屬性作完運動才結束
               flag=false;
           }
           if(attr=='opacity'){
               obj.style.filter='alpha(opacity:'+(cur+speec)+')';
               obj.style.opacity=(cur+speed)/100;
           }
           else{
               obj.style[attr]=(cur+speed)+'px';
           }
       }
       if(flag){
           clearInterval(obj.timer);
           if(fn){
               fn();
           }
       }
   })
}

取得窗口左邊和上邊的位置

var leftPos=(typeof window.screenLeft =="number")?window.screenLeft:window.screenX;

取得頁面視口大小

var pageWidth=window.innerWidth,
   pageHeight=window.innerHeight;
   if(typeof pageHeight!="number"){
       if(document.compatMode=="CSS1Compat"){//標準模式
           pageHeight=window.documentElement.clientHeight;
           pageWidth=window.documentElement.clientWidth;
       }
       else {//BackCompat
           pageHeight=window.body.clientHeight;
           pageWidth=window.body.clientWidth;
       }
   }

檢測插件方法

/**
*
* 檢測插件方法一,IE下無效
*/
function hasPlugin(name){
   name=name.toLowerCase();
   for(var i=0;i<navigator.plugins.length;i++){
       if(navigator.plugins[i].toLowerCase().indexOf(name)!=-1)
       return true;
   }
   return false;
}

/**
* 檢測IE插件方法二 ,name是COM對象惟一標識符
*/
function hasIEPlugin(name){
   try{
       new ActiveXObject(name);
       return true;
   }catch(ex){
       return false;
   }
}

獲取元素

function getElement(id){
   if(document.getElementById){
       return document.getElementById(id);
   }else if(document.all){//IE5前
       return document.all[id];
   }else {
       throw new Error("no way to retrieve element!");
   }
}

檢查對象的某個特性是否存在

function isHostMethod(object,property){
   var t =typeof object[property];
   return t=="function"||
          (!!(t=="object")&&object[property])||
          t=="unknown";//不懂
}

對象轉換成數組

function convertToArray(nodes){
   var array=null;
   try{
       array=Array.propotype.slice.call(nodes,0);//IE8前無效
   }catch(ex){
       for(var i=0,len=nodes.length;i<len;i++){
           array.push(nodes[i]);
       }
   }
}

返回指定的屬性

/**
* 
* 返回指定的屬性 IE ele.attribute[]
* Element.getAttribute()
*/
function outputAttribute(ele){
   var pairs=new Array(),
       attrname,attrvalue,u,len;
   for(i=0,len=ele.attribute.length;i<len;i++){
       attrname=ele.attributes[i].nodeName;
       attrvalue=ele.attributes[i].nodeValue;
       if(ele.attributes[i].specified){//IE
           pairs.push(attrname+'=\"'+attrvalue+'\"');
       }
   }
}

ele是否存在指定屬性

/**
* 
* ele是否存在指定屬性 attr
*/
function hasattribute(ele,attr){
   if(ele.hasAttribute){
       return ele.hasAttribute(attr);
   }else {//IE
       return ele.attributes[attr].specified;
   }
}

ele是否符合選擇器selector

/**
* ele是否符合選擇器selector
*/
function matchesSelector(ele,selector){
   if(ele.matchesSelector){
       return ele.matchesSelector(selector);
   }else if(ele.msmatchesSelector){
       return ele.msmatchesSelector(selector);
   }else if(ele.mozmatchesSelector){
       return ele.mozmatchesSelector(selector);
   }else if(ele.webkitmatchesSelector){
       return ele.webkitmatchesSelector(selector);
   }else{
       throw new Error("not support");
   }
}

獲取內文本

//innerText/textContent
function getInnerText(ele){
   return (typeof ele.innerText=="string")?
   ele.innerText:ele.textContent;
}

獲取鼠標事件的父元素

function getRelatedTarget(e){
       if(e.relatedTarget) return e.relatedTarget;
       else if(e.fromElement) return e.fromElement;//mouseover
       else if(e.toElement) return e.toElement;//mouseout
       else return null;
   }

探測按的是鼠標的哪一個鍵

function getButton(e){
       if(document.implementation.hasFeature("MouseEvents","2.0")){
           return e.button;
       }else {
           switch(e.button){
               case 0 :
               case 1:
               case 3:
               case 5:
               case 7: return 0;
               case 2:
               case 6:return 2;
               case 4:return 1;
           }
       }
   }

鼠標滾動事件

//鼠標滾動,正數表示向上滾動
function getWheelDelta(e){
       if(e.wheelData){
           return (client.engine.opera&&client.engine.opera<9.5)?
       -e.wheelData:e.wheelData;
       }else {
           return -e.detail*40;//firefox
       }
       
}

提取選中的文本

function getSelectedText(textbox){
   if(typeof selectionStart=="number"){
       return textbox.value.subString(textbox.selectionStart,textbox.selectionEnd);
   }else if(document.selection){//IE8以前沒有selectionStart,selectionEnd屬性
       return document.selection.createRange().text;
   }
}

設置文本選中

function selectText(textbox,startIndex,stopIndex){
    if(textbox.setSelectionRange){
        textbox.setSelectionRange(startIndex,stopIndex);
    }else if(textbox.createTextRange){//IE
        var range=textbox.createTextRange();
        range.collapse(true);
        range.moveStart("character",0);
        range.moveEnd("character",stopIndex-startIndex);
        range.select();
    }
}

bind方法對老版本的瀏覽器不起做用

Function.prototype.bind = Function.prototype.bind || function(context){
     var self = this;

     return function(){
       return self.apply(context, arguments);
     };
   }

包裝cookie

//cookie
var cookieUtil={
   // 建立cookie
   setcookie:function (name, value, expires, path, domain, secure) {
   var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
   if (expires instanceof Date) {
       cookieText += '; expires=' + expires.toGMTString();
   }
   if (path) {
       cookieText += '; path=' + path;
   }
   if (domain) {
       cookieText += '; domain=' + domain;
   }
   if (secure) {
       cookieText += '; secure';
   }
   document.cookie = cookieText;
},
   // 獲取cookie
   getcookie:function (name) {
   var cookieName = encodeURIComponent(name) + '=';
   var cookieStart = document.cookie.indexOf(cookieName);
   var cookieValue = null;
   if (cookieStart > -1) {
       var cookieEnd = document.cookie.indexOf(';', cookieStart);
       if (cookieEnd == -1) {
           cookieEnd = document.cookie.length;
       }
       cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
   }
   return cookieValue;
},
  // 刪除cookie
   unsetcookie:function (name,path,domain,secure) {
   this.setcookie(name,"",new Date(0),path,domain,secure);
}
}

包裝子cookie

//子cookie
var subcookieUtil={
   get:function(name,subname){
       var subcookie=getAll(name);
       if(subcookie){
           return subcookie[subname];
       }else {
           return null;
       }
   },
   getAll:function(name){
       var cookieName = encodeURIComponent(name) + '=';
       var cookieStart = document.cookie.indexOf(cookieName);
       var cookieValue = null;
       var subcookie,result={};
       var len,i,parts;
       if (cookieStart > -1) {
           var cookieEnd = document.cookie.indexOf(';', cookieStart);
           if (cookieEnd == -1) {
           cookieEnd = document.cookie.length;
          }
       cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd);
       if(cookieValue.length>0){
           subcookie=cookieValue.split('&');
           len=subcookie.length;
           for(i=0;i<llen;i++){
               parts=subcookie[i].split('=');
               result[parts[0]]=parts[1];
           }
           return result;
       }
      }
   return null;
   },
   
   set:function (name, subname,value, expires, path, domain, secure) {
       var subcookies=this.getAll(name)||{};
       subcookies[subname]=value;
       this.setAll(name,subcookies,expires,path,domain,secure);
   },
   
   setAll:function(name,subcookies,expires,path,domain,secure){
       var cookieText = encodeURIComponent(name) + '=';
       var subcookiesParts=new Array();
       var subname;
       for(subname in subcookies){
           if(subname.length>0&&subcookies.hasOwnProperty(subname)){
               subcookiesParts.push(encodeURIComponent(subname)+'='+encodeURIComponent(subcookies[subname]));
           }
       }
       if(subcookiesParts.length>0){
           cookieText+=subcookiesParts.join('&');
           if (expires instanceof Date) {
               cookieText += '; expires=' + expires.toGMTString();
           }
           if (path) {
               cookieText += '; expires=' + expires;
            }
           if (domain) {
               cookieText += '; domain=' + domain;
           }
           if (secure) {
               cookieText += '; secure';
           }
       }
   
       document.cookie = cookieText;
   },
   unset:function(name,subname,path,domain,secure){
         var subcookies=this.getAll(name);
       if(subcookies){
             delete subcookies[subname];
             this.setAll(name,subcookies,null,path,domain,secure);
         }
       },
   unsetAll:function(name,path,domain,secure){
         this.setAll(name,null,new Date(0),path,domain,secure);
   }
}

indexedDB

var indexedDB=window.indexedDB||window.mozIndexedDB||window.msIndexedDB||window.webkitIndexedDB;
var idbRequest=indexedDB.open('vvv');
idbRequest.onsuccess=function(event){
   database=event.target.result;
}
idbRequest.onerror=function(event){
   alert(event.target.errorCode);
}

手寫typeof

function type(obj) {
   var toString = Object.prototype.toString;
   var map = {
       '[object Boolean]'  : 'boolean', 
       '[object Number]'   : 'number', 
       '[object String]'   : 'string', 
       '[object Function]' : 'function', 
       '[object Array]'    : 'array', 
       '[object Date]'     : 'date', 
       '[object RegExp]'   : 'regExp', 
       '[object Undefined]': 'undefined',
       '[object Null]'     : 'null', 
       '[object Object]'   : 'object'
   };
   if(obj instanceof Element) {//由於對不一樣標籤,toString會返回對應不一樣標籤的構造函數
       return 'element';
   }
   return map[toString.call(obj)];
}

深度克隆

/**
* 
* 深度克隆方法一,用的是instanceof
*/
function clone(Obj) {
   var buf;   
   if (Obj instanceof Array) {
       buf = [];  // 建立一個空的數組
       var i = Obj.length;
       while (i--) {
           buf[i] = clone(Obj[i]);
       }
       return buf;
   } else if (Obj instanceof Object){
       buf = {};  // 建立一個空對象
       for (var k in Obj) {  // 爲這個對象添加新的屬性
           buf[k] = clone(Obj[k]);
       }
       return buf;
   }else{
       return Obj;
   }
}

/**
* 
* 深度拷貝方法二,用的是 toString
*/
function deepClone(data) {
   var t = type(data), o, i, ni;
   
   if(t === 'array') {
       o = [];
   }else if( t === 'object') {
       o = {};
   }else {
       return data;
   }
   
   if(t === 'array') {
       for (i = 0, ni = data.length; i < ni; i++) {
           o.push(deepClone(data[i]));
       }
       return o;
   }else if( t === 'object') {
       for( i in data) {
           o[i] = deepClone(data[i]);
       }
       return o;
   }
}

//經過JSON.stringify一下,而後再JSON.parse一下,就能實現深拷貝。可是數據類型只支持基本數值類型。
var obj = {
   a: 'a',    
   b: function(){console.log('b')}
}
JSON.stringify(obj);// "{"a":"a"}"

組合使用構造函數模式和原型模式建立對象

//組合使用構造函數模式和原型模式建立對象
function Person(name,age){
   this.name=name;
   this.age=age;
   this.friends=["may","john"];
}
Person.prototype={
   constructor:Person,//字面量形式的原型默認構造函數是object,因此在這裏要指定constructor
   sayName=function(){
       alert(this.name);
   }
}

組合繼承

//組合繼承
funcion super(name){
   this.name=name;
   this.color=["red","blue"];
   
}
Super.prototype.sayname=function(){
   alert(this.name);
}
function Sub(age){
   Super.call(this);
   this.age=age;
}
Sub.prototype=new Super();//
Sub.prototype.constructor=Sub;//這個很重要!!
Sub.prototype.sayage=function(){
   alert(this.age);
}

觀察者模式

//觀察者模式
function EventTarget(){     
   this.handlers = {}; 
} 
EventTarget.prototype = {     
   constructor: EventTarget,
   addHandler: function(type, handler){
        if (typeof this.handlers[type] == "undefined"){
             this.handlers[type] = [];
        }
        this.handlers[type].push(handler);
    }, 
   fire: function(event){//執行
        if (!event.target){
            event.target = this;
        }
        if (this.handlers[event.type] instanceof Array){
            var handlers = this.handlers[event.type];
            for (var i=0, len=handlers.length; i < len; i++){
                handlers[i](event); 
           }
        }
    },
    removeHandler: function(type, handler){ 
       if (this.handlers[type] instanceof Array){ 
           var handlers = this.handlers[type]; 
           for (var i=0, len=handlers.length; i < len; i++){ 
               if (handlers[i] === handler){ 
                   break;
                }
            }
            handlers.splice(i, 1); 
         }
     }
};

分享一個題目

//[附加題] 請實現下面的自定義事件 Event 對象的接口,功能見註釋(測試1)
//該 Event 對象的接口須要能被其餘對象拓展複用(測試2)
//測試1
Event.on('test', function (result) {
   console.log(result);
});
Event.on('test', function () {
   console.log('test');
});
Event.emit('test', 'hello world'); // 輸出 'hello world' 和 'test'
// 測試2
var person1 = {};
var person2 = {};
Object.assign(person1, Event);
Object.assign(person2, Event);
person1.on('call1', function () {
   console.log('person1');
});
person2.on('call2', function () {
   console.log('person2');
});
person1.emit('call1'); //輸出 'person1'
person1.emit('call2'); // 沒有輸出
person2.emit('call1'); // 沒有輸出
person2.emit('call2'); // 輸出 'person2'
var Event = {
   // 經過on接口監聽事件eventName
   // 若是事件eventName被觸發,則執行callback回調函數
   on: function (eventName, callback) {
       //你的代碼
       if(!this.handles){
           //Object.assign(target, source);
//這個是ES6的新對象方法,用於對象的合併,將源對象(source)的全部可枚舉屬性,複製到目標對象(target)。
           Object.defineProperty(this, "handles", {
               value: {},
               enumerable: false,//關鍵!
               configurable: true,
               writable: true
           })
       }
      
      if(!this.handles[eventName]){
           this.handles[eventName]=[];
      }
      this.handles[eventName].push(callback);
   },
   // 觸發事件 eventName
   emit: function (eventName) {
       //你的代碼
      if(this.handles[arguments[0]]){
          for(var i=0;i<this.handles[arguments[0]].length;i++){
              this.handles[arguments[0]][i](arguments[1]);
          }
      }
   }
};
//輸出全部頁面寬度和高度大於50像素的節點。
function traverse(oNode) {
   var aResult = [];
   oNode = oNode || document.body;
   if (oNode.style) {
       var nWidth = window.parseInt(oNode.style.width, 10) || 0;
       var nHeight = window.parseInt(oNode.style.height, 10) || 0;
       if (nWidth > 50 && nHeight > 50) {
           aResult.push(oNode);
       }
   }
   var aChildNodes = oNode.childNodes;
   if (aChildNodes.length > 0) {
       for (var i = 0, l = aChildNodes.length; i < l; i++) {
           var oTmp = aChildNodes[i];
           aResult = aResult.concat(traverse(oTmp));
       }
   }
   return aResult;
}
相關文章
相關標籤/搜索