什么是滚动吸附
实现原理
1.使用mousewheel
监听页面滚动
2.使用scrollIntoView
将元素滚动至视区
3.使用防抖函数进行优化
页面样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <html> <head> <style> * { margin: 0; padding: 0; } body { width: 100%; height: 100vh; overflow-y: auto; } body .content { width: 100%; height: 100vh; } </style> </head> <body> <div class="content" style="background: red"></div> <div class="content" style="background: yellow"></div> <div class="content" style="background: blue"></div> </body> </html>
|
1.使用mousewheel
监听页面滚动
根据e.wheelDelta
的正负来判断滚动的方向
1 2 3 4 5 6 7 8 9 10 11
| document.body.addEventListener( "mousewheel", (e) => { if (e.wheelDelta < 0) { } if (e.wheelDelta > 0) { } } );
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| document.body.addEventListener( "mousewheel", (e) => { const els = document.querySelectorAll(".content"); if (e.wheelDelta < 0) { scroll(els[0]) } if (e.wheelDelta > 0) { scroll(els[1]) } } ); function scroll(el) { if (el) { el.scrollIntoView({ behavior: "smooth", block: "center" }); } }
|
这样能实现两个class="content"
元素之间的滚动吸附,但这不具备通用性,当前页面只有两个元素,可以根据滚动方向来判断将那个元素滚动到当前视区。但如果增加元素数量,就很难判断当前要滚动哪个元素,有的人可能想着增加一个全局idx,通过上下滚动来修改idx进行判断当前应该滚动哪个元素,但因为第一步的滚动监听是持续的,因此会造成idx的不断修改,因此进入第三步,引入防抖函数.
3.使用防抖函数进行优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| let idx = 0; document.body.addEventListener( "mousewheel", debounce((e) => { const els = document.querySelectorAll(".content"); if (e.wheelDelta < 0) { idx++; if (idx > els.length - 1) idx = els.length - 1; } if (e.wheelDelta > 0) { idx--; if (idx < 0) idx = 0; } scroll(els[idx]); }, 500) ); function debounce(fn, delay = 500) { let timer = null; return function () { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn.apply(this, arguments); timer = null; }, delay); }; }
|
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <!DOCTYPE html> <html lang="zh"> <head> <style> * { margin: 0; padding: 0; } body { width: 100%; height: 100vh; overflow-y: auto; } body .content { width: 100%; height: 100vh; } </style> </head> <body> <div class="content" style="background: red"></div> <div class="content" style="background: yellow"></div> <div class="content" style="background: blue"></div> <script> let idx = 0; document.body.addEventListener( "mousewheel", debounce((e) => { const els = document.querySelectorAll(".content"); if (e.wheelDelta < 0) { idx++; if (idx > els.length - 1) idx = els.length - 1; } if (e.wheelDelta > 0) { idx--; if (idx < 0) idx = 0; } scroll(els[idx]); }, 500) ); function scroll(el) { if (el) { el.scrollIntoView({ behavior: "smooth", block: "center" }); } } function debounce(fn, delay = 500) { let timer = null; return function () { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn.apply(this, arguments); timer = null; }, delay); }; } </script> </body> </html>
|