# javascript快速入门19--定位
## 元素尺寸
获取元素尺寸可以使用下面几种方式
* 元素的style属性width,height,但这些属性往往返回空值,因为它们只能返回使用行内style属性定义在元素上的样式
* 元素的currentStyle属性width,height(IE),getComputedStyle(obj,null)返回对象的width,height,这样可以获取元素的实际CSS定义的宽度和高度,但当元素没有使用CSS定义外观时,虽然元素仍然有大小(只要其中有字符或其它元素),这些属性的返回值是不确定的,如IE返回auto,而火狐则返回一个看似理想的值。
* 对象的clientWidth和clientHeight属性给出元素的可视部分的宽度和高度,当有滚动条时,只返回可见区域大小,对于块级元素,将返回元素的所设置的宽度和高度加上填充(padding),这一点几乎所有浏览器都达成一致.但当块级元素并没有设置宽和高以及填充时,就出现不同了,谷歌浏览器和火狐浏览器的报告一致,IE报告都为0,而Opera则有所偏差.再将这两个属性应用到行内元素上,IE和火狐都报告为0,谷歌报告了一个看似理想的数字,而Opera竟会一个为正另一个负!
* 对象的offsetWidth和offsetHeight属性用来取得对象在页面中的实际所占区域大小(所设置的宽高加边框加填充,当有滚动条时还会算上滚动条),似乎这个属性对于设置了宽和高的块级元素几乎没有什么浏览器兼容问题,但不得不说的是火狐的一个BUG.火狐浏览器有个可将页面放大缩小的功能,当将页面缩小后,对象的offsetWidth和offsetHeight属性会发生细微的变化-变小几像素!尽管这对JS编程来讲几乎没影响,但似乎这个BUG也太明显了.这两个属性变非总是那么让人信任,当对象并没设置宽高或它是一个行内元素时,它的报告就显得相当复杂,不同浏览器都有自己一套标准(但是仍然可以肯定的是这两个属性报告的仍然是该元素占据的的空间大小,只不过会因字体和空格的默认大小不同而不同),最让人摸不着头脑的是Opera,对于一个body的子块级元素,当body和它自身没设置宽高时,Opera报告的它的宽度相当大,6千多像素!
* 还有就是scrollWidth和scrollWidth了,就目前来讲,对于一个没有滚动条和溢出的元素,其它浏览器对这个属性的报告还算有规律:对象的clientWidth+border=scrollWidth.对象的clientHeight+border=scrollHeight;只有IE报告有问题!它以元素中的内容为准,如果元素内没有其它内容,虽然IE并不会报0,但会报告一个非常小的值!再看看当元素有滚动条时怎么样吧!唯一值得高兴的是,它们对有滚动条的元素的clientWidth和clientHeight都报告一致(但仍有一点要注意,那就是火狐的一BUG,页面缩放功能带来的郁闷,而且这次变化非常大).而对于scrollWidth和scrollHeight真是五花八门:先说好的,尽管各不一样,但它们对scrollWidth不知为什么,相差不大,那么坏的就是,scrollHeight属性就相差太大了,没规律可循!(scrollWidth和scrollHeight属性返加对象内容的实际所需空间,当元素设置了overflow值为scroll或hidden之类时,scrollWidth和scrollHeight属性就派上用场了,可惜的是它问题太多了)
综上所述,对于一个在CSS中定义了大小的块级元素,获取它的实际大小是很简单的,但对于没有定义宽度和高度,或是一行内元素时,则没有跨浏览器的解决方案可以获取它的实际大小!
### 窗口视口宽度和高度
对于窗口视口(视口指显示页面的那部分)的大小,Mozilla提供了window.innerWidth与window.innerHeight两个属性,而IE则没有相对应的属性,但可以使用document.documentElement.clientWidth与document.documentElement.clientHeight 两个属性来获取!另外,对于IE6之前的版本,则需要使用document.body的clientWidth与clientHeight属性!
```
//获取视口大小,依次为火狐,IE6及IE6以上的版本,IE6以下的版本
var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; //事实上,IE版本低于6的浏览器几乎不存在了
//而同时其实火狐也支持通过document.documentElement的clientWidth,clientHeight属性获取视口大小
//完全可以不做任何浏览器检测
w = document.documentElement.clientWidth;
h = document.documentElement.clientHeight;
```
## 元素边框宽度
获取元素边框宽度可以使用下面几种方式
* 元素style属性的borderWidth,但同样它只能返回使用HTML行内style属性定义的边框样式
* 使用currentStyle属性或getComputedStyle方法,可以获取元素CSS定义的实际边框样式,如果CSS没有定义元素的边框,一般的元素是没有边框的,但部分元素,如表单控件,仍然具有默认的边框宽度!对于此类情况,也是不能依靠这种方法来获取元素的边框大小的!
* 对象的clientLeft和clientTop属性。不能不说clientLeft和clientTop的名字起的太奇怪了,事实上它们的名字更应该这样:clientBorderLeftWidth和clientBorderTopWidth(难道是太长了的原因?);更奇怪的是,它们只能取得设置在元素上的左边框和上边框的粗细,而没有返回右边和下边的边框宽度的属性!另外,对于文档根元素(documentElement),在IE中它有默认的两像素边框宽度,而其它浏览器中报告为0.
## 元素坐标
获取元素坐标方法:
* 元素style属性的left,top属性,不但这种方法仅适用于使用HTML style属性声明样式的元素,并且只有当元素使用定位(position设置为relative,absolute,fixed,但不包含static)时,才会存在这些值
* 元素currentStyle属性或getComputedStyle方法返回的Style对象的left,top属性,但这种方法仅对采用定位的元素有作用
* 元素的offsetLeft与offsetTop属性返回元素在页面中相对于父元素的坐标。一般对于进行了定位的元素(即position为不是static的值或没有设置),这两个属性的返回值为CSS中定义的元素的left,top值,当其自身有边距时(margin),还会加上边距。而对于没有采用定位的元素则显得比较复杂,我们只能考虑下设置了宽度和高度的块级元素,因为没有设置宽高,及行内元素,没有办法获取它的宽高,即使能获取它的left,top值也显得无意义了。对于没有采用定位的块级元素,offsetLeft与offsetTop属性将返回其自身的margin+父元素的padding。元素还有个offsetParent属性返回元素的相对定位的父元素,当使用定位时,各个浏览器一致,并且和CSS里设置的吻合,当不使用定位时,父元素是WHO成了问题,各个浏览器认识不一样,IE报告为其父节点,而其它浏览器则报告为body,当然,这次IE正确了。另外,对于表格中的一些元素,不应对其进行定位!
### 具有滚动条时的定位
scrollLeft和scrollTop,它们用来获得那些具有滚动条的元素滚动条滚动的距离,而没有滚动条的元素,它总返回0.可以这样认为,这两个属性报告了有滚动条元素中未显示的左一部分的宽(scrollLeft)和上一部分的高(scrollTop).而对于页面的滚动条,则取documentElement的scrollLeft与scrollTop属性,但是对于谷歌浏览器,它会将页面的滚动条视为document.body的!
## Event对象与定位相关的属性
clientX与clientY返回事件发生时鼠标在视口中的坐标;offsetX与offsetY返回事件发生时鼠标相对于目标对象的坐标,以目标对象右上角为坐标原点,而这两个属性的W3C DOM版本则为layerX与layerY;pageX与pageY返回事件发生时鼠标相对于页面的坐标,虽然这个属性IE不支持,但仍然有补救的余地!
```
//不要在每个事件处理函数中进行判断,而要善于利用之前的fixEvent函数!
function fixEvent(evt) { if (!evt.target) { //函数中已有的部分
evt.pageX = evt.clientX+document.documentElement.scrollLeft;
evt.pageY = evt.clientY+document.documentElement.scrollTop; //可以将事件发生时鼠标在视口中的坐标加上页面滚动的偏移量得出pageX与pageY
evt.layerX = evt.offsetX;
evt.layerY = evt.offsetY;
} return evt;
}
```
## 拖动
最简单的拖动脚本——拖动的基本原理
```
window.onload = function () { var oDiv = document.getElementById("oDiv");//oDiv必须使用CSS定位
oDiv.onmousedown = drag; function drag(evt) {
evt = evt || window.event; this.onmouseup = drop; this.onmousemove = moveDiv; this.offset = {
x:evt.offsetX || evt.layerX,
y:evt.offsetY || evt.layerY
};
} function moveDiv(evt) {
evt = evt || window.event; this.style.left = evt.clientX-this.offset.x+"px"; this.style.top = evt.clientY-this.offset.y+"px";
} function drop(evt) { this.onmouseup = null; this.onmousemove = null;
}
};
```
- 介绍
- HTML/CSS 教程
- 第 1 章 HTML5 概述
- 第 2 章 基本格式
- 第 3 章 文本元素
- 第 4 章 超链接和路径
- 第 5 章 分组元素
- 第 6 章 表格元素
- 第 7 章 文档元素
- 第 8 章 嵌入元素
- 第 9 章 音频和视频
- 第 10 章 表单元素[上]
- 第 10 章 表单元素[中]
- 第 10 章 表单元素[下]
- 第 11 章 全局属性和其他
- 第 12 章 CSS 入门
- 第 13 章 CSS 选择器[上]
- 第 14 章 CSS 颜色与度量单位
- 第 15 章 CSS 文本样式[上]
- 第 15 章 CSS 文本样式[下]
- 第 16 章 CSS 盒模型[上]
- 第 16 章 CSS 盒模型[下]
- 第 17 章 CSS 边框与背景[上]
- 第 17 章 CSS 边框与背景[下]
- 第 18 章 CSS 表格与列表
- 第 19 章 CSS 其他样式
- 第 20 章 CSS3 前缀和 rem
- 第 21 章 CSS3 文本效果
- 第 21 章 CSS3 文本效果
- 第 23 章 CSS3 边框图片效果
- 第 24 章 CSS3 变形效果[下]
- 第 25 章 CSS3 过渡效果
- 第 26 章 CSS3 动画效果
- 第 27 章 CSS 传统布局[上]
- 第 27 章 CSS 传统布局[下]
- 第 28 章 CSS3 多列布局
- 第 29 章 CSS3 弹性伸缩布局[上]
- 第 29 章 CSS3 弹性伸缩布局[中]
- 第 29 章 CSS3 弹性伸缩布局[下]
- 第 30 章 使用 Emmet 插件
- Bootstrap 教程
- 第 1 章 Bootstrap 介绍
- 第 2 章 排版样式
- 第 3 章 表格和按钮
- 第 4 章 表单和图片
- 第 5 章 栅格系统
- 第 6 章 辅组类和响应式工具
- 第 7 章 图标菜单按钮组件
- 第 8 章 输入框和导航组件
- 第 9 章 路径分页标签和徽章组件
- 第 10 章 巨幕页头缩略图和警告框组件
- 第 11 章 进度条媒体对象和 Well 组件
- 第 12 章 列表组面板和嵌入组件
- 第 13 章 模态框插件
- 第 14 章 下拉菜单和滚动监听插件
- 第 15 章 标签页和工具提示插件
- 第 16 章 弹出框和警告框插件
- 第 17 章 按钮和折叠插件
- 第 18 章 轮播插件
- 第 19 章 附加导航插件
- 第 20 章 项目实战--响应式导航[1]
- 第 20 章 项目实战--响应式轮播图[2]
- 第 20 章 项目实战--首页内容介绍[上][3]
- 第 20 章 项目实战--首页内容介绍[下][4]
- 第 20 章 项目实战--资讯内容[5,6]
- 第 20 章 项目实战--案例和关于[7]
- javaScript 教程
- javascript快速入门1--JavaScript前世今生,HelloWorld与开发环境
- javascript快速入门2--变量,小学生数学与简单的交互
- javascript快速入门3--分支判断与循环
- javascript快速入门4--函数与内置对象
- javascript快速入门5--数组与对象
- javascript快速入门6--Script标签与访问HTML页面
- javascript快速入门7--ECMAScript语法基础
- javascript快速入门8--值,类型与类型转换
- javascript快速入门9--引用类型
- javascript快速入门10--运算符,语句
- javascript快速入门11--正则表达式
- javascript快速入门12--函数式与面向对象
- javascript快速入门13--BOM——浏览器对象模型(Browser Object Model)
- javascript快速入门14--DOM基础
- javascript快速入门15--节点
- javascript快速入门15--表单
- javascript快速入门16--表格
- javascript快速入门17--事件
- javascript快速入门18--样式
- javascript快速入门19--定位
- javascript快速入门20--Cookie
- javascript快速入门21--DOM总结
- javascript快速入门22--Ajax简介
- javascript快速入门23--XHR—XMLHttpRequest对象
- javascript快速入门24--XML基础
- javascript快速入门25--浏览器中的XML
- javascript快速入门26--XPath
- javascript快速入门27--XSLT基础
- PHP 教程
- 第一章 如何加载运行已发布的PHP项目
- 第二章 PHP基础
- 第三章 操作符与控制结构
- 第四章 数学运算
- 第五章 数组
- 第六章 目录与文件
- 第七章 自定义函数
- 第八章 字符串处理
- 第九章 正则表达式
- 第十章 日期与时间
- 第十一章 表单与验证
- 第十二章 会话控制
- 第十三章 上传文件
- 第十四章 处理图像
- 第十五章 MySQL 数据库
- 第十六章 PHP 操作MySQL
- 第十七章 面向对象基础
- 第十八章 面向对象的特性
- 第十九章 面向对象的工具