您当前的位置:首页 > 网站建设笔记 >

javascript getBoundingClientRect()确定元素大小

0

IE、Firefox 3+、Safari 4+、Opera 9.5及Chrome为每个元素都提供了一个getBoundingClientRect()方法。这个方法会返回一个矩形对象,包含4个属性:left、top、right和bottom。这些属性给出了元素在页面中相对于视口的位置。但是,浏览器的实现稍有不同。IE8及更早版本认为文档的左上角坐标是(2,2),而其他浏览器包括IE9则将传统的(0,0)作为起点坐标。因此,就需要在一开始检查一下位于(0,0)处的元素的位置,在IE8及更早版本中,会返回(2,2),而在其他浏览器中会返回(0,0)。

function getBoundingClientRect(element){
	if(typeof arguments.callee.offset!="number"){
		var scrollTop=document.documentElement.scrollTop;
		var temp=document.createElement("div");
		temp.style.cssText="position:absolute;left:0;top:0;";
		document.body.appendChild(temp);
		arguments.callee.offset = -temp.getBoundingClientRect().top-scrollTop;
		document.body.removeChild(temp);
		temp=null;
	}
	var rect=element.getBoundingClientRect();
	var offset=arguments.callee.offset;
	return {
		left:rect.left+offset,
		right:rect.right+offset,
		top:rect.top+offset,
		bottom:rect.bottom+offset
	};
}

这个函数使用了它自身的属性来确定是否要对坐标进行调整。第一步是检测属性是否有定义,如果没有就定义一个。最终的offset会被设置为新元素上坐标的负值,实际上就是在IE中设置为-2,在Firefox和Opera中设置为-0。为此,需要创建一个临时的元素,将其位置设置在(0,0),然后再调用其getBoundingClientRect()。而之所以要减去视口的scrollTop,是为了防止调用这个函数时窗口被滚动了。这样编写代码,就无需每次调用这个函数都执行两次getBoundingClientRect()了。接下来,再在传入的元素上调用这个方法并基于新的计算公式创建一个对象。对于不支持getBoundingClientRect()的浏览器,可以通过其他手段取得相同的值。一般来说,right和left的差值与offsetWidth的值相等,而bottom和top的差值与offsetHeight相等。而且,left和top属性大致等于使用getElementLeft()getElementTop()函数取得的值。综合上述,就可以创建出下面这个跨浏览器的函数:

function getBoundingClientRect(element){
	var scrollTop=document.documentElement.scrollTop;
	var scrollLeft=document.documentElement.scrollLeft;
	if(element.getBoundingClientRect){
		if(typeof arguments.callee.offset!="number"){
			var temp=document.createElement("div");
			temp.style.cssText="position:absolute;left:0;top:0;";
			document.body.appendChild(temp);
			arguments.callee.offset=-temp.getBoundingClientRect().top-scrollTop;
			document.body.removeChild(temp);
			temp=null;
		}
		var rect=element.getBoundingClientRect();
		var offset=arguments.callee.offset;
		return {
			left:rect.left + offset,
			right:rect.right + offset,
			top:rect.top + offset,
			bottom:rect.bottom + offset
		};
	}else{
		var actualLeft=getElementLeft(element);
		var actualTop=getElementTop(element);
		return {
			left: actualLeft-scrollLeft,
			right: actualLeft-scrollLeft+element.offsetWidth,
			top: actualTop-scrollTop,
			bottom: actualTop-scrollTop+element.offsetHeight
		};
	}
}

这个函数在getBoundingClientRect()有效时,就使用这个原生方法,而在这个方法无效时则使用默认的计算公式。在某些情况下,这个函数返回的值可能会有所不同,例如使用表格布局或使用滚动元素的情况下。由于这里使用了arguments.callee,所以这个方法不能在严格模式下使用。

顶部中部底部