悬停时水平滚动不顺畅 [英] Jerky horizontal scroll on hover

查看:20
本文介绍了悬停时水平滚动不顺畅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用下面的 JS 代码来构建一个水平图像轮播,它可以在悬停时滚动.mousemove 事件检测鼠标在容器上的位置并相应地向左或向右滚动.一切都按我的预期工作,但是如果我在动画运行时将鼠标移到容器上,它会变得有点生涩.

I'm using the following JS code to build a horizontal image carousel that scrolls on hover. The mousemove event detects the position of the mouse over the container and scrolls to the left or to the right accordingly. Everything works as I expect but if I move the mouse over the container while the animation is running, it becomes a bit jerky.

有什么解决办法吗?

谢谢

JS:

$( '.carousel-frame ul' ).mousemove( function(e) {
    var container = $(this).parent();
    if ((e.pageX - container.offset().left) < container.width() / 2) {
        var direction = function() {
            container.animate({scrollLeft: '-=600'}, 1000, 'linear', direction);
        }
        container.stop().animate({scrollLeft: '-=600'}, 1000, 'linear', direction);
    } else {
        var direction = function() {
            container.animate({scrollLeft: '+=600'}, 1000, 'linear', direction);
        }
        container.stop().animate({scrollLeft: '+=600'}, 1000, 'linear', direction);
    }
}).mouseleave( function() {
    var container = $(this).parent();
    container.stop();
});

CSS:

.carousel-frame {
    width: 100%;
    margin-bottom: 0.5em;
    padding-bottom: 1em;
    position: relative;
    overflow-x: scroll;
    white-space: nowrap;
}
.carousel-frame ul {
    margin: 0;
    padding: 0;
    height: 100%;
    list-style: none;
}
.carousel-frame li.carousel-item {
    cursor: pointer;
    display: inline-block;
    margin: 0 5px 0 0;
    padding: 0;
}

HTML:

<div class="carousel-frame">
  <ul>
    <li class="carousel-item">
      <img src="http://placehold.it/200x150" />
    </li>
    <li class="carousel-item">
      <img src="http://placehold.it/200x150" />
    </li>
    <li class="carousel-item">
      <img src="http://placehold.it/200x150" />
    </li>
    <li class="carousel-item">
      <img src="http://placehold.it/200x150" />
    </li>
    <li class="carousel-item">
      <img src="http://placehold.it/200x150" />
    </li>
  </ul>
</div>

小提琴:

https://jsfiddle.net/dk6f3snf/

推荐答案

要获得流畅的效果,需要进行两个主要更改:

There are two major changes required to get a smooth effect:

一:尝试创建流畅的动画时,请始终使用 window.requestAnimationFrame...

One: When trying to create smooth animations always go for window.requestAnimationFrame...

二:在您的示例中,您正在检测 ul 上的鼠标事件,这意味着每次光标通过 li 之间的间隙"时动画都会中断元素.

Two: In your example you are detecting mouse events on the ul, which means that the animation is interrupted every time the cursor passes a "gap" between the li elements.

更新的小提琴:https://jsfiddle.net/dk6f3snf/6/

var speed = 0;
var scroll = 0;
var container = $('.carousel-frame');
var container_w = container.width();
var max_scroll = container[0].scrollWidth - container.outerWidth();

container.on('mousemove', function(e) {
    var mouse_x = e.pageX - container.offset().left;
    var mouseperc = 100 * mouse_x / container_w;
    speed = mouseperc - 50;
}).on ( 'mouseleave', function() {
    speed = 0;
});

function updatescroll() {
		if (speed !== 0) {
    		scroll += speed / 5;
        if (scroll < 0) scroll = 0;
        if (scroll > max_scroll) scroll = max_scroll;
    		$('.carousel-frame').scrollLeft(scroll);
    }
    $("#speed").html('Speed: ' + speed);
    $("#scroll").html('Scroll: ' + scroll);
    window.requestAnimationFrame(updatescroll);
}
window.requestAnimationFrame(updatescroll);

.carousel-frame {
    width: 100%;
    margin-bottom: 0.5em;
    padding-bottom: 1em;
    position: relative;
    overflow-x: scroll;
    white-space: nowrap;
 }
 .carousel-frame ul {
    margin: 0;
    padding: 0;
    height: 100%;
    list-style: none;
}
.carousel-frame li.carousel-item {
    cursor: pointer;
    display: inline-block;
    margin: 0 5px 0 0;
    padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel-frame">
      <ul>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
        <li class="carousel-item">
          <img src="http://placehold.it/200x150" />
        </li>
      </ul>
    </div>
    <div id="speed"></div>
    <div id="scroll"></div>

请注意,我还使速度取决于光标与中间的距离,而不是仅取决于光标在哪一半结束并减慢速度...主要是为了演示使用 window.requestAnimationFrame 的流畅程度 方法制造东西.

Note that I also made the speed depend on how far the cursor is from the middle, rather than only which half it is over and slowed it way down... mostly to demonstrate how smooth using the window.requestAnimationFrame method makes things.

实际上,为了使不同设备上的速度保持一致,并且不管其他窃取"资源的东西,我想你还需要考虑帧之间经过的时间.我已经更新了演示这个的小提琴:https://jsfiddle.net/dk6f3snf/7/

Actually to make the speed consistent on different devices and regardless of other stuff "stealing" resources, I guess you need to consider the time elapsed between frames as well. I've updated the fiddle demonstrating this: https://jsfiddle.net/dk6f3snf/7/

我认为您关于单个页面上的多个轮播的问题与您的原始问题完全不同......但一种方法是将其包装在一个简单的插件中 - 例如:https://jsfiddle.net/dk6f3snf/8/

I think your question about multiple carousels on a single page is an entirely different subject than your original question... but one way would be to just wrap it in a simple plugin - example: https://jsfiddle.net/dk6f3snf/8/

这篇关于悬停时水平滚动不顺畅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆