【问题标题】:Scrolling multiple elements/DIVs滚动多个元素/DIV
【发布时间】:2014-11-20 21:34:26
【问题描述】:

我想同时滚动多个 div。

我有一些可以工作的东西,但它在慢速机器(尤其是移动设备)上性能不佳

<!-- HTML -->
<div class="container">
    <div class="row">
        <div class="scroller">
            <div>some really long content that just keeps going on and on and on and on and on and on and on and on and on and on and on and on and on</div>
        </div>
    </div>
    <div class="row">
        <div class="scroller">
            <div>some really long content that just keeps going on and on and on and on and on and on and on and on and on and on and on and on and on</div>
        </div>
    </div>
    <div class="row">
        <div class="scroller">
            <div>some really long content that just keeps going on and on and on and on and on and on and on and on and on and on and on and on and on</div>
        </div>
    </div>
    <div class="row">
        <div class="scroller">
            <div>some really long content that just keeps going on and on and on and on and on and on and on and on and on and on and on and on and on</div>
        </div>
    </div>
    <div class="row">
        <div class="scroller">
            <div>some really long content that just keeps going on and on and on and on and on and on and on and on and on and on and on and on and on</div>
        </div>
    </div>
</div>
<style>
/* CSS */
    .container { width:300px; }
    .scroller { width:100%; height:40px; padding:0 0 16px; line-height:40px; overflow-x:auto; overflow-y:hidden; white-space:nowrap; }
</style>

<script>
// jQuery
$(".scroller").scroll(function(){
    $(".scroller").scrollLeft($(this).scrollLeft());
});
</script>

Here's a pen/demo

我可以看到,无论我滚动一个元素,它都会滚动同一个类的其他元素,但是因为我在该类上设置了一个滚动“侦听器”,所以该函数会再次为每个其他元素触发,因为它们已使用 scrollLeft 方法滚动。

有人知道我可以如何改进吗?

【问题讨论】:

  • 所以,只是为了澄清一下:所有卷轴同时滚动的行为是有意的,它只是关于性能?
  • 没错@Markai。
  • 它们是否应该实时更新,即当滚动条移动时,或者是否足以在滚动结束时移动它们?
  • Live是理想的,界面的想法是实时比较2行数据/文本

标签: javascript jquery html css


【解决方案1】:

您可以使用以下 sn-p:{需要一些测试,不确定它是否能处理所有情况}

$(".scroller").css('outline', 0).attr('tabindex' , -1).scroll(function(e){
    if (!$(this).is(':hover') && !$(this).is(':focus'))  return;
    $(".scroller").not(this).scrollLeft($(this).scrollLeft());
});

【讨论】:

  • 这肯定要快得多,谢谢,尽管在移动设备(android - chrome)上似乎我需要“touchstart”并等待几毫秒,直到应用 :focus 或 :hover 。这可以通过添加 .scroller:hover, .scroller:focus { background-color:#333; 来演示。 } 到 css
【解决方案2】:

您可以在调用scrollLeft() 之前禁用所有元素的滚动处理程序,然后在之后重新启用滚动处理程序。 这将防止处理程序被重复调用。

var scrollHandler = function(){
  var $scrollers = $(".scroller");
  $scrollers.off("scroll", scrollHandler);
  $scrollers.scrollLeft($(this).scrollLeft());
  setTimeout(function(){$scrollers.on("scroll", scrollHandler);}, 0);
}

$(".scroller").on("scroll", scrollHandler);

【讨论】:

  • 在我看来,你应该延迟重新绑定:setTimeout(function(){$scrollers.on("scroll", scrollHandler);}, 0);
  • 我想这是最干净的方法!
  • 不幸的是,这似乎在我的手机上具有相当的性能。好主意!
【解决方案3】:

你可以只滚动滚动位置不同的元素吗?

$(".scroller").on('scroll', function(event){
  var a = $(this).scrollLeft();
  $(".scroller").each(function(){
    var b = $(this).scrollLeft();
    if(a !== b){
      $(this).scrollLeft(a);
    }
  });
});

【讨论】:

  • 不幸的是,仍然会为其他 DIV 触发滚动事件。虽然我不确定 OP 问题的确切问题是什么
【解决方案4】:

我认为最大的问题是,您在将事件侦听器附加到事件侦听器内部的元素上触发滚动事件。如果您将其从要滚动的元素中排除,您应该会在低硬件上获得很大的性能提升:

$(".scroller").scroll(function(e){
    $(".scroller").not(this).scrollLeft($(this).scrollLeft());
});

【讨论】:

  • 我最初尝试过这个,问题是“$(this).scrollLeft()”在另一个“.scroller”上重新运行整个方法,而后者又调用自己......这可以通过将其添加到滚动方法中来显示:var $index = $(this).index(".scroller"); // this is the index to ignore. console.log($index);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
相关资源
最近更新 更多