悬停时生涩的水平滚动 [英] Jerky horizontal scroll on hover

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

问题描述

我正在使用以下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.

对此有什么解决办法吗?

Is there any solution for this?

谢谢

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/

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

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天全站免登陆