1、偏移量---offsetjavascript
一、定位父级css
在理解偏移大小以前,首先要理解offsetParent。人们并无把offsetParent翻译为偏移父级,而是翻译成定位父级,很大缘由是offsetParent与定位有关html
定位父级offsetParent的定义------》与当前元素最近的通过定位(position不等于static)的父级元素,主要分为下列几种状况 :java
【1】元素自身有fixed定位,offsetParent的结果为nullchrome
当元素自身有fixed固定定位时,咱们知道固定定位的元素相对于视口进行定位,此时没有定位父级,offsetParent的结果为null浏览器
[注意]firefox浏览器有兼容性问题布局
<div id="test" style="position:fixed"></div> <script> //firefox并无考虑固定定位的问题,返回<body>,其余浏览器都返回null console.log(test.offsetParent); </script>
【2】元素自身无fixed定位,且父级元素都未通过定位,offsetParent的结果为<body>性能
<div id="test"></div>
<script>
console.log(test.offsetParent);//<body>
</script>
【3】元素自身无fixed定位,且父级元素存在通过定位的元素,offsetParent的结果为离自身元素最近的通过定位的父级元素字体
<div id="div0" style="position:absolute;">
<div id="div1" style="position:absolute;">
<div id='test'></div>
</div>
</div>
<script>
console.log(test.offsetParent); //<div id="div1">
</script>
【4】<body>元素的parentNode是null网站
console.log(document.body.offsetParent);//null
补充:对于定位父级offsetParent来讲,IE7-浏览器存在如下Bug
【bug1】当元素自己通过绝对定位或相对定位,且父级元素无通过定位的元素时,IE7-浏览器下,offsetParent是<html>
<div id="test" style="position:absolute;"></div> <script> //IE7-浏览器返回<html>,其余浏览器返回<body> console.log(test.offsetParent); </script><div id="test" style="position:relative;"></div> <script> //IE7-浏览器返回<html>,其余浏览器返回<body> console.log(test.offsetParent); </script><div id="test" style="position:fixed;"></div> <script> //firefox并无考虑固定定位的问题,返回<body>,其余浏览器都返回null console.log(test.offsetParent); </script>【bug2】若是父级元素存在触发 haslayout 的元素或通过定位的元素,即offsetParent的结果为离自身元素最近的通过定位或触发haslayout的父级元素
<div id="div0" style="display:inline-block;"> <div id='test'></div> </div> <script> //IE7-浏览器返回<div id="div0">,其余浏览器返回<body> console.log(test.offsetParent); </script>
<div id="div0" style="position:absolute;"> <div id="div1" style="display:inline-block;"> <div id='test'></div> </div> </div> <script> //IE7-浏览器返回<div id="div1">,其余浏览器返回<div id="div0"> console.log(test.offsetParent); </script>
<div id="div0" style="display:inline-block;"> <div id="div1" style="position:absolute;"> <div id='test'></div> </div> </div> <script> //全部浏览器都返回<div id="div1"> console.log(test.offsetParent); </script>
二、4个偏移量【元素 的可见大小由其高度、宽度决定,包括全部内边距、滚动条和边框大小(注意,不包括外边距)】
【1】offsetHeight------元素在垂直方向上占用的空间大小,以像素计。
offsetHeight = border-top-width + padding-top + height + padding-bottom + border-bottom-width
【2】offsetWidth------元素在水平方向上占用的空间大小,以像素计。
offsetWidth = border-left-width + padding-left + width + padding-right + border-right-width;
补充:若是存在垂直滚动条,offsetWidth也包括垂直滚动条的宽度;若是存在水平滚动条,offsetHeight也包括水平滚动条的高度
<div id="test" style="width:100px; height:100px; padding:10px; margin:10px; border:1px solid black; overflow: scroll;"></div> <script> //IE8-浏览器将垂直滚动条的宽度计算在width宽度和height高度中,width和height的值仍然是100px; //而其余浏览器则把垂直滚动条的宽度从width宽度中移出,把水平滚动条的高度从height高度中移出,则滚动条宽度为17px,width宽度和height高度为剩下的83px if(window.getComputedStyle){ console.log(getComputedStyle(test).width,getComputedStyle(test).height)//83px }else{ console.log(test.currentStyle.width,test.currentStyle.height);//100px } console.log(test.offsetWidth,test.offsetHeight);//122=1+10+100+10+1</script>
【3】offsetTop------元素的上外边框(border-top)至包含元素的上内边框之间的像素距离
【4】offsetLeft------元素的左外边框(border-left)至包含元素的左内边框之间的像素距离
补充:IE7-浏览器在offsetTop属性的处理上存在bug
【1】若父级设置position: relative,则在IE7-浏览器下,offsetTop值为offsetParent元素的paddingBottom值
<div id="out" style="padding: 5px;position: relative;"> <div id="test" style="width:100px; height:100px; margin:10px;"></div> </div> <script> //其余浏览器返回15(5+10),而IE7-浏览器返回5 console.log(test.offsetTop); </script>
【2】若父级设置position: aboslute(或其余触发haslayout的条件),offsetTop值为offsetParent元素的paddingBottom值和当前元素的marginTop值的较大值
<div id="out" style="padding: 5px;position:absolute;"> <div id="test" style="width:100px; height:100px; margin:10px;"></div> </div> <script> //其余浏览器返回15(5+10),而IE7-浏览器返回10(10和5的较大值) console.log(test.offsetTop); </script>
三、页面偏移
要知道某个元素在页面上的偏移量,将这个元素的offsetLeft和offsetTop与其offsetParent的相同属性相加,并加上offsetParent的相应方向的边框,如此循环直到根元素,就能够获得元素到页面的偏移量
【注意】在默认状况下,IE8-浏览器下若是使用currentStyle()方法获取<html>和<body>(甚至普通div元素)的边框宽度都是medium,而若是使用clientLeft(或clientTop)获取边框宽度,则是实际的数值
html,body{border: 0;} body{margin:0;}
function getElementLeft(element){ var actualLeft = element.offsetLeft; var current = element.offsetParent; while(current != null){ actualLeft += current.offsetLeft + current.clientLeft; current = current.offsetParent; } return actualLeft + 'px'; } function getElementTop(element){ var actualTop = element.offsetTop; var current = element.offsetParent; while(current != null){ actualTop += current.offsetTop + current.clientTop; current = current.offsetParent; } return actualTop + 'px'; }
<div style="padding: 20px;border:1px solid black;position:absolute;"> <div id="test" style="width:100px; height:100px; margin:10px;"></div> </div> <script> //其余浏览器返回31(10+20+1),而IE7-浏览器返回21((20和10的较大值)+1) console.log(getElementTop(test)); //全部浏览器返回31(10+20+1) console.log(getElementLeft(test)); </script>
注意:
一、全部这些偏移量属性都是只读的,并且每次访问它们都须要从新计算。
二、应该尽可能避免重复访问这些属性;若是须要重复使用其中某些属性的值,能够将它们保存在局部变量中,以提升性能。
三、若是给元素设置了display:none,则它的偏移量属性都为0
2、客户区大小---client
定义:元素内容及其内边距所占据的空间大小【即:元素内部的空间大小】
/*滚动条占用的空间不计算在内*/
<div id="test" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;overflow:scroll"></div> <script> //103(120-17),滚动条宽度为17px console.log(test.clientHeight); console.log(test.clientWidth); </script>
一、4个客户区大小
【1】clientHeight
clientHeight = padding-top + height + padding-bottom
【2】clientWidth
clientWidth = padding-left + height + padding-right
补充:当height和纵向padding的和为0(以及小于17px的状况)时,若是仍然存在滚动条,各浏览器表现不同
<div id="test" style="width: 100px;height:0;margin: 10px;border: 1px solid black;overflow:scroll"></div> <script> //chrome/safari:-17(0-17) //firefox/IE:0 console.log(test.clientHeight); </script>
bug:若是设置overflow:scroll,使得滚动条始终存在,当不设置高度height值时,各个浏览器表现不同。
一、firefox存在一个最小高度为34px的垂直滚动条
二、IE7-浏览器存在一个最小高度为19px的垂直滚动条,
三、而其余浏览器的垂直滚动条无最小高度
总结:当clientHeight的值小于34px时,firefox会返回34;当clientHeight的值小于19px时,IE7-会返回19
/*无高度*/
<div id="test" style="width: 100px;margin: 10px;border: 1px solid black;overflow:scroll"></div> <script> //chrome/IE8+/safari:0(由于height和padding都是0) //firefox:34(设置overflow:scroll以后,默认存在一个高34px的垂直滚动条) //IE7-:19(默认存在一个高19px的垂直滚动条) console.log(test.clientHeight); </script>
/*字体大小为20px*/
<div id="test" style="width: 100px;margin: 10px;border: 1px solid black;font-size:20px;line-height:1;overflow:scroll">内容</div> <script> //chrome/IE8+/safari:20(20*1) //firefox:34(20<34) //IE7-:20(20>19) console.log(test.clientHeight); </script>
/*有padding-top和字体大小*/
<div id="test" style="width: 100px;padding-top:20px;margin: 10px;border: 1px solid black;font-size:20px;line-height:1;overflow:scroll">内容</div> <script> //chrome/IE8+/safari:40(20*1+20) //firefox:40(40>34) //IE7-:40(40>19) console.log(test.clientHeight); </script>
【3】clientLeft-----------返回左边框的宽度
【4】clientHeight------------返回上边框的宽度
<div id="test" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></div> <script> //1 1 console.log(test.clientLeft); console.log(test.clientTop); </script>
【注意】若是display为inline时,clientLeft属性和clientTop属性都返回0
<div id="test" style="display:inline;width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></div> <script> //0 0 console.log(test.clientLeft); console.log(test.clientTop); </script>
二、页面大小---肯定浏览器 视口大小
【1】document.documentElement的client属性来表示页面大小(不包含滚动条宽度)
【注意】在IE7-浏览器中,<html>元素默认存在垂直滚动条
<body style="overflow:scroll"> <script> //1903(1920-17) console.log(document.documentElement.clientWidth); //930(947-17) console.log(document.documentElement.clientHeight); </script>
【2】表示页面大小的属性是window.innerHeight和innerWidth属性(包含滚动条宽度)
innerHeight和innerWidth表示的是浏览器窗口大小减去菜单栏、地址栏等剩余的页面尺寸,因为滚动条是属于页面的,因此包含滚动条
【注意】IE8-浏览器不支持innerHeight和innerWidth属性
<body style="overflow:scroll"> <script> //1920 console.log(window.innerWidth); //947 console.log(window.innerHeight); </script>
【注意】
一、若是没有滚动条,这两类属性在电脑端表示一样的值,可是却表示不一样的含义。在移动端,innerWidth和innerHeight表示的是视觉视口,即用户正在看到的网站的区域;而document.documentElement.clientWidth和clientHeight表示的是布局视口,指CSS布局的尺寸。
二、页面的客户区大小和页面的实际大小是不一样的,页面的实际大小将scroll滚动大小来表示
三、全部客户区client属性都是只读的【IE8-浏览器会报错,其余浏览器则静默失败】
四、每次访问客户区client属性都须要从新计算,重复访问须要耗费大量的性能,因此要尽可能避免重复访问这些属性。若是须要重复访问,则把它们的值保存在变量中,以提升性能
五、若是给元素设置了display:none,则客户区client属性都为0
六、,要肯定浏览器视口大小,可使用 document.documentElement 或 document.body(在 IE7 以前的版本中)的 clientWidth 和 clientHeight【肯定浏览器是否运行在混杂模式】
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 }; } }
3、滚动大小----scroll
定义:包含滚动内容的元素的大小
一、4个滚动大小
【1】scrollHeight----在没有滚动条的状况下,元素内容的总高度,包括因为溢出而没法展现在网页的不可见部分
【2】scrollWidth-----在没有滚动条的状况下,元素内容的总宽度,包括因为溢出而没法展现在网页的不可见部分
【注意】
一、scrollHeight和scrollWidth只可读
二、scrollWidth 和 scrollHeight 主要用于肯定元素内容的实际大小。
例如,一般认为元素是在 Web 浏览器的视口中滚动的元素(IE6 以前版本运行在混杂模式下时是元素)。所以,带有 垂直滚动条的页面总高度就是
document.documentElement.scrollHeight。
三、IE7-浏览器返回值是不许确的
【1】没有滚动条时,scrollHeight与clientHeight属性结果相等,scrollWidth与clientWidth属性结果相等
<div id="test" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;"></div> <script> //120 120 console.log(test.scrollHeight,test.scrollWidth); //120 120 console.log(test.clientHeight,test.clientWidth); </script>【2】存在滚动条时,但元素设置宽高大于等于元素内容宽高时,scroll和client属性的结果相等
<div id="test"style="width: 100px;height: 100px;padding:10px;margin:10px;border:1px solid black;overflow:scroll;font-size:20px;line-height:1;"> 内容<br>内容<br> </div> <script> //103(120-17) 103(120-17) console.log(test.scrollHeight,test.scrollWidth); //103(120-17) 103(120-17) console.log(test.clientHeight,test.clientWidth); </script>
【3】存在滚动条,但元素设置宽高小于元素内容宽高,即存在内容溢出的状况时,scroll属性大于client属性
[注意]scrollHeight属性存在兼容性问题,chrome和safari浏览器中,scrollHeight包含padding-bottom;而IE和firefox不包含padding-bottom
<div id="test" style="width:100px;height:100px;padding:10px;margin:10px;border:1px solid black;overflow:scroll;font-size:20px;line-height:200px;"> 内容 </div> <script> //chrome/safari:220(200+10+10) //firefox/IE:210(200+10) console.log(test.scrollHeight); //103(120-17) console.log(test.clientHeight); </script>******************************************************************************************************
对于不包含滚动条的页面而言, scrollWidth 和 scrollHeight 与 clientWidth 和 clientHeight 之间的关系并不十分清晰。
在这种状况下,基于document.documentElement 查看 这些属性会在不一样浏览器间发现一些不一致性问题,以下所述。
一、Firefox 中这两组属性始终都是相等的,但大小表明的是文档内容区域的实际尺寸,而非视口的 尺寸。
二、Opera、Safari 3.1 及更高版本、Chrome 中的这两组属性是有差异的,其中 scrollWidth 和 scrollHeight 等于视口大小,而 clientWidth 和 clientHeight 等于文档内容区域的大小。
三、IE(在标准模式)中的这两组属性不相等,其中 scrollWidth 和 scrollHeight 等于文档内 容区域的大小,而 clientWidth 和 clientHeight 等于视口大小。
总结:在肯定文档的总高度时(包括基于视口的最小高度时),必须取得 scrollWidth/clientWidth 和 scrollHeight/clientHeight 中的最大值,才能保证在跨浏览器的环境下获得精确的结果。【对于运行在混杂模式下的 IE,则须要用 document.body 代替 document.documentElement。】
var docHeight = Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight); var docWidth = Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth);
【3】scrollLeft-----被隐藏在内容区域左侧的像素数。元素未滚动时,scrollLeft的值为0,若是元素被水平滚动了,scrollLeft的值大于0
【4】scrollTop-----被隐藏在内容区域上方的像素数。元素未滚动时,scrollTop的值为0,若是元素被垂直滚动了,scrollTop的值大于0
一、当滚动条滚动到内容底部时,符合如下等式
scrollHeight == scrollTop + clientHeight
<div id="test" style="width: 100px;height: 100px;padding: 10px;margin: 10px;border: 1px solid black;overflow:scroll;font-size:20px;line-height:200px;"> 内容</div> <button id='btn1'>点击</button> <div id="result"></div> <script> btn1.onclick = function(){
//scrollTop:0;clientHeight:103;scrollHeight:220 result.innerHTML = 'scrollTop:' + test.scrollTop+';clientHeight:' + test.clientHeight + ';scrollHeight:' + test.scrollHeight } </script>二、scrollLeft和scrollTop是可写的,scrollLeft和scrollTop赋值为负值时,并不会报错,而是静默失败
二、页面尺寸
document.documentElement.clientHeight表示页面的可视区域的尺寸,而document.documentElement.scrollHeight表示html元素内容的实际尺寸。可是因为各个浏览器表现不同,分为如下几种状况
【1】html元素没有滚动条时,IE和firefox的client和scroll属性始终相同,且返回可视区的尺寸大小;而safari和chrome表现正常,clientHeight返回可视区域大小,而scrollHeight返回元素内容大小
//firefox: 755 755 //chrome: 947 8(body元素的margin) //safari: 744 8(body元素的margin) //IE: 768 768 console.log(document.documentElement.clientHeight,document.documentElement.scrollHeight)
【2】html元素存在滚动条时,各个浏览器都表现正常。clientHeight返回可视区域大小,而scrollHeight返回元素内容大小
<body style="height:1000px"> <script> //firefox: 755 1016(1000+8*2) //chrome: 947 1016(1000+8*2) //safari: 744 1016(1000+8*2) //IE: 768 1016(1000+8*2) console.log(document.documentElement.clientHeight,document.documentElement.scrollHeight) </script>
兼容
所以要取得文档实际高度时,要取得<html>元素的scrollHeight和clientHeight的最大值
var docHeight = Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight); var docWidth = Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth);
三、页面滚动
理论上,经过document.documentElement.scrollTop和scrollLeft能够反映和控制页面的滚动;可是chrome和safari浏览器是经过document.body.scrollTop和scrollLeft来控制的
<body style="height:1000px"> <button id='btn1' style="position:fixed;top:0;">点击</button> <div id="result" style="position:fixed;top:30px;"></div> <script> btn1.onclick = function(){ result.innerHTML = 'html的scrollTop:' + document.documentElement.scrollTop +';body的scrollTop:' + document.body.scrollTop; } </script> </body>
//页面的滚动高度兼容写法是
var docScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
四、回到顶部
function scrollTop(){
if((document.body.scrollTop || document.documentElement.scrollTop) != 0){
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
}
<body style="height:1000px">
<button id='btn' style="position:fixed">回到顶部</button>
<script>
function scrollTop(){
if((document.body.scrollTop || document.documentElement.scrollTop) != 0){
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
}
btn.onclick = scrollTop;
</script>
</body>
4、获取整个页面滚动的像素值
【1】pageXOffset-----表示水平方向上页面滚动的像素值
【2】pageYOffset-----表示垂直方向上页面滚动的像素值
[注意]IE8-浏览器不支持
<body style="height:1000px"> <button id='btn1' style="position:fixed;top:0;">点击</button> <div id="result" style="position:fixed;top:30px;"></div> <script> btn1.onclick = function(){ result.innerHTML = 'pageYOffset:' + window.pageYOffset; } </script> </body>
5、滚动方法
【1】scrollTo(x,y)----滚动当前window中显示的文档,让文档中由坐标x和y指定的点位于显示区域的左上角
<body style="height:1000px"> <button id='btn' style="position:fixed">滚动</button> <script> btn.onclick = function(){scrollTo(0,0);} </script>
【2】scrollBy(x,y)-----滚动当前window中显示的文档,x和y指定滚动的相对量
<body style="height:1000px"> <button id='btn1' style="position:fixed">向下滚动</button> <button id='btn2' style="position:fixed;top:40px">向上滚动</button> <script> btn1.onclick = function(){scrollBy(0,100);} btn2.onclick = function(){scrollBy(0,-100);} </script>
【小应用】利用scrollBy()加setInterval计时器实现简单的快速滚动功能
<body style="height:1000px"> <button id='btn1' style="position:fixed">开始滚动</button> <button id='btn2' style="position:fixed;top:40px">中止滚动</button> <script> var timer = 0; btn1.onclick = function(){ timer = setInterval(function(){ scrollBy(0,10); },100)} btn2.onclick = function(){ clearInterval(timer); timer = 0; } </script>
【3】scrollIntoView()滚动当前元素,进入浏览器的可见区域
该方法能够接受一个布尔值做为参数。若是为true,表示元素的顶部与当前区域的可见部分的顶部对齐(前提是当前区域可滚动);若是为false,表示元素的底部与当前区域的可见部分的尾部对齐(前提是当前区域可滚动)。若是没有提供该参数,默认为true
<body style="height:1000px"> <div id="test" style="height:100px;width:100px;position:absolute;left:0;top:500px; line-height: 1.5 !important;">></div> <button id='btn1' style="position:fixed">滚动到页面开头</button> <button id='btn2' style="position:fixed;top:40px">滚动到页面结尾</button> <script> btn1.onclick = function(){ test.scrollIntoView(); }; btn2.onclick = function(){ test.scrollIntoView(false); } </script>
【4】scrollIntoViewIfNeeded()
scrollIntoViewIfNeeded(true)方法只在当前元素在视口中不可见的状况下,才滚动浏览器窗口或容器元素,最终让它可见。若是当前元素在视口中可见,这个方法什么也不作
若是将可选的alignCenter参数设置为true,则表示尽可能将元素显示在视口中部(垂直方向)
[注意]该方法只有chrome和safari支持
<body style="height:1000px"> <div id="test" style="height:100px;width:100px;position:absolute;left:0;top:500px; line-height: 1.5 !important;">></div> <button id='btn' style="position:fixed">滚动到页面中间</button> <script> btn.onclick = function(){ test.scrollIntoViewIfNeeded(true) }; </script>
【5】scrollByLines(lineCount)
scrollByLines(lineCount)方法将元素的内容滚动指定的行髙,lineCount值能够是正值, 也能够是负值
[注意]该方法只有safari支持
<div id="test" style="width:100px;height: 100px;padding:10px;margin: 10px;border: 1px solid black;overflow:scroll;font-size:20px;line-height:200px;"> 内容</div> <button id='btn1'>向下滚动</button> <button id='btn2'>向上滚动</button> <script> btn1.onclick = function(){test.scrollByLines(1);} btn2.onclick = function(){test.scrollByLines(-1);} </script>
【6】scrollByPages(pageCount)
scrollByPages(pageCount)方法将元素的内容滚动指定的页面高度,具体高度由元素的高度决定
[注意]该方法只有safari支持
<div id="test" style="width:100px;height:100px;padding:10px;margin:10px;border:1px solid black;overflow:scroll;font-size:20px;line-height:200px;"> 内容</div> <button id='btn1'>向下滚动</button> <button id='btn2'>向上滚动</button> <script> btn1.onclick = function(){test.scrollByPages(1);} btn2.onclick = function(){test.scrollByPages(-1);} </script>
6、滚动事件
scroll事件是在window对象上发生的,它表示的是页面中相应元素的变化。固然,scroll事件也能够用在有滚动条的元素上
<body style="height:1000px"> <div id="result" style="position:fixed;top:10px;"></div> <script> window.onscroll = function(){ result.innerHTML = '页面的scrollTop:' + (document.documentElement.scrollTop||document.body.scrollTop); } </script> </body>