瀏覽器主要也就是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
function addLoadEvent(func){ var oldonload=window.onload; if(typeof window.onload!= 'function'){ window.onload=func; } else{ window.onload=function(){ oldonload(); func(); } } }
//第一種寫法,《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));//第二種寫法
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); } }, }
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; }
/** * 把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); } }
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; }
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; }
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是否存在指定屬性 attr */ function hasattribute(ele,attr){ if(ele.hasAttribute){ return ele.hasAttribute(attr); }else {//IE return ele.attributes[attr].specified; } }
/** * 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(); } }
Function.prototype.bind = Function.prototype.bind || function(context){ var self = this; return function(){ return self.apply(context, arguments); }; }
//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 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); } }
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); }
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; }