我正在学习JavaScript和jquery,并尝试创建自己的轮播。
我偶然发现的当前问题如下。当用户停止在圆盘传送带中滚动时,我可以运行一个功能,将我的目标圆盘传送带项目居中放置到所需的位置。我在小提琴中用黑线说明了这一点。这是我将该项目居中的功能:
jQuery.fn.CenterToPoint = function(){
return this.each(function(){
Offset = $(this).offset().left;
Width = $(this).width();
Illuminate_Point = 0.45 * $(window).width();
ScrollLeft = Illuminate_Point - (Offset+Width/2);
$Container.animate({scrollLeft: "-=" + ScrollLeft},450);
});
}
但是,即使动画正在运行,我也希望用户能够滚动。运行该动画但在轮播上使用用户单击,鼠标滚动或触控板时,如何杀死该动画?
这是我的jFiddle:
http://jsfiddle.net/ptp05jvo/
最佳答案
据我了解,您的问题是:
到达所需点(黑线)后,盒子会抽动。
设置动画时(框朝黑线移动),用户输入将导致框“跳转”。在这种情况下,您希望用户输入覆盖动画滚动。
我没有解决整个问题,但是到目前为止,这是我得到的:http://jsfiddle.net/ptp05jvo/3/
我设法通过在.animate()
中添加以下选项来停止第一个问题(抽搐)。
always: function() {
clearTimeout($Container.data('scrollTimeout'));
isSystemScroll = false;
}
当使用
.animate()
设置动画以进行滚动时,jQuery会滚动该元素,并且该元素实际上被视为滚动,因此会触发.scroll()
事件。这可以是好/坏。在您的轮播情况下,这有点不好,因为在
.CenterToPoint()
事件中调用了.scroll()
,这意味着每次jQuery动画框居中时都会调用它。这就是导致抽动问题的原因。
.CenterToPoint()
不断在`.scroll()'事件中被调用。因此,我添加的选项将阻止此操作。为了分开关注点,我添加了新的jQuery函数
scrollStopped
来处理滚动停止事件。我向代码中引入了一个名为
isSystemScroll
的新变量。这个想法是要识别滚动是否来自用户/动画。这样,我们可以优先考虑用户输入以覆盖动画滚动。但是,用户输入可以是任何东西,例如键盘箭头,鼠标滚轮滚动,鼠标在滚动条上单击等等。在我的示例中,我仅处理键盘箭头输入,如以下代码所示:
$(document).keyup(function () {
isSystemScroll = false;
console.log("key up");
});
显然,您可以添加其他检查以仅捕获向左/向右箭头键而不是所有键。
这种解决第二个问题。但是您仍然需要处理其他用户输入,尤其是鼠标移动滚动条。
通过测试,我发现Firefox可以更好,更流畅地渲染动画。在Firefox中,使用键盘箭头的用户输入将完美地覆盖动画。两者之间的过渡是平稳的。但是,在Chrome中,存在一些滞后/跳跃。
另外,在Chrome中,水平滚动条不会显示,而在Firefox中会显示。
值得一提的是,Firefox没有显示抽搐问题。我不确定这是否是由您的CSS引起的。我没有修改您的CSS。
我遇到了几个轮播库,并进行了相同的测试,以了解他们如何处理该问题。
猫头鹰轮播
http://owlgraphic.com/owlcarousel/demos/custom.html
仅允许拖动输入。其他用户输入被禁用(滚动条,键盘箭头等)。但是,如果尝试在动画制作过程中拖动轮播(在Chrome浏览器中),则会看到相同的跳转/滞后问题。同样,Firefox使用此库显示了更好,更流畅的动画。
光滑的
http://kenwheeler.github.io/slick/
当轮播动画时,“自动播放”选项可防止用户输入。没有滚动条,只能使用键盘箭头移动。
结论
从这个长答案得出的结论是,如果您想构建自己的轮播,您可以做的事情很少:
限制用户输入,仅允许某些输入。
禁用滚动条。
或者,您可以使用现有的库。