当前位置: 首页 > 编程日记 > 正文

HTML中常见的各种位置距离以及dom中的坐标讨论

最近在学习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:同理 描述元素外尺寸高度,是指 元素内容高度+内边距高度(上下两个)+边框(上下两个),不包括外边距和滚动条部分。

下面我们看一下一段代码

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

<script type="text/javascript">var div = document.getElementById('divChild');var offsetHeight = div.offsetHeight;var offsetWidth = div.offsetWidth;div.innerHTML += 'offsetHeight: ' + offsetHeight + '<br />';div.innerHTML += 'offsetWidth: ' + offsetWidth + '<br />';var offsetLeft = div.offsetLeft;var offsetTop = div.offsetTop;div.innerHTML += 'offsetLeft: ' + offsetLeft + '<br />';div.innerHTML += 'offsetTop: ' + offsetTop + '<br />';var offsetParent = div.offsetParent;div.innerHTML += 'offsetParent: ' + offsetParent.id + '<br />';</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:滚动条左边卷去的宽度

好现在我们 看一段代码

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

<script type="text/javascript">var divParent= document.getElementById("divParent");var scrollwidth = divParent.scrollWidth;var scrollheight = divParent.scrollHeight;var scrolltop = divParent.scrollTop;var scrollleft = divParent.scrollLeft;divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';
</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事件

<script type="text/javascript">var divParent = document.getElementById("divParent");divParent.onscroll = function () {divChild.innerHTML = "";var scrollwidth = divParent.scrollWidth;var scrollheight = divParent.scrollHeight;var scrolltop = divParent.scrollTop;var scrollleft = divParent.scrollLeft;divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';divChild.innerHTML += 'scrolltop: ' + scrolltop + '<br />';divChild.innerHTML += 'scrollleft: ' + scrollleft + '<br />';}
</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">

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

现在我们来测试一下

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

<script type="text/javascript">var divParent = document.getElementsByTagName("body")[0];divParent.onscroll = function () {divChild.innerHTML = "";divChild.style.top = window.pageYOffset + "px";var scrollwidth = divParent.scrollWidth;var scrollheight = divParent.scrollHeight;var scrolltop = divParent.scrollTop;var scrollleft = divParent.scrollLeft;var pagexoffset = window.pageXOffset;var pageyoffset = window.pageYOffset;var documentelementtop = document.documentElement.scrollTop;var documentelementleft = document.documentElement.scrollLeft;var bodyscrolltop = document.body.scrollTop;var bodyscrollleft = document.body.scrollLeft;divChild.innerHTML += 'clientWidth: ' + scrollwidth + '<br />';divChild.innerHTML += 'clientHeight: ' + scrollheight + '<br />';divChild.innerHTML += 'scrolltop: ' + scrolltop + '<br />';divChild.innerHTML += 'scrollleft: ' + scrollleft + '<br />';divChild.innerHTML += 'pagexoffset: ' + pagexoffset + '<br />';divChild.innerHTML += 'pageyoffset: ' + pageyoffset + '<br />';divChild.innerHTML += 'documentelementtop: ' + documentelementtop + '<br />';divChild.innerHTML += 'documentelementleft: ' + documentelementleft + '<br />';divChild.innerHTML += 'bodyscrolltop: ' + bodyscrolltop + '<br />';divChild.innerHTML += 'bodyscrollleft: ' + bodyscrollleft + '<br />';}
</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所返回的坐标包含元素的内边距和边框,不包含外边距。兼容性很好,非常好用。

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

得到滚动条值

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

转载于:https://www.cnblogs.com/liuyuqing/p/4520470.html

相关文章:

快速掌握Python的捷径-Python基础前传(1)

文&#xff1a; jacky(朱元禄) 开文序 最近看新闻&#xff0c;发现高考都考Python了&#xff0c;随着人工智能的火热&#xff0c;学数据科学的人越来越多了&#xff01;但对于数据行业本身来说&#xff0c;现象级的火热&#xff0c;这并不是什么好事。 方丈高楼平地起&#xf…

jsp实现日历

在JSP程序中使用各种脚本元素和标签实现具体的功能 <%--Created by IntelliJ IDEA.User: asusDate: 2020/2/25Time: 21:39To change this template use File | Settings | File Templates. --%> <% page contentType"text/html;charsetUTF-8" language&quo…

小胖妞洗发水广告

觉得自己的博客可能太严肃了&#xff0c;都是技术文章&#xff0c;书评&#xff0c;鸡汤呀&#xff0c;来点稍微轻松点。虽然自己都不敢直视一年前的小胖妞跳的舞蹈&#xff0c;不过现在更胖。 权且娱乐下&#xff0c;也当留个纪念~ http://v.youku.com/v_show/id_228708395.ht…

Yii2.0 RESTful API 之版本控制

Yii2.0 RESTful API 之版本控制 之前我写过两篇关于 Yii2.0 RESTful API 如何搭建&#xff0c;以及 认证 等处理&#xff0c;但是没有涉及到版本管理&#xff0c;今天就来谈谈版本管理如何实现。 索性就从头开始一步一步搭建吧&#xff0c;但是关于一些概念以及使用本篇就不一一…

ssl 和 https

SSL (Secure Socket Layer) 为Netscape所研发&#xff0c;用以保障在Internet上数据传输之安全&#xff0c;利用数据加密(Encryption)技术&#xff0c;可确保数据在网络上之传输过程中不会被截取及窃听。目前一般通用之规格为40 bit之安全标准&#xff0c;美国则已推出128 bit之…

jsp实现日历(二)

<% page contentType"text/html;charsetUTF-8" language"java" %> <% page import"java.util.Calendar" %> <html> <head><title>日历</title><style>table{border: none;}table caption{color: red;…

Java微信公众平台开发(十)--微信自定义菜单的创建实现

转自&#xff1a;http://www.cuiyongzhi.com/post/48.html 自定义菜单这个功能在我们普通的编辑模式下是可以直接在后台编辑的&#xff0c;但是一旦我们进入开发模式之后我们的自定义菜单就需要自己用代码实现&#xff0c;所以对于刚开始接触的人来说可能存在一定的疑惑&#x…

【经典算法】快速排序

与归并排序一样&#xff0c;快速排序使用也使用了分治的思想。下面是对一个典型的子数组A[p,...,r]进行快速排序的三步分治过程&#xff1a; 分解&#xff1a;数组A[p,...,r]被划分成两个&#xff08;可能为空&#xff09;子数组A[P,...,q-1]和A[q1,...,r]&#xff0c;使得A[p,…

.Net 中如何测试静态方法

大部分Mokc框架是不支持mock静态方法的&#xff0c;那我们如何测试静态方法呢&#xff1f; 下面这个类包含了一个静态方法&#xff1a; public class MyHelper {public static string GetHelp(){return "This is help";} } 这个类调用了上面的Helper类中的静态方法 p…

计组--习题--总线

计算机使用总线结构的主要优点是便于实现积木化&#xff0c;缺点是______ A、 地址信息、数据信息和控制信息不能同时出现 B、 地址信息与数据信息不能同时出现 C、 两种信息源的代码在总线中不能同时传送 这里是引用 总线中地址线的作用是_______ A、 只用于选择存储器单元 B…

dispatch_queue_create(com.biostime.xxx, DISPATCH_QUEUE_SERIAL)的陷阱

代码 for(int i 0;i<10;i) { NSLog("i%d",i); dispatch_queue_t mySerialQueue dispatch_queue_create("com.biostime.xxx", DISPATCH_QUEUE_SERIAL); __block int d i; dispatch_async(mySerialQueue, ^{ …

详解Oracle安装与配置.

标签&#xff1a;Oracle 安装 配置 原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://enetq.blog.51cto.com/479739/316532 一.Oracle 简介. Oracle oracle是殷墟&#xff08;Yin Xu&#…

今天起,在广东可以用百度App一键报警!

今天&#xff0c;百度联合广东省公安厅上线了一款智能小程序&#xff1a;只要打开你手机里的百度 App 就能用了 &#xff01;在110实际接警的过程中&#xff0c;经常会遇到电话并不能很好地表达发生事件的地点等信息的情况&#xff0c;会耽误救援时间。因此&#xff0c;“广东1…

Spring 注解

1. Configuration Configuration用于定义配置类&#xff0c;可替换xml配置文件&#xff0c;被注解的类内部包含有一个或多个被Bean注解的方法&#xff0c;这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描&#xff0c;并用…

Junit的安装与使用

一、简介&#xff1a; JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立&#xff0c;逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个。 JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。Junit测试是程…

安装 ssh 的公开密匙到 iPhone 上

1). 在Mac的终端上产生密匙 ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/xxxx/.ssh/id_rsa): Created directory /home/xxxx/.ssh. Enter passphrase (empty for no passphrase): xxx Enter same passphrase again…

浏览器关闭事件处理

//有确认退出var msg_unload"您的文章内容还没有进行保存&#xff01;";var unloadConfirm {};unloadConfirm.SetConfirmMsg function(confirmMsg){ window.onBeforeUnload function(event) { event event || window.event; event.returnval…

spring注解--@Bean

Configuration public class KnightConfig {Beanpublic Knight knight(){return new BraveKnight(quest () );}}spring的Bean注解用于告诉方法&#xff0c;产生一个Bean对象&#xff0c;然后把这个Bean对象交给spring管理。注意&#xff1a;产生这个Bean对象的方法Spring只会调…

如何用 Windows Live Writer 和 Word 2013 分别发表博客到Cnblog 和CSDN

ps CSDN 老是505错误&#xff0c;放弃了 为什么会写这篇 最近写博客在 Cnblog 上面写博客&#xff0c; 发现图片不能复制了直接粘贴上&#xff0c;这对于把博客当随手笔记的人来说无疑非常痛苦。求助于博客园&#xff0c;他们让我用 Windows Live Writer 试试。我查了下大家推荐…

JavaScript 事件冒泡简介及应用(转)

http://www.jb51.net/article/21801.htm 一、什么是事件冒泡在一个对象上触发某类事件&#xff08;比如单击onclick事件&#xff09;&#xff0c;如果此对象定义了此事件的处理程序&#xff0c;那么此事件就会调用这个处理程序&#xff0c;如果没有定义此事件处理程序或者事件返…

不改文件名的情况下上传突破

方法不错&#xff0c;首先就是不强制改上传文件名。还有就是上传目录没有执行的权限。 然后用这方法貌似就可以上传到上级可写目录了。 比如抓这是抓的上传数据包: POST /upload/upfile.asp HTTP/1.1Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image…

static interface method calls are not supported at language level 1.6

报错解决&#xff08;导入项目时&#xff09; 点击那个红色的小灯泡 下面的那行&#xff1a; set language to … 等待 即可

Objetive-C +load方法研究

load方法的执行时机Objetive-C 的runtime会在一个类的所有方法加载到内存中时调用这个类的load() 方法&#xff0c;因为每个类的方法只是加载一次&#xff0c;所以每个load&#xff08;&#xff09;方法只调用一次。加载一个类的方法会在一个进程启动开始的时候&#xff0c;这个…

HDU3434数学题

纯粹的数学题&#xff0c;题目的意思是给你一组序列&#xff0c;让你能同时改变它的一个子序列&#xff0c;让其子序列的值增加1&#xff0c;或者减少1. 思路的话&#xff0c;就是找其中的数学规律&#xff0c;给你的序列例如是&#xff1a;3,5,1,4,7。先求出其序列的正差和5-3…

python的基本知识点

一.数据类型 1.整数2.浮点数3.字符串4.布尔值:True/False5.空值:None 二.变量 变量名必须是大小写英文、数字和_的组合&#xff0c;且不能以数字开头 三.常量 全部大写的变量名表示常量,python没有一种机制保证常量不能被修改.PI 3.14156 四.特殊的地板除 // // 除法只取结果的…

上传代码到git上的分支(协同开发)

任意位置右键单击 git bash,输入命令如下&#xff1a; git config --global user.name "用户名" &#xff08;用户名就是gitlab上的用户名&#xff0c;我的是名字拼音&#xff09;git config --global user.email "邮箱" &#xff08;注册gitlab时的邮箱&…

Android网络编程系列 一 Socket抽象层

在《Android网络编程》系列文章中&#xff0c;前面已经将Java的通信底层大致的描述了&#xff0c;在我们了解了TCP/IP通信族架构及其原理&#xff0c;接下来我们就开始来了解基于tcp/ip协议层的Socket抽象层。本篇文章将会让我们清楚的了解和学会使用Socket。什么是Socket&…

HDFS的shell和API操作

1. HDFS的shell操作 hadoop version //查看版本 hadoop fs -appendToFile src(Linux中的文件) dest(hdfs目录下的文件) //追加 hadoop fs -cat file(hdfs目录下的文件) //查看文件内容 Hadoop fs -tail file(hdfs目录下的文件) //查看文件末尾1kb的数据…

C#中的问号用法

在看一些国外牛人写的C#代码时&#xff0c;总是看到会有Boolean?、DateTime?这样的类型&#xff0c;以为是一些新的类型&#xff08;该类型变量有一些新的属性和方法&#xff09;&#xff0c;后来经过查找相关的资料&#xff0c;发现原来另有微妙。以下是MSDN中对这个问号的解…

L1-006 连续因子

题目&#xff1a; 一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3567&#xff0c;其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N&#xff0c;要求编写程序求出最长连续因子的个数&#xff0c;并输出最小的连续因子序列。 输入格式&#xff1a; 输…