当在 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. 中控考勤仪IFace302多线程操作时无法订阅事件

    场景: 在各办事点安装中控考勤仪Iface302,各办事点的工作人员上下班报到时使用指纹或面纹进行自动登记,验证成功后将与服务吕进行通讯记录相关的考勤信息. 条件限制: 由于Iface302设备不支持 ...

  2. 记一次ORACLE的UNDO表空间爆满分析过程

    这篇文章是记录一次ORACLE数据库UNDO表空间爆满的分析过程,主要整理.梳理了同事分析的思路.具体过程如下所示: 早上收到一数据库服务器的UNDO表空间的告警邮件,最早一封是7:55发出的(监控作 ...

  3. mysql5.6主从参数详解

    mysql5.6的主从相当的不错,增加了不少参数,提升了主从同步的安全和效率,以下是mysql5.6主从参数详解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  4. Ubuntu下安装Pyenv不成功,求指教

    虚拟机:VMware12.0 操作系统:Ubuntu16.04 LTS (新安装系统) 已经按照网上的步骤: 1.安装git: $sudo apt-get install git 2.安装依赖包: $ ...

  5. 工作中常用的Linux命令:ipcs/ipcrm命令

    本文链接:http://www.cnblogs.com/MartinChentf/p/6057100.html (转载请注明出处) ipcs 1. 命令格式 ipcs [resource-option ...

  6. PHP Redis

    <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); class Myredis { //redis所 ...

  7. Django初体验(一):自定义表单提交

    注:本人使用的Django1.8.3版本进行测试 除了使用Django内置表单,有时往往我们需要自定义表单.对于自定义表单Post方式提交往往会带来由CSRF(跨站请求伪造)产生的错误"CS ...

  8. git 学习使用总结一(本地操作)

    通过几天的学习,熟悉了 git 的一些常用命令,要用熟练和操作更复杂的功能还必须继续学习.不过 git 作为工具,它是用来提高我们的工作效率的工具,系统的学习之后可以暂且放放,等到以后实际项目中用到了 ...

  9. 彻底解决mysql中文乱码的办法,修改mysql解压缩版(免安装版或zip版)字符编码

    MySQL会出现中文乱码的原因不外乎下列几点:1.server本身设定问题,例如server字符编码还停留在latin12.table的语系设定问题(包含character与collation)3.客 ...

  10. Application中的路径

    前提条件 项目工程目录:E:/Work/cosmosbox/cb-client/ 我电脑当前的用户名:qingqing PersistentDataPath Application.persisten ...