A brief analysis of browser compatibility problems in JavaScript

  • 2021-02-17 06:10:07
  • OfStack

Browser compatibility is one of the most important things that is often overlooked in real development. Before we get into compatibility issues with older browsers, we need to know what capability checking is. It checks whether the browser supports the property or method to be called. The following is a brief introduction.

1, innerText and innerContent
1) innerText and innerContent have the same function
2) Browser support prior to innerText IE8
3) Support for older versions of innerContent
4) The new version of the browser supports both


1 //  Compatible with older browsers  innerText  and  innerContent
2 if (element.textContent) {
3    return element.textContent ;
4  } else {
5    return element.innerText;
6  }

2. Get compatibility issues with sibling nodes/elements
1) sibling nodes, supported by all browsers
①nextSibling has 1 sibling node, which may be non-element node; You get the text node
② There is one sibling node on previousSibling, which may be non-element node; You get the text node
2) sibling elements, not previously supported by IE8

(1) previousElementSibling takes the nearest sibling element and ignores whitespace
nextElementSibling gets the next sibling element and ignores whitespaces


// Compatible browser 
//  To obtain the 1 The adjacent sibling elements 
function getNextElement(element) {
  //  Ability to detect 
 if(element.nextElementSibling) {
   return element.nextElementSibling;
  } else {
     var node = element.nextSibling;
     while(node && node.nodeType !== 1) {
         node = node.nextibling;
     }
     return node;
  }
 }

/**
*  On the back 1 An element 
* @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;
  }
}

/**
*  Returns the first 1 An element firstElementChild Browser Compatibility 
* @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;
  }
}

/**
*  Returns the last 1 An element 
* @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;
  }
}

/**
* Gets all sibling elements of the current element 
* @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 ();
// Creates a new array containing all the elements that pass the test using the specified function


//  Compatible with old environment 
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 ();
// iterate through the array


// Compatible with old environment 
// 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. Register events
.addEventListener = function (type,listener,useCapture ) { };
// The name of the first argument event
// Argument-2 event handler (listener)
// The third parameter, true, catches the false bubble
// ES59en9 will be supported later
// Compatible with old environments


var EventTools = {
    addEventListener: function (element, eventName, listener) {
      // Ability to detect 
      if(element.addEventListener) {
        element.addEventListener(eventName, listener,false);
      }else if(element.attachEvent) {
        element.attachEvent("on" + eventName, listener);
      }else{
        element["on" + eventName] = listener;
      }
    },

//   To remove events, you cannot use anonymous functions 
    removeEventListener: function (element, eventName, listener) {
      if(element.removeEventListener) {
        element.removeEventListener(eventName,listener,false);
      }else if(element.detachEvent) { //IE8 Before registration .attachEvent And remove events .detachEvent
        element.detachEvent("on"+eventName,listener);
      }else{
        element["on" + eventName] = null;
      }
    }
  };

6. Event objects
1) Event parameter e, is the event object, the standard way to obtain
btn.onclick = function(e) { }
2)e.eventPhase event stage, IE8 was not previously supported
3)e.target is always the object that triggers the event (button clicked)
i) IE8 before srcElement
ii) is compatible with browsers
var target = e.target || window.event.srcElement;


//  Get the event object   Compatible browser 
 getEvent: function(e) {
  return e || window.event; // e The event object   Standard access methods;  window.event IE8 Previous way to get event objects 
 }
//  Compatible with target
 getTarget: function(e) {
  return e.target || e.srcElement;
 }

7. Get the mouse position on the page
① Location in the visible area: e.clientX e.clientY
② Location in the document:
i) e. pageX e pageY
ii) is compatible with browsers


// Compatible browser 
//  To obtain the 1 The adjacent sibling elements 
function getNextElement(element) {
  //  Ability to detect 
 if(element.nextElementSibling) {
   return element.nextElementSibling;
  } else {
     var node = element.nextSibling;
     while(node && node.nodeType !== 1) {
         node = node.nextibling;
     }
     return node;
  }
 }
0

8. Get the scroll distance of the page


// Compatible browser 
//  To obtain the 1 The adjacent sibling elements 
function getNextElement(element) {
  //  Ability to detect 
 if(element.nextElementSibling) {
   return element.nextElementSibling;
  } else {
     var node = element.nextSibling;
     while(node && node.nodeType !== 1) {
         node = node.nextibling;
     }
     return node;
  }
 }
1

9. Deselect text


// Compatible browser 
//  To obtain the 1 The adjacent sibling elements 
function getNextElement(element) {
  //  Ability to detect 
 if(element.nextElementSibling) {
   return element.nextElementSibling;
  } else {
     var node = element.nextSibling;
     while(node && node.nodeType !== 1) {
         node = node.nextibling;
     }
     return node;
  }
 }
2

[Summary] This is only a summary of the 1 part, the actual development will also encounter a variety of browser compatibility problems. Different browsers in PC terminal and mobile phone terminal will also encounter different adaptation problems, these will be waiting for children's shoes 1 to explore and summarize ~~ I hope to help you, the lack of advice ~~~


Related articles: