【问题标题】:Jerky horizontal scroll on hover悬停时水平滚动不顺畅
【发布时间】:2016-12-27 12:26:54
【问题描述】:

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

有什么解决办法吗?

谢谢

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/

【问题讨论】:

    标签: jquery scroll hover carousel mousemove


    【解决方案1】:

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

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

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

    更新的小提琴: 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 方法使事情变得多么流畅.

    更新

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

    更新

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

    【讨论】:

    • 谢谢!!!只有一个问题,如果我在同一页面上有多个轮播怎么办?为了考虑这种情况,我需要对您的脚本进行哪些更改?
    • 很好的答案对我帮助很大。谢谢
    【解决方案2】:

    我对我的 JS 代码进行了一些更改,现在当鼠标在容器内移动时,滚动动画不再那么不稳定了。如果有人有更好的解决方案,请随时在此处发布。

    JS:

    var b = null;
    $( '.carousel-frame ul' ).on( '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 );
            }
            if ((b == false) || (b == null)) {
                b = true;
                container.stop( true ).animate( {scrollLeft: '-=600'}, 1000, 'linear', direction );
            }
        } else {
            var direction = function() {
                container.animate( {scrollLeft: '+=600'}, 1000, 'linear', direction );
            }
            if ((b == true) || (b == null)) {
                b = false;
                container.stop( true ).animate( {scrollLeft: '+=600'}, 1000, 'linear', direction );
            }
        }
    }).on ( 'mouseleave', function() {
        var container = $(this).parent();
        container.stop( true );
        b = null;
    });
    

    小提琴:

    https://jsfiddle.net/dk6f3snf/1/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多