我正在尝试自定义section-scroll
,其中在动画运动时禁用滚动事件。当滚动动画正在进行时,我尝试了隐藏溢出和其他类似的功能来应用,但没有成功。
JS fiddle示例
CSS
.stop-scrolling {
height: 100%;
overflow: hidden;
}
JS示例:
$('html').on('wheel', function(event) {
if (event.originalEvent.deltaY > 0) {
//scroll down
counter++;
$('body').addClass('stop-scrolling');
console.log("Start animacije");
setTimeout(function () {
$('body.stop-scrolling').removeClass('stop-scrolling');
console.log("End animation");
}, 800);
if (!(counter > maxSections)) {
$('html, body').animate({
scrollTop: $( $("#sect-"+counter) ).offset().top
}, 800);
}
} else {
//scroll up
counter--;
$('body').addClass('stop-scrolling');
console.log("Start animation");
setTimeout(function () {
$('body.stop-scrolling').removeClass('stop-scrolling');
console.log("End animation");
}, 800);
if (!(counter < 1)) {
$('html, body').animate({
scrollTop: $( $("#sect-"+counter) ).offset().top
}, 800);
}
}
if (counter <= 0) {
counter = 1;
}
else if (counter >= 3) {
counter = maxSections;
}
console.log(counter);
});
如果在动画进行时滚动,则滚动将继续,直到到达节的末尾。
是否可以在动画进行时禁用滚动事件?
这里有一个简单的修复程序,代码修改较少。
只需声明一个表示滚动状态的变量。使用此状态,如果当前正在滚动,则可以忽略传入的滚动事件。
let scrolling = false;
$('html').on('wheel', function(event) {
if (scrolling) {
return;
} else {
scrolling = true;
setTimeout(function () {
scrolling = false;
}, 800 /* animation duration */);
}
...
这是最后一个小提琴环节。
使用setTimeout
功能,您可以将滚动状态重置为false
,以便接收新的事件。
您可以使用脚本来阻止滚动事件,而不是使用CSS。
可以使用.animate
方法的onComplete
参数在动画结束后运行回调。
这样,您就可以使用标志变量来确定页面是否正在滚动。
整个过程大概是这样的:
- 动画开始
- 标志动画设置为true
- 阻止滚动
- 动画结束
- 标志动画设置为false
- 取消阻止滚动
这是一个最小且可重复的例子。它可能有一些错误,但它应该能解决你的主要问题。
$(document).ready(function(){
'use strict';
// Flag to decide whether or not scroll is allowed.
let animating = false;
$(window).on('scroll', (e) => {
if (animating){
// Block scroll
e.preventDefault();
}
});
$('.section').on('wheel', e => {
e.stopPropagation();
// Do not run this function again when animation is happening.
if (animating){
return;
}
const $target = $(e.target);
const isScrollDown = e.originalEvent.deltaY > 0;
// Choose whether to scroll to next or previous section.
const $targetSection = isScrollDown ? $target.next('.section') : $target.prev('.section');
// Check whether or not there is a target
const hasTargetSection = $targetSection.length > 0;
// Only animate when there is a target.
if (hasTargetSection){
// Flag animation start
animating = true;
$('html, body').animate(
// Animation properties
{
scrollTop: $targetSection.offset().top
},
// Animation duration
800,
// Function to run after animation ends
() => {
// Flag animation ended
animating = false;
}
);
}
});
});
html, body, #app {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.section {
width: 100%;
height: 100%;
font-size: 3em;
display: flex;
justify-content: center;
align-items: center;
}
.a {
background-color: #f008;
}
.b {
background-color: #0f08;
}
.c {
background-color: #00f8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app">
<div class="section a">Section A</div>
<div class="section b">Section B</div>
<div class="section c">Section C</div>
</div>
您所要求的叫做节流。我建议你阅读这个链接以更好地理解它。
因此,要修复代码,只需要为wheel
事件侦听器启用节流。
像这样:
let throttle = (fn, timedelay) => {
let pass = true;
return function () {
if (pass) {
setTimeout(() => {
fn.apply(this, arguments);
pass = true;
}, timedelay);
pass = false;
}
};
};
let scrollFunction = throttle(function(event) {
// your code
}, 200); // 200 miliseconds sounds good
$('html').on('wheel', scrollFunction);
这是一个工作代码:https://jsfiddle.net/d1fcL5en/