Native DOM compatibility features

Browser main IE is a little bit unique, so the IE focus to distinguish

The name of the The mainstream IE
The text within innerText textContent
The request object XMLHttpRequest ActiveXObject

[” MSXML2. XMLHttp. 6.0 “, “MSXML2. XMLHttp. 3.0”, “MSXML2. XMLHttp”]
Add listening events addEventListener(DOM2),

[‘on’+eventName](DOM0)
attachEvent
Listener Event Removal removeEventListener(DOM2),

[‘on’+eventName]=null(DOM0)
detachEvent
The event object function(e) e Before the window. The event (ie 7)
Blocking default events preventDefault e.returnValue=false
To prevent a bubble stopPropagation e.cancelBubble=true
Keyboard event keyboard encoding e.charCode e.keyCode
Gets the text of the clipboard e.clipboardData window.clipboardData
Sets the clipboard text e.clipboardData.setData(“text/plain”,value); window.clipboardData.setData(“text”,value);
The element that triggers the event e.target e.srcElement
Get the style getComputedStyle(obj,false)[attr]; (Firefox)

Attr (only valid for filter,opacity, etc.)

obj.style[attr]
obj.currentStyle[attr];
The position to the left of the window window.screenLeft window.screenX
Page viewport size window.innerHeight if(document.compatMode==”CSS1Compat”)window.documentElement.clientHeight;

if(document.compatMode==”BackCompat”)window.body.clientHeight

Access to elements document.getElementById(id); document.all[id]; (IE5)
Returns the specified property ele.getAttribute(attr) ele.attribute[attr]
Ele whether the specified attribute attr exists ele.hasAttribute(attr) ele.attributes[attr].specified;
Mouse scroll, the positive number indicates that scroll up function getWheelDelta(e){

if(e.wheelData){

Return (client) engine) opera && client. The engine. The opera < 9.5).

-e.wheelData:e.wheelData;

}else {

return -e.detail*40; //firefox

}

}
Extracts the selected text textbox.value.subString(textbox.selectionStart,textbox.selectionEnd); document.selection.createRange().text;

Before IE8, there was no selectionStart, selectionEnd attribute
Set text selection textbox.setSelectionRange(startIndex,stopIndex); var range=textbox.createTextRange();

range.collapse(true);

range.moveStart(“character”,0);

range.moveEnd(“character”,stopIndex-startIndex);

range.select()

Here are some of the compatibility functions that have been accumulated and can be used as templates

  • Add multiple onLoad events
  • Dealing with ActiveXObject/XMLHttpRequest
  • Request object properties and method Settings
  • Sending form data
  • Cross-browser CORS
  • Cross-browser event handlers
  • Handles target/srcelemnt instead of this
  • Implement insertAfter
  • Give Element a class name
  • Check if it’s an array
  • Before the consumer does not support the docunment. GetElementByClassName
  • Get the CSS style
  • Handwritten animation
  • Get the left and top positions of the window
  • Gets the page viewport size
  • Detection plug-in method
  • Access to elements
  • Checks whether a property of an object exists
  • Objects are converted to arrays
  • Returns the specified property
  • Ele indicates whether the specified attribute exists
  • Whether ele matches selector
  • Get inside text
  • Gets the parent element of the mouse event
  • Detect which mouse key is pressed
  • Mouse scroll event
  • Extracts the selected text
  • Set text selection
  • The bind method does not work with older browsers
  • Packing cookies
  • Wraps a cookie
  • indexedDB
  • Handwritten typeof
  • The depth of the clone
  • Use a combination of constructor and stereotype patterns to create objects
  • Combination of inheritance
  • Observer model
  • Share a topic

Add multiple onLoad events

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

Dealing with ActiveXObject/XMLHttpRequest

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"], / / I, IE 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(); }Copy the code

Request object properties and method Settings

var xhr=createXHR(); Xhr.onreadystatechange =function(){ 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){// Whether progress information is available 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); //GETCopy the code

Sending form data

var form=document.getElementById("info"); xhr.send(serialize(form)); Xhr. send(new FormData(form)); // The second wayCopy the code

Cross-browser 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(); }Copy the code

Cross-browser event handlers

Var eventUtil={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) {/ / grade DOM2 obj addEventListener (eventName, handler, false); / / false - the default. } else{//DOM0 level obj['on'+eventName]=handler; } }, removeEventHandler:function(obj, eventName, handler){ if (document.attachEvent) {//IE obj.detachEvent("on" + eventName, handler); } else if (document. AddEventListener) {/ / DOM2 level obj. The removeEventListener (eventName, handler, false); } else {/ / DOM0 level obj [' on '+ eventName] = null; }}, // Get a reference to the event object, get all the information about the event, ensure that the event is always available; 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; }, // event type getType: function (e) {return e.type; }, / / call event element getElement: function (e) {return e. arget | | e.s rcElement; }, // preventDefault preventDefault: function (e) {e= this.getevent (e); if(e.preventDefault){ e.preventDefault(); } else { return e.returnValue=false; Function (e) {if(e.topPropagation){e.topPropagation (); } else { e.cancelBubble=true; GetCharCode :function (e){if(typeof e.charcode =="number")return e.charcode; else return e.keyCode; }, / / for the clipboard text getClipbordText: function (e) {var clipboardData = (e.c. with our fabrication: lipboardData | | window. The clipboardData); return clipboardData.getData("text"); }, / / set the clipboard text setClipboardText: function (e, value) {if (e.c. with our fabrication: lipboardData) {return e.c. with our fabrication: lipboardData. SetData (" text/plain ", value); }else if(window.clipboardData){ return window.clipboardData.setData("text",value); }}},Copy the code

Handles target/srcelemnt instead of 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; }Copy the code

Implement insertAfter

/** * insert newElement after targetElement,js API only insertBefore, InsertAfter (newElement,targetElement) {var parent = targetElement. ParentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSibling); }}Copy the code

Give Element a class name

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

Check if it’s an array

function isArray(arg) { //return Object.prototype.toString.call(arr)=='[Object Array]'; This method can also be used if (typeof arg == 'object') {// All arrays have a constructor containing the word 'arry', and the final I means case-insensitive var criteria = arg.constructor.toString().match(/array/i); return (criteria ! = null); } return false; }Copy the code

Before the consumer does not support the docunment. GetElementByClassName

function getByClass(clsName,parent){ if(docunment.getElementByClassName) return docunment.getElementByClassName(clsName); 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; }Copy the code

Get the CSS style

Function getStyle(obj,attr){if(obj.currentStyle) {//IE browser return obj.currentStyle[attr]; }else{//Firefox browser return getComputedStyle(obj,false)[attr]; }}Copy the code

Handwritten animation

/ / animation 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]){// Make all attributes complete motion 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(); }}})}Copy the code

Get the left and top positions of the window

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

Gets the page viewport size

var pageWidth=window.innerWidth, pageHeight=window.innerHeight; if(typeof pageHeight! = "number") {if patMode = = "CSS1Compat" (document.com) {/ / standard mode pageHeight = window. DocumentElement. ClientHeight; pageWidth=window.documentElement.clientWidth; } else {//BackCompat pageHeight=window.body.clientHeight; pageWidth=window.body.clientWidth; }}Copy the code

Detection plug-in method

*/ 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; */ function hasIEPlugin(name){try{new ActiveXObject(name); return true; }catch(ex){ return false; }}Copy the code

Access to elements

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!");
   }
}Copy the code

Checks whether a property of an object exists

function isHostMethod(object,property){ var t =typeof object[property]; return t=="function"|| (!! (t=="object")&&object[property])|| t=="unknown"; / / don't understand}Copy the code

Objects are converted to arrays

function convertToArray(nodes){ var array=null; try{ array=Array.propotype.slice.call(nodes,0); }catch(ex){for(var I =0,len=nodes.length; i<len; i++){ array.push(nodes[i]); }}}Copy the code

Returns the specified property

[] * 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+'\"'); }}}Copy the code

Ele indicates whether the specified attribute exists

Attr */ function hasattribute(ele,attr){if(ele. Hasattribute){return ele. Hasattribute (attr); }else {//IE return ele.attributes[attr].specified; }}Copy the code

Whether ele matches 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"); }}Copy the code

Get inside text

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

Gets the parent element of the mouse event

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; }Copy the code

Detect which mouse key is pressed

The function getButton (e) {if (document. Implementation. HasFeature (" MouseEvents ", "2.0")) {return e.b utton; }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; }}}Copy the code

Mouse scroll event

Function getWheelDelta(e){if(e.data){return (client.engine. Opera &&client.engine. Opera <9.5)? -e.wheelData:e.wheelData; }else { return -e.detail*40; //firefox } }Copy the code

Extracts the selected text

function getSelectedText(textbox){ if(typeof selectionStart=="number"){ return textbox.value.subString(textbox.selectionStart,textbox.selectionEnd); {} else if (the document selection) / / no selectionStart before IE8, selectionEnd properties return document. The selection, createRange (). The text; }}Copy the code

Set text selection

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(); }}Copy the code

The bind method does not work with older browsers


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

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

Packing cookies

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; 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; }, // delete cookie unsetcookie:function (name,path,domain,secure) {this.setcookie(name,"",new Date(0),path,domain,secure); }}Copy the code

Wraps a 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); }}Copy the code

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);
}Copy the code

Handwritten 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) {// Because toString returns the constructor 'Element' for each tag; } return map[toString.call(obj)]; }Copy the code

The depth of the clone

/** ** instanceof */ function clone(Obj) {var buf; if (Obj instanceof Array) { buf = []; // Create an empty array var I = obj. length; while (i--) { buf[i] = clone(Obj[i]); } return buf; } else if (Obj instanceof Object){ buf = {}; Buf [k] = clone(Obj[k]); for (var k in Obj) {buf[k] = clone(Obj[k]); } return buf; }else{ return Obj; 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; }} // Use json.stringify and json.parse to make a deep copy. But data types only support basic numeric types. var obj = { a: 'a', b: function(){console.log('b')} } JSON.stringify(obj); // "{"a":"a"}"Copy the code

Use a combination of constructor and stereotype patterns to create objects

Function Person(name,age){this.name=name; this.age=age; this.friends=["may","john"]; } Person. Prototype ={constructor: object; // Constructor sayName=function(){ alert(this.name); }}Copy the code

Combination of inheritance

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; // This is important!! Sub.prototype.sayage=function(){ alert(this.age); }Copy the code

Observer model

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){// execute 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); }}};Copy the code

Share a topic

//[additional questions] Implement the following interface for custom Event objects, On ('test', function (result) {console.log(result); function (result) {console.log(result); }); Event.on('test', function () { console.log('test'); }); Event.emit('test', 'hello world'); Var person1 = {}; 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'); // output 'person1' person1.emit('call2'); // person2.emit('call1') is not output; // person2.emit('call2') is not output; // If eventName is raised, execute the callback function on: Function (eventName, callback) {// Your code if(! this.handles){ //Object.assign(target, source); // This is a new object method in ES6. It is used for object merging. All enumerable properties of the source object are copied to the target object. 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]); }}}}; // Outputs all nodes with page width and height greater than 50 pixels. 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; }Copy the code