滚动距离控制

144 阅读1分钟

要考虑兼容性

获取滚动距离

/* 
常规:
window.pageYoffset;

IE9、IE8及以下:
(这俩互斥一个可用的话另一个肯定是0)
document.body.scrollTop;
document.documentElement.scrollTop;

不常见:
window.scrollX;*/
function getScrollOffset() {
  if (window.pageXoffSet) {
    return {
      left: window.pageXOffSet,
      top: window.pageYOffSet,
    };
  } else {
    return {
      left: document.body.scrollLeft + document.documentElement.scrollLeft,
      top: document.body.scrollTop + document.documentElement.scrollTop,
    };
  }
}

获取浏览器可视区域尺寸

浏览器的怪异模式和标准模式

dom 是由 w3c 制定规范的,因此如果 HTML 头部增加<!DOCTYPE html> 则表明为标准模式,如果没有则是浏览器的怪异模式

/*
常规:
window.innerWidth/window.innerHeight

IE9、IE8及以下:
标注模式:document.documentElement.clientWidth/document.documentElement.clientHeight
怪异模式:document.body.clientWidth/document.body.clientHeight
*/
function getViewportSize() {
  if (window.innerWidth) {
    return {
      width: window.innerWidth,
      height: window.innerHeight,
    };
  } else {
    if (document.compatMode === "BackCompat") {
      // 如果浏览器模式是怪异模式
      return {
        width: document.body.clientWidth,
        height: document.body.clientHeight,
      };
    } else {
      return {
        width: document.doucmentElement.clientWidth,
        height: document.documentELement.clientHeight,
      };
    }
  }
}

整个浏览器文档的宽高

当滚动条滚动到底部时 整个文档的高度等于当前可视窗口高度+滚动高度

function getScrollSize() {
  if (document.body.scrollWidth) {
    return {
      width: document.body.scrollWidth,
      height: document.body.scrollHeight,
    };
  } else {
    return {
      width: document.documentElement.scrollWidth,
      height: document.documentElement.scrollHeight,
    };
  }
}

盒子距离父级边的距离或者距浏览器边的距离

offsetTop:如果父亲有定位则是距父亲的距离如果没有则一直往上找直到找到整个文档的边

封装一个方法找到指定元素到 document 边的距离

// 递归
function getElemDocPosition(el, resultObj = { left: 0, top: 0 }) {
  let parent = el.offsetParent,
    left = el.offsetLeft,
    top = el.offsetTop;

  if (parent) {
    resultObj.left += left;
    resultObj.top += top;
    return getElemDocPosition(parent, resultObj);
  } else {
    return resultObj;
  }
}
//循环
function getElemDocPosition(el) {
  let parent = el.offsetParent,
    offsetLeft = el.offsetLeft,
    offsetTop = el.offsetTop;

  while (parent) {
    offsetLeft += parent.offsetLeft;
    offsetTop += parent.offsetTop;
    parent = parent.offsetParent;
  }
  return {
    left: offsetLeft,
    top: offsetTop,
  };
}

操作滚动条

// 滚动到哪里
window.scroll(x, y);
window.srcollTo(x, y);

// 在当前基础上滚动 x ,y
window.scrollBy(x, y);