深入理解滚动scroll
前面的话
前面两篇博文分别介绍过偏移大小、客户区大小。本文介绍元素尺寸中内容最多的一部分——滚动scroll
滚动宽高
scrollHeight
scrollHeight表示元素的总高度,包括由于溢出而无法展示在网页的不可见部分
scrollWidth
scrollWidth表示元素的总宽度,包括由于溢出而无法展示在网页的不可见部分
[注意]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>
页面尺寸
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);
滚动长度
scrollTop
scrollTop属性表示被隐藏在内容区域上方的像素数。元素未滚动时,scrollTop的值为0,如果元素被垂直滚动了,scrollTop的值大于0,且表示元素上方不可见内容的像素宽度
scrollLeft
scrollLeft属性表示被隐藏在内容区域左侧的像素数。元素未滚动时,scrollLeft的值为0,如果元素被水平滚动了,scrollLeft的值大于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(){
result.innerHTML = 'scrollTop:' + test.scrollTop+';clientHeight:' + test.clientHeight + ';scrollHeight:' + test.scrollHeight
}
</script>
与scrollHeight和scrollWidth属性不同的是,scrollLeft和scrollTop是可写的
[注意]为scrollLeft和scrollTop赋值为负值时,并不会报错,而是静默失败
<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.scrollTop += 10;}
btn2.onclick = function(){test.scrollTop -= 10;}
</script>
页面滚动
理论上,通过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
回到顶部
可以利用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>
还有两个window的只读属性可以获取整个页面滚动的像素值,它们是pageXOffset和pageYOffset
pageXOffset
pageXOffset表示水平方向上页面滚动的像素值
pageYOffset
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>
滚动方法
scrollTo(x,y)
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>
scrollBy(x,y)
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>
scrollIntoView()
Element.scrollIntoView方法滚动当前元素,进入浏览器的可见区域
该方法可以接受一个布尔值作为参数。如果为true,表示元素的顶部与当前区域的可见部分的顶部对齐(前提是当前区域可滚动);如果为false,表示元素的底部与当前区域的可见部分的尾部对齐(前提是当前区域可滚动)。如果没有提供该参数,默认为true
<body style="height:1000px">
<div id="test" style="height:100px;width:100px;position:absolute;left:0;top:500px;background-color:green"></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>
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;background-color:green"></div>
<button id='btn' style="position:fixed">滚动到页面中间</button>
<script>
btn.onclick = function(){
test.scrollIntoViewIfNeeded(true)
};
</script>
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>
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>
滚动事件
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>
最后
本文详细介绍了滚动scroll的知识,基本上囊括了关于滚动现有的所有属性和方法。本文中并未详细介绍滚动条,详细内容移步至此
下文将以实例的形式,对滚动的属性和方法进行应用,总结回到顶部的多种写法,并尝试优化
欢迎交流
深入理解滚动scroll的更多相关文章
- jacascript 滚动 scroll 与回到顶部
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 滚动 scroll scrollHeight 表示元素的总高度,包括由于溢出而无法展示在网页的不可见部分: ...
- jacascript 滚动scroll
滚动 scroll scrollHeight 表示元素的总高度,包括由于溢出而无法展示在网页的不可见部分: scrollWidth 表示元素的总宽度,包括由于溢出而无法展示在网页的不可见部分: 没有滚 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- 【前端性能】高性能滚动 scroll 及页面渲染优化--转发
本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的关系,节流与防抖,pointer-events:none 优化滚动.因为本文涉及了很多很多基础,可以对照上面的知 ...
- 高性能滚动 scroll 及页面渲染优化
最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...
- 前端高性能滚动 scroll 及页面渲染优化
前言 最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作.本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲 ...
- 元素滚动 scroll 系列
定义 : scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小.滚动距离等. 常用属性 : 需要用到页面滚动事件scroll因为是页面滚动,所以事件源是docu ...
- JQUERY 滚动 scroll事件老忘记 标记下
制作笔记 这个scroll事件 老忘记.... 写的太垃圾了 希望有路过的大神指点的吧~ 这个貌似应该写个函数里 调用好些的吧~ 写个类这样的 也方便扩展貌似 不过就是想想 ~ $(windo ...
- 记录下vue keep-alive IOS下无法保存滚动scroll位置的问题
最近 做的项目,遇到了一点小麻烦,就是我一个页面A页面是加载 列表数据 ,B页面是展示详细信息的.A进去B时,缓存A页面. 效果 做出来 后,缓存是缓存数据 了,但是当我A页面的列表数据 好多,要滚动 ...
随机推荐
- C++ 结构体数组回调C#代码,c#数组只有一条
C# 方法 [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall, CharSet = CharSet.Ansi)] public ...
- C#获取存储过程返回值和输出参数值的方法
//转自网络,先留个底 1.获取Return返回值 //存储过程 //Create PROCEDURE MYSQL // @a int, // @b int //AS // return @a + @ ...
- 【BZOJ3314】 [Usaco2013 Nov]Crowded Cows 单调队列
第一次写单调队列太垃圾... 左右各扫一遍即可. #include <iostream> #include <cstdio> #include <cstring> ...
- Where product development should start
We all need to know our customers in order to create products they’ll actually buy. This is why the ...
- tomcat context配置
<Context path="/ext" docBase="/eqp/export" /> 访问目录 ...
- Python之路Day13--堡垒机
一.前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功能只是堡垒机所具备的功能属性中的 ...
- SQL Server 触发器
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- Apache服务器在80端口配置多域名虚拟主机的方法
我们在配置一台服务器的时候,如果只运行一个站点,往往过于浪费资源.Nginx和Apache都可以通过配置虚拟主机实现多站点.配置虚拟主机的方式主要有两种,一种是多个不同端口对应的多个虚拟主机站点,一种 ...
- Mac读取Andriod屏幕截图
int main(int argc, const char * argv[]) { // insert code here... string str3 = "/Users/Ethan/Do ...
- mysql 内连接、左连接、右连接
记录备忘下,初始数据如下: DROP TABLE IF EXISTS t_demo_product; CREATE TABLE IF NOT EXISTS t_demo_product( proid ...