当在 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. junit 使用

    今天用jsoup做了一个‘网络抓取实例’,然而,当作者把junit-4.11.jar 导入项目中,在类中方法上加入@Test,运行时却报错,报错代码如下: java.lang.NoClassDefFo ...

  2. Nginx 多站点配置

    最近学习和练习的时候,为Laravel应用程序添加了好几个站点,有些程序删除之后站点却还留着,这让强迫症感到非常难受,上次解决了这个问题之后并没有记录一下,于是导致今天又花了很多时间折腾,所以特地来写 ...

  3. 【Linux】将Oracle安装目录从根目录下迁移到逻辑卷

    [Linux]将Oracle安装目录从根目录下迁移到逻辑卷 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到 ...

  4. c# 设置winform程序为默认打开软件 在运行中获取参数

    1.右键→打开方式→选择默认程序→选择winform程序 2.修改Program.cs 判断注册的事件是否存在,如果不存在则运行实例,并把参数传入MainForm里,如果存在则把参数写到txt文件中, ...

  5. ARM体系结构

    工作模式_ufisaus USR(User) :正常程序的执行状态 FIQ(Fast interrupt) :用于高速数据传输和通道处理 IRQ(Interrupt) :通常的中断处理 SVC(Sup ...

  6. webstorm 10 配置

    小弟以前都是用sublime,sublime是一款轻量级的文本编辑器.但是现在要隆重介绍的前端开发工具webstorm,为什么说它是前端开发工具,而不是前端开发编辑器呢?它具备的功能,不只只是编辑器这 ...

  7. Equinox P2的学习

    product.configuration 点击“Add按钮”并添加以下插件: org.eclipse.equinox.p2.ui org.eclipse.equinox.p2.ui.sdk org. ...

  8. [转]ASP.NET Web API(三):安全验证之使用摘要认证(digest authentication)

    本文转自:http://www.cnblogs.com/parry/p/ASPNET_MVC_Web_API_digest_authentication.html 在前一篇文章中,主要讨论了使用HTT ...

  9. Struts2工作原理

    Struts2工作原理 Struts2请求响应流程: 在struts2的应用中,从用户请求到服务器返回相应响应给用户端的过程中,包含了许多组件如:Controller.ActionProxy.Acti ...

  10. 32-bit ALU [Verilog]

    Based on MIPS Instruction Structure Main Module module Alu( input [31:0] a, // operand 1 input [31:0 ...