Synchronized scrolling using jQuery?

后端 未结 8 1187
你的背包
你的背包 2020-11-28 09:29

I am trying to implement synchronized scrolling for two DIV with the following code.

DEMO

$(document).ready(function() {
    $(\"#div1\"         


        
相关标签:
8条回答
  • 2020-11-28 09:46

    If the divs are of equal sizes then this code below is a simple way to scroll them synchronously:

    scroll_all_blocks: function(e) {
            var scrollLeft = $(e.target)[0].scrollLeft;
    
            var len = $('.scroll_class').length;
            for (var i = 0; i < len; i++)
            {
                $('.scroll_class')[i].scrollLeft = scrollLeft;
            }
    
        }
    

    Here im using horizontal scroll, but you can use scrollTop here instead. This function is call on scroll event on the div, so the e will have access to the event object. Secondly, you can simply have the ratio of corresponding sizes of the divs calculated to apply in this line $('.scroll_class')[i].scrollLeft = scrollLeft;

    0 讨论(0)
  • 2020-11-28 09:50

    If you don't want proportional scrolling, but rather to scroll an equal amount of pixels on each field, you could add the value of change to the current value of the field you're binding the scroll-event to.

    Let's say that #left is the small field, and #right is the bigger field.

    var oldRst = 0;
    
    $('#right').on('scroll', function () {
        l = $('#left');
        var lst = l.scrollTop();
        var rst = $(this).scrollTop();
    
        l.scrollTop(lst+(rst-oldRst)); // <-- like this
    
        oldRst = rst;
    });
    

    https://jsfiddle.net/vuvgc0a8/1/

    By adding the value of change, and not just setting it equal to #right's scrollTop(), you can scroll up or down in the small field, regardless of its scrollTop() being less than the bigger field. An example of this is a user page on Facebook.

    This is what I needed when I came here, so I thought I'd share.

    0 讨论(0)
  • 2020-11-28 09:58

    You can use element.scrollTop / (element.scrollHeight - element.offsetHeight) to get the percentage (it'll be a value between 0 and 1). So you can multiply the other element's (.scrollHeight - .offsetHeight) by this value for proportional scrolling.

    To avoid triggering the listeners in a loop you could temporarily unbind the listener, set the scrollTop and rebind again.

    var $divs = $('#div1, #div2');
    var sync = function(e){
        var $other = $divs.not(this).off('scroll'), other = $other.get(0);
        var percentage = this.scrollTop / (this.scrollHeight - this.offsetHeight);
        other.scrollTop = percentage * (other.scrollHeight - other.offsetHeight);
        // Firefox workaround. Rebinding without delay isn't enough.
        setTimeout( function(){ $other.on('scroll', sync ); },10);
    }
    $divs.on( 'scroll', sync);
    

    http://jsfiddle.net/b75KZ/5/

    0 讨论(0)
  • 2020-11-28 10:00

    I solved the sync scrolling loop problem by setting the scroll percentage to fixed-point notation: percent.toFixed(0), with 0 as the parameter. This prevents mismatched fractional scrolling heights between the two synced elements, which are constantly trying to "catch up" with each other. This code will let them catch up after at most a single extra step (i.e., the second element may continue to scroll an extra pixel after the user stops scrolling). Not a perfect solution or the most sophisticated, but certainly the simplest I could find.

    var left = document.getElementById('left');
    var right = document.getElementById('right');
    var el2;
    var percentage = function(el) { return (el.scrollTop / (el.scrollHeight - el.offsetHeight)) };
    
    function syncScroll(el1) {
      el1.getAttribute('id') === 'left' ? el2 = right : el2 = left;
      el2.scrollTo( 0, (percentage(el1) * (el2.scrollHeight - el2.offsetHeight)).toFixed(0) ); // toFixed(0) prevents scrolling feedback loop
    }
    
    document.getElementById('left').addEventListener('scroll',function() {
      syncScroll(this);
    });
    document.getElementById('right').addEventListener('scroll',function() {
      syncScroll(this);
    });
    
    
    0 讨论(0)
  • 2020-11-28 10:04

    I like pawel's clean solution but it lacks something I need and has a strange scrolling bug where it continues to scroll and my plugin will work on multiple containers not just two.

    http://www.xtf.dk/2015/12/jquery-plugin-synchronize-scroll.html

    Example & demo: http://trunk.xtf.dk/Project/ScrollSync/

    Plugin: http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js

    $('.scrollable').scrollSync();

    0 讨论(0)
  • 2020-11-28 10:10

    From the pawel solution (first answer).

    For the horizzontal synchronized scrolling using jQuery this is the solution:

    var $divs = $('#div1, #div2'); //only 2 divs
    var sync = function(e){
        var $other = $divs.not(this).off('scroll');
        var other = $other.get(0);
        var percentage = this.scrollLeft / (this.scrollWidth - this.offsetWidth);
        other.scrollLeft = percentage * (other.scrollWidth - other.offsetWidth);
        setTimeout( function(){ $other.on('scroll', sync ); },10);
    }
    
    $divs.on('scroll', sync);
    

    JSFiddle

    An other solution for multiple horizontally synchronized divs is this, but it works for divs with same width.

    var $divs = $('#div1, #div2, #div3'); //multiple divs
    var sync = function (e) {
        var me = $(this);
        var $other = $divs.not(me).off('scroll');
        $divs.not(me).each(function (index) {
            $(this).scrollLeft(me.scrollLeft());
        });
        setTimeout(function () {
            $other.on('scroll', sync);
        }, 10);
    }
    $divs.on('scroll', sync);
    

    NB: Only for divs with same width

    JSFiddle

    0 讨论(0)
提交回复
热议问题