最近在学习JavaScript,特意买了一本犀牛角书来看看,尼玛一千多页,看的我头昏脑涨,翻到DOM这章节,突然记起平常在使用DOM时,碰到了好多的这个dom里面的各种宽度,高度,特意在此写一写,写的不好或者写错了,欢迎各位指正。好了废话不多说,开始进入主题。

这篇文章主要讨论两点:

一、DOM中各种宽度、高度

二、DOM中的坐标系

下面我们看看DOM中都有一些什么宽度、高度。

常见的

offsetWidth

clientWidth

scrollWidth

offsetHeight

clientHeight

scrollHeight

offsetLeft

clientLeft

scrollLeft

offsetTop

clientTop

scrollTop

下面我们来一一讲解

offsetleft:元素的边框的外边缘距离与已定位的父容器(offsetparent)的左边距离(不包括元素的边框和父容器的边框)。

offsettop:同理是指元素的边框的外边缘距离与已定位的父容器(offsetparent)的上边距离(不包括元素的边框和父容器的边框)。

offsetwidth:描述元素外尺寸宽度,是指 元素内容宽度+内边距宽度(左右两个)+边框(左右两个),不包括外边距和滚动条部分。

offsetheight:同理 描述元素外尺寸高度,是指 元素内容高度+内边距高度(上下两个)+边框(上下两个),不包括外边距和滚动条部分。

下面我们看一下一段代码

  1. <div id="divParent" style="padding: 8px; background-color:#CCC; position: relative;">
  2. <div id="divChild" style="background-color:#C00; margin: 30px; padding: 10px;
  3. height: 200px; width: 200px; border: solid 10px #0000CC;">
  4. </div>
  5. </div>

  

  1. <script type="text/javascript">
  2. var div = document.getElementById('divChild');
  3. var offsetHeight = div.offsetHeight;
  4. var offsetWidth = div.offsetWidth;
  5. div.innerHTML += 'offsetHeight: ' + offsetHeight + '<br />';
  6. div.innerHTML += 'offsetWidth: ' + offsetWidth + '<br />';
  7.  
  8. var offsetLeft = div.offsetLeft;
  9. var offsetTop = div.offsetTop;
  10. div.innerHTML += 'offsetLeft: ' + offsetLeft + '<br />';
  11. div.innerHTML += 'offsetTop: ' + offsetTop + '<br />';
  12.  
  13. var offsetParent = div.offsetParent;
  14. div.innerHTML += 'offsetParent: ' + offsetParent.id + '<br />';
  15.  
  16. </script>

  看一下效果

现在我们按照上面的说明比对一下

offsetleft:(div id=divChild)margin 30(外边距--距离父容器左边30px)+ (div id=divParent) padding 8 (父容器的内边左距离 8px)=38

offsettop:margin 30+ padding 8=38;

offsetwidth:本身的宽度(200)+内边距左右(10*2)+边框左右(10*2)=240;

offsetheight:同理;

下面我们来看下第二组

clientleft:元素的内边距的外边缘和边框的外边缘的距离,实际就是边框的左边框宽度

clienttop:同理边框的上边框的宽度

clientwidth:用于描述元素内尺寸宽度,是指 元素内容+内边距 大小,不包括边框、外边距、滚动条部分

clientheight:同理 用于描述元素内尺寸高度,是指 元素内容+内边距 大小,不包括边框、外边距、滚动条部分

我们只更改一下JavaScript的代码,DOM不改变

chrome 41 版本

clientleft:左边框宽度 10;

clienttop:10;

clientwidth:本身宽度(200)+内边距(10*2)=220;

clientheight:本身高度(200)+内边距(10*2)=220;

正确,下面我们来看下嵌套的div盒子模型图

div id=divChild

div id=divParent

符合我们上面所说的,下面我们看下

scrollwidth:内容区域尺寸加上内边距加上溢出尺寸,当内容正好和内容区域匹配没有溢出时,这些属性与clientWidth和clientHeight相等

scrollheight:同上

scrolltop:滚动条上方卷去的高度

scrollleft:滚动条左边卷去的宽度

好现在我们 看一段代码

  1. <div id="divParent" style="padding: 8px; background-color: #aaa; height:200px; width:300px; overflow:auto" >
  2. <div id="divChild" style="background-color: #0f0;height: 400px; width: 500px; border: solid 10px #f00;">
  3. </div>
  4. </div>

  

  1. <script type="text/javascript">
  2. var divParent= document.getElementById("divParent");
  3. var scrollwidth = divParent.scrollWidth;
  4. var scrollheight = divParent.scrollHeight;
  5. var scrolltop = divParent.scrollTop;
  6. var scrollleft = divParent.scrollLeft;
  7. divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';
  8. divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';
  9. </script>

  现在我们要计算id=divParent的scrollheight,和scrollwidth。根据上面的说明,我们知道应该按照下面的公式计算

scrollwidth=子div的宽度(500)+子div的边框(10*2)+父容器的padding(8)=528

scrollwidth=子div的高度(400)+子div的边框(10*2)+父容器的padding(8)=428

现在我们验证一下

我们发现在 ie8及之后的 浏览器 为428,firework 也为428;而 chrome Safari opera 都为436;

因此我们可以猜测 chrome和 Safari、opera 在计算 scrollheight时,加上了 父容器的下 padding(8) 即 428+8=436;

下面我们在看看scrolltop和scrollleft的值怎么样

测试了好几个浏览器都发现其值为零,这是肿么回事,尼玛,万能的百度、谷歌,原来我的滚动条一直在顶端和左端,没有卷走高度,我们修改一下代码,将显示内容绑定到onscroll事件

  1. <script type="text/javascript">
  2. var divParent = document.getElementById("divParent");
  3. divParent.onscroll = function () {
  4. divChild.innerHTML = "";
  5. var scrollwidth = divParent.scrollWidth;
  6. var scrollheight = divParent.scrollHeight;
  7. var scrolltop = divParent.scrollTop;
  8. var scrollleft = divParent.scrollLeft;
  9. divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';
  10. divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';
  11. divChild.innerHTML += 'scrolltop: ' + scrolltop + '<br />';
  12. divChild.innerHTML += 'scrollleft: ' + scrollleft + '<br />';
  13. }
  14. </script>

终于发现值改变了

另外我们在使用window的pageXOffset,pageYOffset求浏览器滚动条的卷去的高度和左边的距离,同时scrolltop、scrollleft也可以,但是要注意

当我们网页页面申明了dtd(文档模型时), 使用document.documentElement.scrolltop scrollleft获取浏览器卷去上面的距离,左边卷去的距离。

如果网页没有申明dtd(怪异模式时),使用document.body.scrolltop  scrollleft获取上边卷去的距离、左边卷去的距离。

什么是dtd,这里简单解释一下,我们使用vs新建页面时,在每个网页的顶端 一般会有这样的申明

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

这里申明了 网页的模型 ,再浏览器加载网页时,会选择对应的模式渲染网页。

现在我们来测试一下

  1. <div id="divParent" style="padding: 8px; background-color: #aaa; height:1200px; width:300px; overflow:auto" >
  2. <div id="divChild" style="background-color: #0f0;height: 400px; width: 500px; border: solid 10px #f00; position:absolute">
  3. </div>
  4. </div>

  

  1. <script type="text/javascript">
  2. var divParent = document.getElementsByTagName("body")[0];
  3. divParent.onscroll = function () {
  4. divChild.innerHTML = "";
  5. divChild.style.top = window.pageYOffset + "px";
  6. var scrollwidth = divParent.scrollWidth;
  7. var scrollheight = divParent.scrollHeight;
  8. var scrolltop = divParent.scrollTop;
  9. var scrollleft = divParent.scrollLeft;
  10. var pagexoffset = window.pageXOffset;
  11. var pageyoffset = window.pageYOffset;
  12. var documentelementtop = document.documentElement.scrollTop;
  13. var documentelementleft = document.documentElement.scrollLeft;
  14. var bodyscrolltop = document.body.scrollTop;
  15. var bodyscrollleft = document.body.scrollLeft;
  16. divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';
  17. divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';
  18. divChild.innerHTML += 'scrolltop: ' + scrolltop + '<br />';
  19. divChild.innerHTML += 'scrollleft: ' + scrollleft + '<br />';
  20. divChild.innerHTML += 'pagexoffset: ' + pagexoffset + '<br />';
  21. divChild.innerHTML += 'pageyoffset: ' + pageyoffset + '<br />';
  22. divChild.innerHTML += 'documentelementtop: ' + documentelementtop + '<br />';
  23. divChild.innerHTML += 'documentelementleft: ' + documentelementleft + '<br />';
  24. divChild.innerHTML += 'bodyscrolltop: ' + bodyscrolltop + '<br />';
  25. divChild.innerHTML += 'bodyscrollleft: ' + bodyscrollleft + '<br />';
  26. }
  27. </script>

  chrome测试结果,我们发现 pagexoffset  document.body.scrolltop 可以用,但是注意 我当前的申明了 html5的<!DOCTYPE html>,说明document.documentelement可以用的。

在来看看 firefox的测试效果,同样申明了文档类型 这里 document.documentelement可以用,尼玛真是日了狗了,难道是html5 文档类型特殊一点,我们测试一下其他类型的文档类型

但是发现结果和上面的一样,好吧,不管上面那些了,下面总结如何兼容scrolltop如果是求 scrolltop 可以取 body.scrolltop 和documen.documentelement.scrolltop的max值,这样不管如何总能取一个正确的值。

我们在上面的章节知道了如何取scrolltop值,接下来我们就来介绍一下dom中的窗口坐标和文档坐标,

窗口坐标:当前显示可见的页面的左上角的坐标(如果出现滚动条,且滚动条发生滚动,则 窗口坐标和文档坐标不一致,因为窗口坐标只显示当前显示的页面的部分,而文档可能因为滚动条的缘故遮盖了);

文档坐标:垂直滚动条在最上方,没有滚动,水平滚动条在最左边,没有滚动时,时的左上方的坐标

如果没有滚动条时,窗口坐标和文档坐标一致。

那如何在窗口坐标和文档坐标之间进行转换呢,这里我们就要用到上面的滚动条卷去的高度和坐标的距离,假设,有一个元素在文档中的y坐标(即垂直方向的)是200px;但是我们通过滚动条向下滚动了75px,那么当前的窗口坐标就为125px;

因此如果scrolltop的值大于0的话  我们窗口的坐标y=文档的坐标y-scrolltop,

同时视口坐标也有对应的方法可以使用

可以通过调用元素getBoundingClientRect方法。方法返回一个有left、right、top、bottom属性的对象,分别表示元素四个位置的相对于视口的坐标。getBoundingClientRect所返回的坐标包含元素的内边距和边框,不包含外边距。兼容性很好,非常好用。

下面贴一段犀牛角上的代码

得到滚动条值

  1. function getScrollOffsets(w) {
  2. var w = w || window;
    //除ie8及更早版本,其他浏览器都能使用
  3. if (w.pageXoffset != null) {
  4. return { x: w.pageXoffset, y: pageYoffset };
  5. }
    //标注模式ie(或任何浏览器)
  6. var d = w.document;
  7. if (document.compatMode == "CSS1Compat")
  8. return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
    //怪异模式下(没有申明dtd)
  9. return { x: d.body.scrollLeft, y: d.body.scrollTop };
  10. }
    通过使用这个函数发现也不是很兼容 chrome中一直是0,说明即使在标准模型中,,即申明了dtd chrome 也不能取documentElement.scrollLeft值。opera也同样不能取值,firefox能取值。因此早平常的使用中我还是 使用math.max(docuemnt.body.scrolltop,docuemnt.documentelement.scrolltop)来使用。
    好了今天的就介绍到这里。如有错误,欢迎各位博客园朋友指正

HTML中常见的各种位置距离以及dom中的坐标讨论的更多相关文章

  1. js和jq中常见的各种位置距离之offsetLeft和position().left的区别(四)

    offsetLeft:元素的边框的外边缘距离与已定位的父容器(offsetparent)的左边距离(不包括元素的边框和父容器的边框).position().left:使用position().left ...

  2. js和jq中常见的各种位置距离之offset和offset()的区别(三)

    offsetLeft:元素的边框的外边缘距离与已定位的父容器(offsetparent)的左边距离(不包括元素的边框和父容器的边框). offset().left:返回的是相对于当前文档的坐标,使用o ...

  3. js和jq中常见的各种位置距离之offset()和position()的区别(二)

    offset()返回的是相对于当前文档的坐标,position()返回的是相对于其定位的祖辈元素的坐标. 使用position()方法时事实上是把该元素当绝对定位来处理,获取的是该元素相当于最近的一个 ...

  4. js和jq中常见的各种位置距离之offsetLeft/clientLeft/scrollLeft (一)

    offsetLeft offsetTop offsetWidth offsetHeight offsetLeft:元素的边框的外边缘距离与已定位的父容器(offsetparent)的左边距离(不包括元 ...

  5. Android 中常见控件的介绍和使用

    1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...

  6. Spring中常见的bean创建异常

    Spring中常见的bean创建异常 1. 概述     本次我们将讨论在spring中BeanFactory创建bean实例时经常遇到的异常 org.springframework.beans.fa ...

  7. 2、Java应用中常见的JDBC连接字符串(SQLite、MySQL、Oracle、Sybase、SQLServer、DB2)

    2.Java应用中常见的JDBC连接字符串 Java应用中连接数据库是不可或缺的,于是便整理一些可能用到的JDBC的jar包及其相匹配的URL,以备日后查阅. 1)SQLite Class.forNa ...

  8. C程序中常见的内存操作错误

    对C/C++程序员来说,管理和使用虚拟存储器可能是个困难的, 容易出错的任务.与存储器有关的错误属于那些令人惊恐的错误, 因为它们在时间和空间上, 经常是在距错误源一段距离之后才表现出来. 将错误的数 ...

  9. 【转】《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误

    原文地址:http://blog.csdn.net/slvher/article/details/9150597 对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构 ...

随机推荐

  1. EasyUI篇のDataGrid

    HTML: <table id="dg"></table> 或者 <div id="dg"></div> JS: ...

  2. BZOJ 1024 生日快乐

    Description windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕.现在包括windy,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋 ...

  3. 舍伍德(Sherwood)算法学习笔记

    一.概念引入 设A是一个确定性算法,当它的输入实例为x时所需的计算时间记为tA(x).设Xn是算法A的输入规模为n的实例的全体,则当问题的输入规模为n时,算法A所需的平均时间为.这显然不能排除存在x∈ ...

  4. 【Java】在Eclipse中使用JUnit4进行单元测试(初级篇)

    本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能 ...

  5. ios入门之c语言篇——基本函数——1——随机数生成

    1.随机数函数 参数返回值解析: 参数: a:int,数字范围最小值: b:int,数字范围最大值: 返回值: 1:闰年: 0:非闰年: 备注: a-b的绝对值不能超过int的最大值(65535); ...

  6. C Static Inline函数

    Inline函数 程序执行时,处理器从Memory中读取代码执行.当程序中调用一个函数时,程序跳到存储器中保存函数的位置开始读取代码执行,执行完后再返回. 为了提高速度,C定义了inline函数,告诉 ...

  7. Linux配置支持高并发TCP连接(socket最大连接数)

    Linux配置支持高并发TCP连接(socket最大连接数) Linux配置支持高并发TCP连接(socket最大连接数)及优化内核参数 2011-08-09 15:20:58|  分类:LNMP&a ...

  8. Linux企业级开发技术(5)——libevent企业级开发之简介

    Libevent是一个用于编写高速可移植非阻塞IO应用的库,它的设计目标是: 可移植性:使用libevent编写的程序应该可以在libevent支持的所有平台上工作.即使没有好的方式进行非阻塞IO,l ...

  9. 模板:强连通分量&2-sat

    void Tarjan(int x){ low[x]=ID[x]=++tot; st[++top]=x;Inst[x]=true; for(int i=fir[x];i;i=nxt[i]) if(!I ...

  10. Delphi WEB APP DEBUGGER是如何使用的

      WEB APP DEBUGGER是怎么使用的最近在写一个WEBSERVICE的程序,怎么设置使用,WEBAPPDEBUGGER这个工具呢,让别人在调用我的WEBSERVICE的时候我可以调试的?谢 ...