博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
兼容浏览器原生DOM的各种特性总结
阅读量:6715 次
发布时间:2019-06-25

本文共 21034 字,大约阅读时间需要 70 分钟。

原生DOM兼容特性

浏览器主要也就是IE有点独特,所以把IE重点区分开

名称 主流 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()

下面是积累下来的一些兼容函数,可以当做模板用

添加多个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

请求对象的属性和方法设置

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

获取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

获取元素

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

返回指定的属性

/*** * 返回指定的属性 IE ele.attribute[]* Element.getAttribute()*/function outputAttribute(ele){   var pairs=new Array(),       attrname,attrvalue,u,len;   for(i=0,len=ele.attribute.length;i

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/textContentfunction 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

//cookievar 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

//子cookievar 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
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)//测试1Event.on('test', function (result) {   console.log(result);});Event.on('test', function () {   console.log('test');});Event.emit('test', 'hello world'); // 输出 'hello world' 和 'test'// 测试2var 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
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;}

转载地址:http://blelo.baihongyu.com/

你可能感兴趣的文章
jvm疯狂吞占内存,罪魁祸首是谁?
查看>>
表格存储Tablestore权威指南(持续更新)
查看>>
java B2B2C源码电子商城系统-Kafka快速入门
查看>>
Spring Cloud云服务 - HongHu架构common-service 项目构建过程
查看>>
hadoop中hive原理及安装
查看>>
pear默认安装后一个小bug
查看>>
nginx-通过Nginx统计当前每个域名流量
查看>>
OpenSSL学习(二十五):基础-指令x509
查看>>
sql server随机函数
查看>>
WinAircrackPack 破解你邻居家的无线WIFI密码
查看>>
自定义格式化字符串
查看>>
bgp发布路由对端无法收到,原因是使用默认网段
查看>>
JQuery实现简单的服务器轮询效果
查看>>
幽灵漏洞(GHOST)影响大量Linux操作系统及其发行版(更新修复方案)
查看>>
Sunday算法
查看>>
netstat
查看>>
优朋普乐:OTT正重构电视版图
查看>>
遇到"process launch failed: Security"问题,解决的一种方法
查看>>
Ubuntu 14.04 LTC 有线网络——网线不识别,灯不亮问题
查看>>
Unity3D DLL加密
查看>>