Skip to content

老旧浏览器API兼容

获取滚动距离

js
/**
 * 兼容: 获取offsetTop/offsetLeft, 惰性函数(只会判断一次)
 * @returns {Object: {top, left}}
 */
var getScrollOffset = (function () {
  if (window.pageXOffset) {
    return function () {
      return {
        top: window.pageXOffset,
        left: window.pageYOffset,
      };
    };
  }

  return function () {
    return {
      top: document.body.scrollTop + document.documentElement.scrollTop,
      left: document.body.scrollLeft + document.documentElement.scrollLeft,
    };
  };
})();

获取已经已滚动的宽/高度 PageX/Y

js
/**
 * 兼容: 获取滚动的宽度/高度
 * @returns {object: {width, height}}
 */
var getScrollSize = (function () {
  if (document.body.scrollHeight) {
    return function () {
      return {
        width: document.body.scrollWidth,
        height: document.body.scrollHeight,
      };
    };
  }
  return function () {
    return {
      width: document.documentElement.scrollWidth,
      height: document.documentElement.scrollHeight,
    };
  };
})();

/**
 * 兼容: pageX/pageY
 * @param {Event} e
 * @returns {Object:{x, y}}
 */
var getPagePosition = function (e) {
  var scrollPos = getScrollOffset(),
    clientLeft = document.documentElement.clientLeft || 0,
    clientTop = document.documentElement.clientTop || 0;
  return {
    x: e.clientX + scrollPos.left - clientLeft,
    y: e.clientY + scrollPos.top - clientTop,
  };
};

获取可视区域大小

js
/**
 * 兼容: 获取可视区域大小
 * @returns {Object:{width, height}}
 */
var getViewportSize = (function () {
  if (window.innerWidth) {
    return function () {
      return {
        width: window.innerWidth,
        height: window.innerHeight,
      };
    };
  } else {
    return function () {
      // ie
      var key = document.compatMode === 'BackCompat' ? 'body' : 'documentElement';
      return {
        width: document[key].clientWidth,
        height: document[key].clientHeight,
      };
    };
  }
})();

获取 style 对象属性的值

js
/**
 * 兼容: 获取 getComputedStyle 的值
 * @returns {string|number|undefined}
 */
var getStyles = (function () {
  if (window.getComputedStyle) {
    return function (el, prop) {
      var styles = window.getComputedStyle(el, null);
      return styles[prop] ? styles[prop] : undefined;
    };
  }

  return function (el, prop) {
    // ie
    var styles = el.currentStyle;
    return styles[prop] ? styles[prop] : undefined;
  };
})();

添加/移除事件监听函数

js
/**
 * 兼容: 添加事件处理函数(惰性函数另一种实现,只会判断一次)
 * @param {HTMLElement} el 事件源
 * @param {String} type 事件类型
 * @param {Function} handler 事件处理函数
 * @returns
 */
function addEvent(el, type, handler, capture) {
  if (el.addEventListener) {
    addEvent = function (el, type, handler, capture) {
      el.addEventListener(type, handler, capture);
    };
  } else if (el.attachEvent) {
    addEvent = function (el, type, handler) {
      el.attachEvent('on' + type, function () {
        handler.call(el);
      });
    };
  } else {
    addEvent = function (el, type, handler) {
      el['on' + type] = handler;
    };
  }
  return addEvent(el, type, handler, capture);
}

/**
 * 兼容: 移除事件处理函数
 * @param {HTMLElement} el 事件源
 * @param {String} type 事件类型
 * @returns
 */
function removeEvent(el, type, handler) {
  if (el.removeEventListener) {
    removeEvent = function (el, type, handler) {
      el.removeEventListener(type, handler);
    };
  } else if (el.detachEvent) {
    removeEvent = function (el, type, handler) {
      el.detachEvent('on' + type, handler);
    };
  } else {
    removeEvent = function (el, type, _handler) {
      el['on' + type] = null;
    };
  }
  return removeEvent(el, type, handler); // 只有这一次执行会判断
}

取消冒泡/浏览器默认行为

js
/**
 * 兼容: 取消冒泡
 * @param {Event} e
 * @returns
 */
function cancelBubble(e) {
  if (e.stopPropagation) {
    cancelBubble = function (e) {
      e = e || window.event;
      return e.stopPropagation();
    };
  } else {
    cancelBubble = function (e) {
      e = e || window.event; // window.event 兼容ie8及其以下版本的浏览器
      e.cancelBubble = true;
    };
  }

  return cancelBubble(e);
}

/**
 * 兼容: 取消浏览器默认事件
 * @param {Event} e
 * @returns
 */
function preventDefault(e) {
  var e = e || window.event;
  if (e.preventDefault) {
    // w3c standard
    preventDefault = function (e) {
      e.preventDefault(e);
    };
  } else {
    // ie: 9/8/7/6
    preventDefault = function (e) {
      e = e || widow.event;
      e.returnValue = false;
    };
  }
  return preventDefault(e);
}

Released under the MIT License.