当在 Web 浏览器中查看 HTML 文档时,DOM 节点被解析,并被渲染成盒模型(如下图),有时我们需要知道一些信息,比如盒模型的大小,盒模型在浏览器中的位置等等,本文我们就来详细了解下元素节点的几何量以及滚动几何量。

获取元素相对于 offsetParent 的 offsetTop 以及 offsetLeft 值


使用 offsetTop 和 offsetLeft 属性,我们可以获取元素节点相对于 offsetParent 的偏移像素量。这些元素节点属性告诉我们某元素上部与左侧边框最外沿到 offsetParent 上部和左侧边框内部的距离,以像素为单位。 offsetParent 的值判定依据为查找离该元素最近的 CSS 定位值不为 static 的祖先元素。如果没有,则 <body> 元素,某些人或称之为“文档”(而不是浏览器视区),即为 offsetParent 值。如果,在查询祖先过程中,找到 <td> <th><table> 元素,且它的定位为 static,则它将成为 offsetParent 的值。

<style>
  body {
    margin: 0;
  }

  #blue {
    width: 100px;
    height: 100px;
    background-color: blue;
    border: 10px solid gray;
    padding: 25px;
    margin: 25px;
  }

  #red {
    width: 50px;
    height: 50px;
    background-color: red;
    border: 10px solid gray;
  }
</style>

<div id='blue'>
  <div id='red'></div>
</div>

<script>
  var myDiv = document.querySelector('#red');

  console.log(myDiv.offsetLeft); // 60
  console.log(myDiv.offsetTop);  // 60
  console.log(myDiv.offsetParent);  // body
</script>

如果将以上代码中的蓝色 div 元素定位改为 absolute,那么将会得到完全不一样的结果,因为蓝色 div 会成为红色 div 的offsetParent。

offsetLeft 和 offsetTop 属性和包含元素有关,包含元素的引用保存在 offsetParent 属性中,而 offsetParent 属性不一定与 parentNode 的值相等。例如,<td> 元素的 offsetParent 是作为其祖先元素的 <table> 元素,因为 table 元素是在 DOM 层次中距离 td 元素最近的一个具有大小的元素。

要想知道某个元素在页面上的偏移量,将这个元素的 offsetLeft 和 offsetTop 与其 offsetParent 的相同属性相加,如此循环直至根元素,就可以得到一个基本准确的值。

function getElementLeft(element) {
  var actualLeft = element.offsetLeft;
  var current = element.offsetParent;

  while (current !== null) {
    actualLeft += current.offsetLeft;
    current = current.offsetParent;
  }

  return actualLeft;
}

function getElementTop(element) {
  var actualTop = element.offsetTop;
  var current = element.offsetParent;

  while (current !== null) {
    actualTop += current.offsetTop;
    current = current.offsetParent;
  }

  return actualTop;
}

对于简单的 CSS 布局的页面,这两函数可以得到非常准确的结果。但是对于利用表格和内嵌框架布局的页面,由于不同浏览器实现这些元素的方式不同,因此得到的值就不太精确了。一般来说,页面中的所有元素都会被包含在几个 div 元素中,而这些 div 元素的 offsetParent 又是 body 元素,所以 getElementLeft() 与 getElementTop() 会返回和 offsetLeft 和 offsetTop 相同的值。

使用 getBoundingClientRect() 获取元素相对于视区的 Top、Right、Buttom 以及 Left 边沿偏移量


使用 getBoundingClientRect() 方法,我们可以获取元素外边沿的位置。元素调用 getBoundingClientRect() 方法后会返回一个对象,该对象包含 top、right、bottom 以及 left 属性。

还是上面的代码:

 <style>
  body {
    margin: 0;
  }

  #blue {
    width: 100px;
    height: 100px;
    background-color: blue;
    border: 10px solid gray;
    padding: 25px;
    margin: 25px;
  }
</style>

<div id='blue'></div>

<script>
  var divEdges = document.querySelector('#blue').getBoundingClientRect();

  console.log(divEdges.top); // 25
  console.log(divEdges.right);  // 195
  console.log(divEdges.bottom);  // 195
  console.log(divEdges.left);  // 25
</script>

元素大小的获取


<style>
  body {
    margin: 0;
  }

  #blue {
    width: 100px;
    height: 50px;
    background-color: blue;
    border: 10px solid gray;
    padding: 25px;
    margin: 25px;
  }
</style>

<div id='blue'></div>

<script>
  var div = document.querySelector('#blue')
    , divEdges = div.getBoundingClientRect();

  // 获取元素大小
  // border + pading + content
  console.log(divEdges.width, divEdges.height); // 170 120

  // 也能取得元素大小
  console.log(div.offsetWidth, div.offsetHeight); // 170 120

  // padding + content 不含 border
  console.log(div.clientWidth, div.clientHeight); // 150 100
</script>

获取滚动几何量


<style>
  * {
    margin: 0;
    padding: 0;
  }

  div {
    width: 100px;
    height: 100px;
    overflow: auto;
  }

  p {
    width: 1000px;
    height: 1000px;
    background-color: red;
  }
</style>

<div><p></p></div>

<script>
  var div = document.querySelector('div');

  // 获取滚动元素的宽和高
  console.log(div.scrollWidth, div.scrollHeight);  // 1000 1000

  // scrollLeft 和 scrollTop 属性都是读写属性
  // 返回可滚动视区中因为滚动而暂时不可见的元素距离左边和上边的像素距离

  div.scrollLeft = 500;
  div.scrollTop = 500;

  console.log(div.scrollLeft, div.scrollTop);  // 500 500
</script>

使用 scrollIntoView() 滚动元素到视区


选取可滚动节点中某一节点后,我们可以使用 scrollIntoView() 方法告诉选取的节点滚动到可视区域。

<style>
  div {
    width: 30px;
    height: 30px;
    overflow: auto;
  }

  p {
    background-color: red;
  }
</style>

<div>
  <content>
    <p>0</p>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
    <p>6</p>
    <p>7</p>
    <p>8</p>
    <p>9</p>
  </content>
</div>

<script>
  document.querySelector('content').children[4].scrollIntoView(true);
</script>

DOM 元素节点几何量与滚动几何量的更多相关文章

  1. JavaScript HTML DOM 元素(节点)

    JavaScript HTML DOM 元素(节点) 创建新的 HTML 元素 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素 ...

  2. JavaScript 要点(十四)HTML DOM 元素(节点)

    A.创建新的 HTML 元素 如需向 HTML DOM 添加新元素,必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id="div1"> ...

  3. 围绕DOM元素节点的增删改查

    HTML 文档中的所有内容都是节点: 整个文档是一个文档节点 document 每个 HTML 元素是元素节点 element HTML 元素内的文本是文本节点 每个 HTML 属性是属性节点 注释是 ...

  4. JavaScript HTML DOM元素节点常用操作接口

    在文档对象模型 (DOM) 中,每个节点都是一个对象.DOM 节点有三个重要的属性 : 1. nodeName : 节点的名称 2. nodeValue :节点的值 3. nodeType :节点的类 ...

  5. 吴裕雄--天生自然 JAVASCRIPT开发学习:HTML DOM 元素 (节点)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. 深入理解DOM节点类型第五篇——元素节点Element

    × 目录 [1]特征 [2]子节点 [3]特性操作[4]attributes 前面的话 元素节点Element非常常用,是DOM文档树的主要节点:元素节点是html标签元素的DOM化结果.元素节点主要 ...

  7. DOM中元素节点、属性节点、文本节点

    DOM中有12中节点,但最常用到的是元素节点,属性节点,文本节点. 元素节点的节点类型(nodeType)是1: 属性节点的节点类型(nodeType)是2: 文本节点的节点类型(nodeType)是 ...

  8. DOM中元素节点、属性节点、文本节点的理解

    DOM中元素节点.属性节点.文本节点的理解 节点信息 每个节点都拥有包含着关于节点某些信息的属性.这些属性是:nodeName(节点名称) nodeValue(节点值) nodeType(节点类型)  ...

  9. JavaScript HTML DOM 元素(节点)

    添加和删除节点(HTML 元素) 创建新的 HTML 元素  如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. 例如:这段代码创建新的 < ...

随机推荐

  1. CentOS6.5 oracle 11g R2 开机自动启动

    1.root 用户下修改ORATAB(将N该为Y): [root@ora11gr2 ~]# vim /etc/oratab mytest:/oracle/product//db_1:Y 2.oracl ...

  2. mongoDB怎样拷贝一个collection从一个数据库到另一个在同一个主机上

    new_database是目的数据库 db.<collection_name>.find().forEach(function(d){ db.getSiblingDB('<new_d ...

  3. iOS Build Active Architecture Only 属性的理解(及 not found for architecture i386 的解决方案)

    最近做项目过程遇到一个问题: 涉及到这个属性:Build Active Architecture Only Yes .No的区别: 设置为yes,是只编译当前的architecture版本,是为了编译 ...

  4. android 读取根目录下的文件或文件夹

    @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setC ...

  5. Centos 内存占满 释放内存

    free -m 查看内存使用情况 top,然后按下shift+m,按内存占用百分比排序 centos 为了提高效率,把部分使用过的文件缓存到了内存里.如果不需要这样的文件性能,那就可以释放. 如下两个 ...

  6. shell流程控制

    if语句 判断条件用[]包裹起来 if [ $a > $b ] then echo ‘a > b’ elif [ $a < $b ] then echo ‘a < b’ els ...

  7. z-index堆叠规则

    一.z-index z-index用来控制元素重叠时堆叠顺序. 适用于:已经定位的元素(即position:relative/absolute/fixed). 一般理解就是数值越高越靠上,好像很简单, ...

  8. 使用dedecms中常见错误提示及解决办法(一)

    在使用 dedecms 做网站时,常常会遇到一些棘手的问题,比如:页面图片不显示(src 的地址不对)等等. 1. 更新网站时错误 问题:Call to a member function GetIn ...

  9. Codeforces Round #286 Div.1 A Mr. Kitayuta, the Treasure Hunter --DP

    题意:0~30000有30001个地方,每个地方有一个或多个金币,第一步走到了d,步长为d,以后走的步长可以是上次步长+1,-1或不变,走到某个地方可以收集那个地方的财富,现在问走出去(>300 ...

  10. POJ1270 Following Orders[拓扑排序所有方案 Kahn]

    Following Orders Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4885   Accepted: 1973 ...