前端回眸一笑

一、网页的绝对大小和相对大小

首先需要明确这两个概念,一张网页的全部面积,就是它的绝对大小,通常情况下,网页的绝对大小由内容和CSS样式表决定;网页的相对大小则是指在浏览器窗口中看到的那部分网页,也就是浏览器窗口的大小,又叫做viewport(视口)。

  1. 获取网页的相对大小
    网页上的每个元素,都有clientHeight和clientWidth属性,利用它们就可以得到网页的相对大小。这两个属性代表的大小,是指元素的内容部分再加上padding的大小,但是不包括border和滚动条占用的空间。因此,document元素的clientHeight和clientWidth属性,就代表了网页的相对大小。
    function getViewport(){
    	if (document.compatMode == "BackCompat"){
    		return {
    			width: document.body.clientWidth,
    			height: document.body.clientHeight
    		}
    	} else {
    		return {
    			width: document.documentElement.clientWidth,
    			height: document.documentElement.clientHeight
    		}
    	}
    }
    PS:document.compatMode属性
    • BackCompat:标准兼容模式关闭,当document.compatMode等于BackCompat时,浏览器客户区宽度是document.body.clientWidth;
    • CSS1Compat:标准兼容模式开启,当document.compatMode等于CSS1Compat时,浏览器客户区宽度是document.documentElement.clientWidth。
    上面的getViewport函数就可以返回浏览器窗口的高和宽。使用的时候,有三个地方需要注意:
    1. 这个函数必须在页面加载完成后才能运行,否则document对象还没生成,浏览器会报错。
    2. 大多数情况下,都是document.documentElement.clientWidth返回正确值。但是,在IE6的quirks模式中,document.body.clientWidth返回正确的值,因此函数中加入了对文档模式的判断。
    3. clientWidth和clientHeight都是只读属性,不能对它们赋值
  2. 获取网页的绝对大小
    document对象的scrollHeight和scrollWidth属性就是网页的绝对大小,意思就是滚动条滚过的所有长度和宽度。仿照getViewport()函数,可以写出getPagearea()函数。

    function getPagearea(){
    	if (document.compatMode == "BackCompat"){
    		return {
    			width: document.body.scrollWidth,
    			height: document.body.scrollHeight
    		}
    	} else {
    		return {
    			width: document.documentElement.scrollWidth,
    			height: document.documentElement.scrollHeight
    		}
    	}
    }
    但是,这个函数有一个问题。前面说过,如果网页内容能够在浏览器窗口中全部显示,不出现滚动条,那么网页的绝对大小与相对大小应该相等,即clientWidth和scrollWidth应该相等。但是实际上,不同浏览器有不同的处理,这两个值未必相等。所以,我们需要取它们之中较大的那个值,因此要对getPagearea()函数进行改写。
    function getPagearea(){
    	if (document.compatMode == "BackCompat"){
    		return {
    			width: Math.max(document.body.scrollWidth,document.body.clientWidth),
    			height: Math.max(document.body.scrollHeight,document.body.clientHeight)
    		}
    	} else {
    		return {
    			width: Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth),
    			height: Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight)
    		}
    	}
    }

二、网页元素的相对与绝对位置

由于网页大小有绝对和相对之分,所以网页元素的位置也有绝对和相对之分。网页元素的左上角相对于整张网页左上角的坐标,就是绝对位置;相对于浏览器窗口左上角的坐标,就是相对位置。

Javascript语言中,网页元素的绝对坐标要通过计算才能得到。每个元素都有offsetTop和offsetLeft属性,表示该元素的左上角与父容器(offsetParent对象)左上角的距离。所以,只需要将这两个值进行累加,就可以得到该元素的绝对坐标。

  1. 获取绝对位置的横坐标和纵坐标
    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;
    }
    由于在表格和iframe中,offsetParent对象未必等于父容器,所以上面的函数对于表格和iframe中的元素不适用。
  2. 有了某个元素的绝对位置以后,获得相对位置就很容易了,只要将绝对坐标减去滚动条滚动的距离就可以了。滚动条滚动的垂直距离,是document对象的scrollTop属性;滚动条滚动的水平距离是document对象的scrollLeft属性。
    function getElementViewLeft(element){
    	var actualLeft = element.offsetLeft;
    	var current = element.offsetParent;
    	
    	while (current !== null){
    		actualLeft += current.offsetLeft;
    		current = current.offsetParent;
    	}
    	
    	if (document.compatMode == "BackCompat"){
    		var elementScrollLeft=document.body.scrollLeft;
    	} else {
    		var elementScrollLeft=document.documentElement.scrollLeft; 
    	}
    	
    	return actualLeft-elementScrollLeft;
    }
    
    function getElementViewTop(element){
    	var actualTop = element.offsetTop;
    	var current = element.offsetParent;
    	
    	while (current !== null){
    		actualTop += current. offsetTop;
    		current = current.offsetParent;
    	}
    	
    	if (document.compatMode == "BackCompat"){
    		var elementScrollTop=document.body.scrollTop;
    	} else {
    		var elementScrollTop=document.documentElement.scrollTop; 
    	}
    	
    	return actualTop-elementScrollTop;
    }
    scrollTop和scrollLeft属性是可以赋值的,并且会立即自动滚动网页到相应位置,因此可以利用它们改变网页元素的相对位置。另外,element.scrollIntoView()方法也有类似作用,可以使网页元素出现在浏览器窗口的左上角。

三、getBoundingClientRect获取元素位置

除了上面的函数以外,还有一种快速方法,可以立刻获得网页元素的位置,那就是使用getBoundingClientRect()方法。

getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。getBoundingClientRect是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;这里的top、left和css中的理解很相似,width、height是元素自身的宽高,但是right,bottom和css中的理解有点不一样。right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。

getBoundingClientRect()最先是IE的私有属性,现在已经是一个W3C标准。所以你不用当心浏览器兼容问题,不过还是有区别的:IE只返回top,lef,right,bottom四个值,不够可以通过以下方法来获取width,height的值:

var ro = object.getBoundingClientRect();
var Width = ro.right - ro.left;
var Height = ro.bottom - ro.top;

兼容所有浏览器写法:

var ro = object.getBoundingClientRect();
var Top = ro.top;
var Bottom = ro.bottom;
var Left = ro.left;
var Right = ro.right;
var Width = ro.width||Right - Left;
var Height = ro.height||Bottom - Top;

有了这个方法,获取页面元素的位置就简单多了:

var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;

四、位置与尺寸的总结

offsetWidth/offsetHeight(非标准属性,但各浏览器都支持)对象的可见宽度,包含滚动条和border。
clientWidth/clientHeight 对象的可见宽度,不包含滚动条和border。
scrollWidth/scrollHeight(慎用)元素完整的高度和宽度,overflow:hidden的部分也计算在内。
offsetLeft/offsetTop 当前元素距浏览器边界的偏移量,以像素为单位。
clientTop/clientLeft 这个属性测试下来的结果是=border。
scrollLeft/scrllTop(IE6计算方式不同)设置或返回已经滚动到元素的左边界或上边界的像素数。

IE6.0、FF1.06+: 
clientWidth = width + padding 
clientHeight = height + padding 
offsetWidth = width + padding + border 
offsetHeight = height + padding + border 
IE5.0/5.5: 
clientWidth = width - border 
clientHeight = height - border 
offsetWidth = width 
offsetHeight = height 

网页可见区域宽: document.body.clientWidth;
网页可见区域高: document.body.clientHeight;
网页可见区域宽: document.body.offsetWidth   (包括边线的宽);
网页可见区域高: document.body.offsetHeight (包括边线的宽);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被卷去的高: document.body.scrollTop;
网页被卷去的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度:window.screen.availWidth;


scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离 
offsetHeight:获取对象相对于版面或由父坐标 offsetParent 属性指定的父坐标的高度 
offsetLeft:获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置 
offsetTop:获取对象相对于版面或由 offsetTop 属性指定的父坐标的计算顶端位置 
event.clientX 相对文档的水平座标 
event.clientY 相对文档的垂直座标 
event.offsetX 相对容器的水平坐标 
event.offsetY 相对容器的垂直坐标 
document.documentElement.scrollTop 垂直方向滚动的值 
event.clientX+document.documentElement.scrollTop 相对文档的水平座标+垂直方向滚动的量

比较offsetHeight/clientHeight/scrollHeight
共同点:3个值都和元素的margin无关。
差异:offsetHeight=height+padding+border
     clientHeight=height+padding-滚动条的宽度(如果有滚动条)
     scrollHeight 获得的是元素的实际宽度影藏的部分也计算在内
备注:Jquery中的css("height")/height()不计算padding/border/滚动条。offsetWidth、clientWidth、scrollWidth同理。
比较offsetTop/clientTop/scrollTop
offsetTop:元素相对body的Top值(元素border以外到body.padding以内)
clientTop=offsetTop-(height+padding)=border
scrollTop:元素的滚动值

五、主流浏览器的鼠标点击事件

Event对象的属性有:

altKey, button, cancelBubble, clientX, clientY, ctrlKey, fromElement, keyCode, offsetX, offsetY, propertyName, returnValue, screenX, screenY, shiftKey, srcElement, srcFilter, toElement, type, x, y

  1. altKey
    描述: 检查alt键的状态。
    语法: event.altKey
    可能的值: 当alt键按下时,值为 TRUE ,否则为 FALSE 。只读。
  2. button
    描述: 检查按下的鼠标键。
    语法: event.button
    可能的值:
    0 没按键 ;1 按左键 ;2 按右键 ;3 按左右键 ;4 按中间键 ;5 按左键和中间键 ;6 按右键和中间键 ;7 按所有的键
    这个属性仅用于onmousedown, onmouseup, 和 onmousemove 事件。对其他事件,不管鼠标状态如何,都返回 0(比如onclick)。
  3. cancelBubble
    描述: 检测是否接受上层元素的事件的控制。
    语法: event.cancelBubble[ = cancelBubble]
    可能的值: 这是一个可读写的布尔值
    TRUE 不被上层原素的事件控制。
    FALSE 允许被上层元素的事件控制。这是默认值。
  4. clientX
    描述: 返回鼠标在窗口客户区域中的X坐标。
    语法: event.clientX
    注释: 这是个只读属性。这意味着,你只能通过它来得到鼠标的当前位置,却不能用它来更改鼠标的位置。
  5. clientY
    描述: 返回鼠标在窗口客户区域中的Y坐标。
    语法: event.clientY
    注释: 这是个只读属性。这意味着,你只能通过它来得到鼠标的当前位置,却不能用它来更改鼠标的位置。
  6. ctrlKey
    描述: 检查ctrl键的状态。
    语法: event.ctrlKey
    可能的值: 当ctrl键按下时,值为 TRUE ,否则为 FALSE 。只读。
  7. fromElement
    描述: 检测 onmouseover 和 onmouseout 事件发生时,鼠标所离开的元素。 参考18.toElement
    语法: event.fromElement
    注释: 这是个只读属性。
  8. keyCode
    描述:检测键盘事件相对应的内码。 这个属性用于 onkeydown, onkeyup, 和 onkeypress 事件。
    语法: event.keyCode[ = keyCode]
    可能的值: 这是个可读写的值,可以是任何一个Unicode键盘内码。如果没有引发键盘事件,则该值为 0 。
  9. offsetX
    描述: 检查相对于触发事件的对象,鼠标位置的水平坐标
    语法: event.offsetX
  10. offsetY
    描述: 检查相对于触发事件的对象,鼠标位置的垂直坐标
    语法: event.offsetY
  11. propertyName
    描述: 设置或返回元素的变化了的属性的名称。
    语法: event.propertyName [ = sProperty ]
    可能的值: sProperty 是一个字符串,指定或返回触发事件的元素在事件中变化了的属性的名称。
    注释:这个属性是可读写的。无默认值。你可以通过使用 onpropertychange 事件,得到 propertyName 的值。
  12. returnValue
    描述: 设置或检查从事件中返回的值
    语法: event.returnValue[ = Boolean]
    可能的值: true 事件中的值被返回
    false 源对象上事件的默认操作被取消
  13. screenX
    描述: 检测鼠标相对于用户屏幕的水平位置
    语法: event.screenX
    注释: 这是个只读属性。这意味着,你只能通过它来得到鼠标的当前位置,却不能用它来更改鼠标的位置。
  14. screenY
    描述: 检测鼠标相对于用户屏幕的垂直位置
    语法: event.screenY
    注释: 这是个只读属性。这意味着,你只能通过它来得到鼠标的当前位置,却不能用它来更改鼠标的位置。
  15. shiftKey
    描述: 检查shift键的状态。
    语法: event.shiftKey
    可能的值: 当shift键按下时,值为 TRUE ,否则为 FALSE 。只读。
  16. srcElement
    描述: 返回触发事件的元素。只读。例子见本文开头。
    语法: event.srcElement
  17. srcFilter
    描述: 返回触发 onfilterchange 事件的滤镜。只读。
    语法: event.srcFilter
  18. toElement
    描述: 检测 onmouseover 和 onmouseout 事件发生时,鼠标所进入的元素。 参考7.fromElement
    语法: event.toElement
    注释: 这是个只读属性。
  19. type
    描述: 返回事件名。
    语法: event.type
    注释: 返回没有“on”作为前缀的事件名,比如,onclick事件返回的type是click 只读。
  20. x
    描述: 返回鼠标相对于css属性中有position属性的上级元素的x轴坐标。如果没有css属性中有position属性的上级元素,默认以BODY元素作为参考对象。
    语法: event.x
    注释: 如果事件触发后,鼠标移出窗口外,则返回的值为 -1
    这是个只读属性。这意味着,你只能通过它来得到鼠标的当前位置,却不能用它来更改鼠标的位置。
  21. y
    描述: 返回鼠标相对于css属性中有position属性的上级元素的y轴坐标。如果没有css属性中有position属性的上级元素,默认以BODY元素作为参考对象。
    语法: event.y

window.event

  • IE
    左键是 window.event.button = 1
    右键是 window.event.button = 2
    中键是 window.event.button = 4
    没有按键动作window.event.button = 0
  • Firefox
    左键是 event.button = 0
    右键是 event.button = 2
    中键是 event.button = 1
    没有按键动作 event.button = 0
  • Opera 7.23/7.54
    鼠标左键是 window.event.button = 1
    没有按键动作 window.event.button = 1
    右键和中键无法获取
  • Opera 7.60/8.0
    鼠标左键是 window.event.button = 0
    没有按键动作 window.event.button = 0
    右键和中键无法获取

另外:屏蔽右键的是window.event.button = 3 

Window.event对象代表事件的状态,例如触发event对象的元素、鼠标的位置及状态、按下的键等等。Window.event对象只在事件发生的过程中才有效。如果事件触发后,鼠标移出窗口外,则返回的值为 -1。

posted @ 2014-10-29 11:32  码农神说  阅读(172)  评论(0编辑  收藏  举报