窗口事件 - JavaScript 事件
窗口事件
scroll 事件
scroll
事件在文档或文档元素滚动时触发,主要出现在用户拖动滚动条。
window.addEventListener('scroll', callback);
该事件会连续地大量触发,所以它的监听函数之中不应该有非常耗费计算的操作。推荐的做法是使用requestAnimationFrame
或setTimeout
控制该事件的触发频率,然后可以结合customEvent
抛出一个新事件。
(function () { var throttle = function (type, name, obj) { var obj = obj || window; var running = false; var func = function () { if (running) { return; } running = true; requestAnimationFrame(function() { obj.dispatchEvent(new CustomEvent(name)); running = false; }); }; obj.addEventListener(type, func); }; // 将 scroll 事件转为 optimizedScroll 事件 throttle('scroll', 'optimizedScroll'); })(); window.addEventListener('optimizedScroll', function() { console.log('Resource conscious scroll callback!'); });
上面代码中,throttle()
函数用于控制事件触发频率,它有一个内部函数func()
,每次scroll
事件实际上触发的是这个函数。func()
函数内部使用requestAnimationFrame()
方法,保证只有每次页面重绘时(每秒60次),才可能会触发optimizedScroll
事件,从而实际上将scroll
事件转换为optimizedScroll
事件,触发频率被控制在每秒最多60次。
改用setTimeout()
方法,可以放置更大的时间间隔。
(function() { window.addEventListener('scroll', scrollThrottler, false); var scrollTimeout; function scrollThrottler() { if (!scrollTimeout) { scrollTimeout = setTimeout(function () { scrollTimeout = null; actualScrollHandler(); }, 66); } } function actualScrollHandler() { // ... } }());
上面代码中,每次scroll
事件都会执行scrollThrottler
函数。该函数里面有一个定时器setTimeout
,每66毫秒触发一次(每秒15次)真正执行的任务actualScrollHandler
。
下面是一个更一般的throttle
函数的写法。
function throttle(fn, wait) { var time = Date.now(); return function() { if ((time + wait - Date.now())上面的代码将
scroll
事件的触发频率,限制在一秒一次。
lodash
函数库提供了现成的throttle
函数,可以直接使用。window.addEventListener('scroll', _.throttle(callback, 1000));本书前面介绍过
debounce
的概念,throttle
与它区别在于,throttle
是“节流”,确保一段时间内只执行一次,而debounce
是“防抖”,要连续操作结束后再执行。以网页滚动为例,debounce
要等到用户停止滚动后才执行,throttle
则是如果用户一直在滚动网页,那么在滚动过程中还是会执行。resize 事件
resize
事件在改变浏览器窗口大小时触发,主要发生在window
对象上面。var resizeMethod = function () { if (document.body.clientWidth该事件也会连续地大量触发,所以最好像上面的
scroll
事件一样,通过throttle
函数控制事件触发频率。fullscreenchange 事件,fullscreenerror 事件
fullscreenchange
事件在进入或退出全屏状态时触发,该事件发生在document
对象上面。document.addEventListener('fullscreenchange', function (event) { console.log(document.fullscreenElement); });
fullscreenerror
事件在浏览器无法切换到全屏状态时触发。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!