兼容IE9及IE9+

632 阅读1分钟

面对三四线城市用户,用IE的人占有一部分比例。分享一下兼容IE9的心得。vue项目最低兼容到IE9

0. 判断是否是IE9

const isIE9 = () => {
  if (navigator.userAgent.indexOf("MSIE")>0 && navigator.userAgent.indexOf("MSIE 9.0")>0){
    return true;
  }else{
    return false;
  } 
}

1. console.log的问题

IE9中不可使用console.log会阻断js的执行。别小看console.log真是越是简单,越是不起眼的问题越是难发现 自己写上去的console.log 可以手动去掉,但是插件的需要在入口文件覆盖

window.console = (function () {
    var c = {};
    c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile = c.clear = c.exception = c.trace = c.assert = function () { };
    return c;
})();

2. 不可使用flex布局

3. 在IE9浏览器中input 标签没有placeholder 属性,使用时会无效果。

4. 没有windo.location.origin

替换方案:

let origin = ''
if (!window.location.origin) {
  origin =
    window.location.protocol +
    '//' +
    window.location.hostname +
    (window.location.port ? ':' + window.location.port : '')
} else {
  origin = window.location.origin
}

5. 兼容的包

  • IntersectionObserver
import 'intersection-observer'
  • IE6
import 'es6-shim'
  • 兼容promise
require('es6-promise').polyfill()
  • import 'core-js/stable'
  • import 'regenerator-runtime/runtime'
  • import 'proto-polyfill'

6. 改写函数

if (!String.prototype.replaceAll) {
  String.prototype.replaceAll = function(s1, s2) {
    return this.replace(new RegExp(s1, 'gm'), s2)
  }
}

if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    enumerable: false,
    value: function(obj) {
      var newArr = this.filter(function(el) {
        return el == obj
      })
      return newArr.length > 0
    },
  })
}

if (!Array.prototype.find) {
  Array.prototype.find = function(callback) {
    return callback && (this.filter(callback) || [])[0]
  }
}

if (!Array.prototype.fill) {
  Object.defineProperty(Array.prototype, 'fill', {
    value: function(value) {
      // Steps 1-2.
      if (this == null) {
        throw new TypeError('this is null or not defined')
      }

      var O = Object(this)

      // Steps 3-5.
      var len = O.length >>> 0

      // Steps 6-7.
      var start = arguments[1]
      var relativeStart = start >> 0

      // Step 8.
      var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len)

      // Steps 9-10.
      var end = arguments[2]
      var relativeEnd = end === undefined ? len : end >> 0

      // Step 11.
      var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len)

      // Step 12.
      while (k < final) {
        O[k] = value
        k++
      }

      // Step 13.
      return O
    },
  })
}
if (!('classList' in document.documentElement)) {
  Object.defineProperty(HTMLElement.prototype, 'classList', {
    get: function() {
      var self = this
      function update(fn) {
        return function(value) {
          var classes = self.className.split(/\s+/g),
            index = classes.indexOf(value)

          fn(classes, index, value)
          self.className = classes.join(' ')
        }
      }

      return {
        add: update(function(classes, index, value) {
          if (!~index) classes.push(value)
        }),

        remove: update(function(classes, index) {
          if (~index) classes.splice(index, 1)
        }),

        toggle: update(function(classes, index, value) {
          if (~index) classes.splice(index, 1)
          else classes.push(value)
        }),

        contains: function(value) {
          return !!~self.className.split(/\s+/g).indexOf(value)
        },

        item: function(i) {
          return self.className.split(/\s+/g)[i] || null
        },
      }
    },
  })
}
;(function() {
  if (!(Object.setPrototypeOf || {}.__proto__)) {
    var nativeGetPrototypeOf = Object.getPrototypeOf
    Object.getPrototypeOf = function(object) {
      if (object.__proto__) {
        return object.__proto__
      } else {
        return nativeGetPrototypeOf.call(Object, object)
      }
    }
  }
})()