---恢复内容开始---

今天在学习javascript的过程中被onscroll这个东西堵了一下午.心情极度郁闷.

在高度较大的网页中,我们通常会加一个返回顶部的按钮,方便用户操作.

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
div{height:300px;}
#btn1{position:fixed;bottom:0;right:0;}
</style>
<script type="text/javascript">
window.onload = function(){
var oDiv = document.getElementsByTagName('div');
var oBtn = document.getElementById('btn1');
var timer = null;
var oSys = true;
var i = 0;
for (i = 0;i<oDiv.length;i++)
{
if(i%2 == 0)
{
oDiv[i].style.background = 'yellow';
}else if(i%3 == 0)
{
oDiv[i].style.background = 'red';
}else if(i%5 == 0)
{
oDiv[i].style.background = 'blue';
}else
{
oDiv[i].style.background = 'green';
}
}
window.onscroll = function(){
if(!oSys)
{
clearInterval(timer);
}
oSys = false;
}
oBtn.onclick = function(){ timer = setInterval(function(){ var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var iSpeed = Math.floor(-scrollTop/8);
oSys = true;
if(!scrollTop)
clearInterval(timer);
document.documentElement.scrollTop = scrollTop + iSpeed ;
},300) }
}
</script>
</head>
<body>
<input type="button" id="btn1" value="backtotop" />
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>

弄这么多DIV纯粹是为了填充高度,其实大可不必,设置一个高大上的DIV足以,但是当时脑残了.废话不说.实现的功能就是点击返回顶部按钮的时候,页面可以以一个舒服的缓慢减速效果移动到顶部.这当中就产生了一个问题.如果页面很长,用户在点击返回顶部按钮后,页面移动到顶部的过程中想停下来(也许发现了什么有趣的东西),如何去停止计时器.

大家知道,在页面想顶部移动过程中,势必要触发window.scroll事件.如果要在触发事件后停下来的话,很简单:

window.onscroll = function(){
clearInterval(timer);
}

这样,只要用户在页面返回顶部过程中拖动滑动条,页面就会停止自动滚动.但是很明显,返回顶部的函数也会触发window.onscroll事件,这样,我们点击返回顶部后,页面向上移动一下,就会停下来.因为计时器被清除了.

那么如何才能让浏览器识别出到底是系统在执行函数的自动滚动,还是用户自己操作的呢?

在第一段代码中,我们声明了一个变量:oSys,定义为true.之后我们在计时器函数中插入了它(请自己看代码).这样每次计时器执行内置函数的时候,都会初始化oSys的值为true.

结合下面的代码段:

window.onscroll = function(){
oSys = false; }

效果就是,当计时器中的函数在执行过程中,oSys变量的值被初始化为true.而一旦函数执行滚动语句,就触发window.onscroll事件,导致oSys的值变为false?为了检验这个结论,下了下面代码

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div style="height:5000px;width:100%;background:gray;"></div>
<input type="button" id="btn1" value="toTop" style="position:fixed;bottom:0;right:0;"/>
<script type="text/javascript">
var oSys = true;
var oBtn = document.getElementById('btn1');
oBtn.onclick = function(){ setInterval(function(){
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var iSpeed = Math.floor(-scrollTop/8);
var oSys = true;
if(scrollTop){
document.documentElement.scrollTop = document.body.scrollTop = scrollTop + iSpeed;
alert(oSys);
} },3000)
window.onscroll = function(){
oSys = false;
}
}
</script>
</body>
</html>

结果发现每次弹出的都是true.这说明我们上面的推论是错误的.

那就是说window.onscroll事件是在滚动完成后触发的,而不是滚动的同时.这也符合函数按顺序依次执行的逻辑:在滚动函数执行完成后,进入window.onscroll触发的函数.那么可以确定,每次进入window.onscroll函数时,oSys的值总是true.而触发onscroll事件后,进入onscroll引用的函数function(){oSys = false},然后oSys的值变为false.

假设我们加上这样一段代码

window.onscroll = function(){
if(!oSys)
{
clearInterval(timer);
}
oSys = false;
}

当计时器函数的一个周期执行完毕后,并且触发的onscroll事件函数也执行完毕后,oSys的值一定为false.此时如果又进入了onscroll事件函数,那么有两种可能.

1.计时器函数进入了下一次循环,初始化oSys的值为true.执行完自身后,触发onscroll事件,进入onscroll触发的匿名函数,此事,oSys的值为true.跳过if语句,不清除计时器.

2.计时器还没有进入下一次循环,是用户手动操作触发了onscroll事件的函数,那么此时oSys的值由于没有进过计时器函数内部的oSys初始化,所以值仍然为false.所以会进入if语句,清除计时器.

理解了.

关于javascript的window.onscroll方法的更多相关文章

  1. $(document).ready() 和 window.onload 方法比较

    说明 页面加载文档完毕后,浏览器会通过 Javascript 为 DOM 元素添加事件. Javascript 使用 window.onload 方法,而 jQuery 使用 $(document). ...

  2. Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间       ...

  3. addEventListener解决多个window.onscroll共存的2个方法

    方法1.(注意第一个和第二个的先后次序) window.onscroll=function(){console.log('第一个');} var oldMethod = window.onscroll ...

  4. javaScript 对象的hasOwnProperty方法打印window自定义属性

    for (var name in window) { if (window.hasOwnProperty(name)) { window.console.log ( name + " : & ...

  5. Jquery中$(document).ready() 和 JavaScript中的window.onload方法 比较

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的.   1.执行时间 win ...

  6. javascript实现图片延迟加载方法汇总(三种方法)

    看到一些大型网站,页面如果有很多图片的时候,当你滚动到相应的行时,当前行的图片才即时加载的,这样子的话页面在打开只加可视区域的图片,而其它隐藏的图片则不加载,一定程序上加快了页面加载的速度,跟着小编一 ...

  7. 收集JavaScript中常用的方法函数

    本文中,收集了一些比较常用的Javascript函数,希望对学习JS的朋友们有所帮助. 1. 字符串长度截取 function cutstr(str, len) { var temp, icount ...

  8. 你想的到想不到的 javascript 应用小技巧方法

    javascript 在前端应用体验小技巧继续积累. 事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElemen ...

  9. JavaScript常用对象的方法和属性

    ---恢复内容开始--- 本文将简单介绍JavaScript中一些常用对象的属性和方法,以及几个有用的系统函数. 一.串方法 JavaScript有强大的串处理功能,有了这些串方法,才能编写出丰富多彩 ...

随机推荐

  1. css笔记12:块元素和行内元素

    1.概念: 行内元素:又叫内联元素,内联元素只能容纳文本或者其他内联元素,常见的内联元素有<span><a> 块元素:块元素一般都是从新行开始,可容纳文本,其他内联元素和其他块 ...

  2. Android二手交易平台,dagger2+mvp+Bmob后台云搭建

    二手交易平台 我的毕业设计项目安卓源码,二手交易平台,dagger2+mvp+Bmob后台云搭建,集成了百度地图,友盟三方登录等 系统架构 Dagger2+MVP分层,完成了一次正常的retrofit ...

  3. C#中登录验证FormsAuthentication

    1:前台编写一个登录界面,这里为了简化,只有用户名和密码 代码如下: <form method="post" action="/User/CheckLogin&qu ...

  4. Linux命令行下cp,rm,mv命令的使用

    以下的内容来源于<鸟哥的私房菜> Linux命令行下的复制.删除与移动:cp,rm,mv cp(copy)复制        cp这个命令的用途很多,除了单纯的复制之外,还可以创建链接文件 ...

  5. RedHat7搭建yum源服务器

    1.新建目录 # mkdir -p /content/rhel7/x86_64/{isos,dvd}/ 2.上传RedHat安装光盘镜像,上传后的路径为 /content/rhel7/x86_64/i ...

  6. Dubbo服务调用的动态代理和负载均衡

    Dubbo服务调用的动态代理及负载均衡源码解析请参见:http://manzhizhen.iteye.com/blog/2314514

  7. hdu 4005 边连通度与缩点

    思路:先将图进行缩点,建成一颗树,那么如果这是一条单路径树(即最大点度不超过2),就不在能删的一条边,使得不连通.因为将其头尾相连,形成一个圈,那么删任意一条边,图都是连通的. 上面的是无解的情况,如 ...

  8. 使用迭代器遍历List的时候修改List报ConcurrentModificationException异常的解决办法

    为了避免这种异常,我们可以使用CopyOnWriteArrayList来代替ArrayList,CopyOnWriteArrayList支持并发访问,所以同时进行迭代和修改是没有问题的.

  9. 查锁表及kill

    当一个表一直被锁住而无法进行操作的时候,可以用如下方法 select l.session_id sid, s.serial#, l.locked_mode 锁模式, l.oracle_username ...

  10. 为什么Java byte 类型的取值范围是-128~127 (转)

    概念:负数的补码是该 数 绝 对 值 的 原 码 按 位 取 反 ,然 后 对 整个数 加 1 步骤: 1.确定byte是1个字节,也就是8位 2.最大的应该是0111 1111,因为第一位是符号位, ...