Home > Article > Web Front-end > A brief analysis of browser compatibility issues in JavaScript_javascript skills
Browser compatibility issues are easily overlooked but the most important part in actual development. Before we talk about the compatibility issue with older versions of browsers, we must first understand what capability detection is. It is used to detect whether the browser has this capability, that is, to determine whether the current browser supports the attribute or method to be called. Below are some brief introductions.
1. innerText and innerContent
1) innerText and innerContent have the same function
2) innerText is supported by browsers before IE8
3) innerContent is supported by older versions of Firefox
4) The new version of the browser supports both methods
1 // 老版本浏览器兼容 innerText 和 innerContent 2 if (element.textContent) { 3 return element.textContent ; 4 } else { 5 return element.innerText; 6 }
2. Compatibility issues in obtaining sibling nodes/elements
1) Brother node, all browsers support
①nextSibling The next sibling node may be a non-element node; the text node
will be obtained
②previousSibling The previous sibling node may be a non-element node; the text node
will be obtained
2) Brother element, IE8 did not support it before
①previousElementSibling Gets the previous sibling element and ignores blank spaces
②NEXTELEMENTSIBLING to get the next neighboring brother element, it will ignore the blank
//兼容浏览器 // 获取下一个紧邻的兄弟元素 function getNextElement(element) { // 能力检测 if(element.nextElementSibling) { return element.nextElementSibling; } else { var node = element.nextSibling; while(node && node.nodeType !== 1) { node = node.nextibling; } return node; } }
/** * 返回上一个元素 * @param element * @returns {*} */ function getPreviousElement(element) { if(element.previousElementSibling) { return element.previousElementSibling; }else { var el = element.previousSibling; while(el && el.nodeType !== 1) { el = el.previousSibling; } return el; } }
/** * 返回第一个元素firstElementChild的浏览器兼容 * @param parent * @returns {*} */ function getFirstElement(parent) { if(parent.firstElementChild) { return parent.firstElementChild; }else { var el = parent.firstChild; while(el && el.nodeType !== 1) { el = el.nextSibling; } return el; } }
/** * 返回最后一个元素 * @param parent * @returns {*} */ function getLastElement(parent) { if(parent.lastElementChild) { return parent.lastElementChild; }else { var el = parent.lastChild; while(el && el.nodeType !== 1) { el = el.previousSibling; } return el; } }
/** *获取当前元素的所有兄弟元素 * @param element * @returns {Array} */ function sibling(element) { if(!element) return ; var elements = [ ]; var el = element.previousSibling; while(el) { if(el.nodeType === 1) { elements.push(el); } el = el.previousSibling; } el = element.previousSibling; while(el ) { if(el.nodeType === 1) { elements.push(el); } el = el.nextSibling; } return elements; }
3. array.filter();
// Test all elements using the specified function and create a new array containing all elements that pass the test
// 兼容旧环境 if (!Array.prototype.filter) { Array.prototype.filter = function(fun /*, thisArg */) { "use strict"; if (this === void 0 || this === null) throw new TypeError(); var t = Object(this); var len = t.length >>> 0; if (typeof fun !== "function") throw new TypeError(); var res = []; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t) { var val = t[i]; // NOTE: Technically this should Object.defineProperty at // the next index, as push can be affected by // properties on Object.prototype and Array.prototype. // But that method's new, and collisions should be // rare, so use the more-compatible alternative. if (fun.call(thisArg, val, i, t)) res.push(val); } } return res; }; }
4. array.forEach();
// Traverse the array
//兼容旧环境 // Production steps of ECMA-262, Edition 5, 15.4.4.18 // Reference: http://es5.github.io/#x15.4.4.18 if (!Array.prototype.forEach) { Array.prototype.forEach = function(callback, thisArg) { var T, k; if (this == null) { throw new TypeError(' this is null or not defined'); } // 1. Let O be the result of calling toObject() passing the // |this| value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get() internal // method of O with the argument "length". // 3. Let len be toUint32(lenValue). var len = O.length >>> 0; // 4. If isCallable(callback) is false, throw a TypeError exception. // See: http://es5.github.com/#x9.11 if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function'); } // 5. If thisArg was supplied, let T be thisArg; else let // T be undefined. if (arguments.length > 1) { T = thisArg; } // 6. Let k be 0 k = 0; // 7. Repeat, while k < len while (k < len) { var kValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty // internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal // method of O with argument Pk. kValue = O[k]; // ii. Call the Call internal method of callback with T as // the this value and argument list containing kValue, k, and O. callback.call(T, kValue, k, O); } // d. Increase k by 1. k++; } // 8. return undefined }; }
5. Registration event
.addEventListener = function (type,listener,useCapture ) { };
//First parameter event name
//Second parameter event handling function (listener)
//The third parameter true captures false bubbling
//Only supported after IE9
// Compatible with old environments
var EventTools = { addEventListener: function (element, eventName, listener) { //能力检测 if(element.addEventListener) { element.addEventListener(eventName, listener,false); }else if(element.attachEvent) { element.attachEvent("on" + eventName, listener); }else{ element["on" + eventName] = listener; } }, // 想要移除事件,不能使用匿名函数 removeEventListener: function (element, eventName, listener) { if(element.removeEventListener) { element.removeEventListener(eventName,listener,false); }else if(element.detachEvent) { //IE8以前注册.attachEvent和移除事件.detachEvent element.detachEvent("on"+eventName,listener); }else{ element["on" + eventName] = null; } } };
6. Event object
1) The event parameter e is the event object, the standard acquisition method
btn.onclick = function(e) { }
2) e.eventPhase event phase, which was not supported before IE8
3)e.target is always the object that triggers the event (the clicked button)
i) Before IE8 srcElement
ii) Browser compatible
var target = e.target || window.event.srcElement;
// 获取事件对象 兼容浏览器 getEvent: function(e) { return e || window.event; // e事件对象 标准的获取方式; window.event IE8以前获取事件对象的方式 } // 兼容target getTarget: function(e) { return e.target || e.srcElement; }
7. Get the position of the mouse on the page
①Position in the visible area: e.clientX e.clientY
②Position in the document:
i) e.pageX e.pageY
ii) Browser compatible
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; var pageY = e.clientY + scrollTop;
8. Get the scrolling distance of the page
// 兼容浏览器 var scrollTop = document.documentElement.scrollTop || document.body.scrolltop;
9. Cancel text selection
// 兼容浏览器 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
[Summary] Here is just a partial summary. In actual development, various browser compatibility issues will also be encountered. Different browsers will also encounter different adaptation problems on PC and mobile phones. These are for children to explore and summarize together~~ I hope it can help everyone. Please give me more advice on the shortcomings~~~
The above brief analysis of browser compatibility issues in JavaScript is all the content shared by the editor. I hope it can give you a reference, and I hope you will support Script Home.