如何在两个窗口之间同步滚动

时间:2015-07-20 19:03:30

标签: javascript jquery html

我的网站上有一个弹出窗口,显示有关在主屏幕中显示的元素的其他信息。我需要同步两个窗口之间的滚动,这样当用户滚动其中一个窗口时,另一个窗口会在同一个ammount中自动滚动。

我能够使用jquery scroll事件,并使用scrollTop函数设置滚动位置。像这样的东西:

$("#localDiv").scroll(function() {        
    var scrollPos = $("#localDiv").scrollTop();
    $("targetElement").scrollTop( scrollPos );
});

我已经简化了实际代码,因为我必须做一些工作才能到达另一个窗口中的元素,但这不是问题。

问题是,此代码在Chrome和IE中运行良好,但在FireFox中,滚动速度非常慢。

我在这里创建了一个示例:http://jsfiddle.net/Lv2dw787/4/。这个问题似乎与DIV在同一页面中的情况相似。您可以注意到,当禁用滚动同步时,速度将恢复正常。

有没有人知道如何在FireFox上修复此问题?

Dave Chen回答后编辑:

接受的答案解决了我的问题,但它有一个问题。我首先尝试这样做:

lock = true;
try {
    var scrollPos = $("#contentDivA").scrollTop();
    $("#contentDivB").scrollTop( scrollPos );
}
finally
{
    lock = false; 
}

但是$("#contentDivB").scrollTop( scrollPos );行似乎只在当前函数完成执行后才在divB上生成一个scroll事件,所以try..finally的最后部分在此之前执行。所以我不得不这样做:

lock = true;

var scrollPos = $("#contentDivA").scrollTop();
$("#contentDivB").scrollTop( scrollPos );

和Div​​B滚动事件:

if (lock)
    lock = false;
else {
   (Do the scroll on DivA)
} 

1 个答案:

答案 0 :(得分:4)

原因是有两个原因:

  1. Firefox在滚动时进行平滑
  2. jQuery的scrollTop将触发事件
  3. 让我们看一些伪代码:

    When divA is scrolled -> scroll divB to the same spot
    When divB is scrolled -> scroll divA to the same spot
    

    问题是当你scroll divA or divB to the same spot时,它还会导致when再次发生。

    例如,当您滚动divA时,会发生以下情况:

    scroll divA -> scroll divB to the same spot -> scroll divA to the same spot
    

    这会导致divA在滚动一点之后粘在同一个位置,从而导致firefox中的缓慢效果。

    解决方法是在滚动时忽略滚动事件:

    $(document).ready(function() {
    
        var ignore = false;
    
        $("#contentDivA").scroll(function() {  
            var tmpIgnore = ignore;
            ignore = false;
            if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
            {
                var scrollPos = $("#contentDivA").scrollTop();
                scrollTop($("#contentDivB"), scrollPos);
            }
        });
    
        $("#contentDivB").scroll(function() {
            var tmpIgnore = ignore;
            ignore = false;
            if (!tmpIgnore && $("#chkSyncEnabled")[0].checked)
            {
                console.log("here");
                var scrollPos = $("#contentDivB").scrollTop();
                scrollTop($("#contentDivA"), scrollPos);
            }
        });
    
        function scrollTop(el, position) {
            ignore = true;
            el.scrollTop(position);
        }
    });
    

    Example