2013-09-23 7 views
21

मैं निम्नलिखित कोड के साथ दो DIV के लिए स्क्रॉल सिंक्रनाइज़ लागू करने के लिए कोशिश कर रहा हूँ।jQuery का उपयोग कर सिंक्रनाइज़ स्क्रॉलिंग?

DEMO

$(document).ready(function() { 
    $("#div1").scroll(function() { 
     $("#div2").scrollTop($("#div1").scrollTop()); 
    }); 
    $("#div2").scroll(function() { 
     $("#div1").scrollTop($("#div2").scrollTop()); 
    }); 
}); 

#div1 और #div2 बहुत ही सामग्री है, लेकिन अलग अलग आकार हो रही है, का कहना है कि

#div1 { 
height : 800px; 
width: 600px; 
} 
#div1 { 
height : 400px; 
width: 200px; 
} 

इस कोड के साथ, मैं दो मुद्दों का सामना करना पड़ रहा है।

1) स्क्रॉल अच्छी तरह से, सिंक्रनाइज़ नहीं कर रहा है के बाद से divs विभिन्न आकार के हैं। मैं जानता हूँ कि, यह है, क्योंकि मैं सीधे scrollTop मान सेट कर रहा हूँ। मैं स्क्रॉल सामग्री का प्रतिशत खोजने के लिए और अन्य div के लिए इसी scrollTop मूल्य की गणना करने की जरूरत है। मुझे यकीन नहीं है, वास्तविक ऊंचाई और वर्तमान स्क्रॉल स्थिति कैसे प्राप्त करें।

2) यह समस्या केवल firefox में पाया जाता है। फ़ायरफ़ॉक्स में, स्क्रॉलिंग अन्य ब्राउज़रों की तरह चिकनी नहीं है। मुझे ऐसा लगता है क्योंकि उपरोक्त कोड स्क्रॉल घटनाओं का अनंत लूप बना रहा है। मुझे यकीन नहीं कर रहा हूँ क्यों यह केवल फ़ायरफ़ॉक्स के साथ हो रहा है। स्क्रॉल ईवेंट के स्रोत को खोजने का कोई तरीका है, ताकि मैं इस समस्या को हल कर सकूं।

किसी भी मदद की सराहना की जाएगी।

+0

कुछ हद तक समान प्रश्न और मेरा उत्तर: http://stackoverflow.com/a/15344759/2000060 – darshanags

उत्तर

42

आप प्रतिशत प्राप्त करने के लिए element.scrollTop/(element.scrollHeight - element.offsetHeight) का उपयोग कर सकते हैं (यह 0 और 1 के बीच एक मान होगा)। तो आप आनुपातिक स्क्रॉलिंग के लिए इस मान से अन्य तत्व के (.scrollHeight - .offsetHeight) को गुणा कर सकते हैं।

श्रोताओं को एक लूप में ट्रिगर करने से बचने के लिए आप अस्थायी रूप से श्रोता को अनबाइंड कर सकते हैं, scrollTop सेट करें और फिर से दोबारा जुड़ें।

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/

+2

आप jQuery.throttle प्लगइन का भी उपयोग कर सकते हैं: https://github.com/cowboy/jquery-throttle-debounce – LeGEC

+2

क्या div2 स्क्रॉल क्षैतिज बनाना संभव है? – RafaSashi

+2

@RafaSashi सुनिश्चित करें, बस '* ऊंचाई 'को' * चौड़ाई' और '* शीर्ष 'से' * बाएं' http: // jsfiddle में बदलें।नेट/बी 75 केजेड/102/(संपादित करें: क्षमा करें, मैंने सोचा था कि आप क्षैतिज दोनों का मतलब है, लेकिन यह इतना आसान होना चाहिए, बस 'स्क्रोलटॉफ्ट' को 'स्क्रॉलटॉप' के आधार पर बदलें और इसके विपरीत) – pawel

2

divs बराबर आकार के हैं तो नीचे दिए गए इस कोड को तुल्यकालिक उन्हें स्क्रॉल करने के लिए एक आसान तरीका है: क्षैतिज स्क्रॉल का उपयोग कर

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; 
     } 

    } 

यहाँ im, लेकिन आप कर सकते हैं इसके बजाय scrollTop का उपयोग करें। यह फ़ंक्शन div पर scroll ईवेंट पर कॉल है, इसलिए e को ईवेंट ऑब्जेक्ट तक पहुंच होगी। दूसरा, आप इस लाइन में लागू होने के लिए गणना की गई divs के संबंधित आकारों का अनुपात केवल $('.scroll_class')[i].scrollLeft = scrollLeft;

2

यही वह है जिसका मैं उपयोग कर रहा हूं। बस उन दो तत्वों के साथ syncScroll(...) फ़ंक्शन को कॉल करें जिन्हें आप सिंक्रनाइज़ करना चाहते हैं। मैंने पाया कि पावेल के समाधान में माउस के बाद धीरे-धीरे स्क्रॉल जारी रखने के साथ समस्याएं थीं या ट्रैकपैड वास्तव में ऑपरेशन के साथ किया गया था।

कार्य उदाहरण देखें here

// Sync up our elements. 
syncScroll($('.scroll-elem-1'), $('.scroll-elem-2')); 


/*** 
* Synchronize Scroll 
* Synchronizes the vertical scrolling of two elements. 
* The elements can have different content heights. 
* 
* @param $el1 {Object} 
*  Native DOM element or jQuery selector. 
*  First element to sync. 
* @param $el2 {Object} 
*  Native DOM element or jQuery selector. 
*  Second element to sync. 
*/ 
function syncScroll(el1, el2) { 
    var $el1 = $(el1); 
    var $el2 = $(el2); 

    // Lets us know when a scroll is organic 
    // or forced from the synced element. 
    var forcedScroll = false; 

    // Catch our elements' scroll events and 
    // syncronize the related element. 
    $el1.scroll(function() { performScroll($el1, $el2); }); 
    $el2.scroll(function() { performScroll($el2, $el1); }); 

    // Perform the scroll of the synced element 
    // based on the scrolled element. 
    function performScroll($scrolled, $toScroll) { 
    if (forcedScroll) return (forcedScroll = false); 
    var percent = ($scrolled.scrollTop()/
     ($scrolled[0].scrollHeight - $scrolled.outerHeight())) * 100; 
    setScrollTopFromPercent($toScroll, percent); 
    } 

    // Scroll to a position in the given 
    // element based on a percent. 
    function setScrollTopFromPercent($el, percent) { 
    var scrollTopPos = (percent/100) * 
     ($el[0].scrollHeight - $el.outerHeight()); 
    forcedScroll = true; 
    $el.scrollTop(scrollTopPos); 
    } 
} 
2

चलाता है घड़ी की कल की तरह (DEMO देख)

$(document).ready(function(){ 

    var master = "div1"; // this is id div 
    var slave = "div2"; // this is other id div 
    var master_tmp; 
    var slave_tmp; 
    var timer; 

    var sync = function() 
    { 
    if($(this).attr('id') == slave) 
    { 
     master_tmp = master; 
     slave_tmp = slave; 
     master = slave; 
     slave = master_tmp; 
    } 

    $("#" + slave).unbind("scroll"); 

    var percentage = this.scrollTop/(this.scrollHeight - this.offsetHeight); 

    var x = percentage * ($("#" + slave).get(0).scrollHeight - $("#" + slave).get(0).offsetHeight); 

    $("#" + slave).scrollTop(x); 

    if(typeof(timer) !== 'undefind') 
     clearTimeout(timer); 

    timer = setTimeout(function(){ $("#" + slave).scroll(sync) }, 200) 
    } 

    $('#' + master + ', #' + slave).scroll(sync); 

}); 
+0

यह बहुत अच्छा काम करता है। धन्यवाद। – Garry

+0

मूसहेल के साथ भी महान काम करता है। –

0

पावेल समाधान (पहले उत्तर) से।

horizzontal स्क्रॉल jQuery का उपयोग कर सिंक्रनाइज़ के लिए यह समाधान है:

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

कई क्षैतिज सिंक्रनाइज़ divs के लिए एक अन्य समाधान यह है, लेकिन यह एक ही चौड़ाई के साथ divs के लिए काम करता है।

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); 

एनबी: केवल एक ही चौड़ाई के साथ divs के लिए

JSFiddle

1

मैं पावेल के स्वच्छ समाधान चाहते हैं, लेकिन यह कुछ मैं जरूरत का अभाव है और एक अजीब स्क्रॉल बग जहां यह स्क्रॉल करें और करने के लिए जारी है मेरी प्लगइन कई कंटेनर पर काम करेगा केवल दो नहीं।

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

उदाहरण & डेमो: http://trunk.xtf.dk/Project/ScrollSync/

प्लगइन: ('। स्क्रॉल')। http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js

$ scrollSync();

+0

यह एज में काम नहीं कर रहा है। – HellBaby

+0

@Frost एक गैर jquery संस्करण है? – hipkiss

1

आप आनुपातिक स्क्रॉल नहीं करना चाहते, बल्कि प्रत्येक क्षेत्र पर पिक्सल के बराबर संख्या में स्क्रॉल करने के लिए है, तो खाने आप स्क्रॉल घटना बाध्यकारी रहे हैं के वर्तमान मूल्य के लिए परिवर्तन की मूल्य जोड़ सकता है सेवा मेरे।

मान लें कि #left छोटा क्षेत्र है, और #right बड़ा क्षेत्र है।

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/

परिवर्तन की मूल्य जोड़ने, और न सिर्फ स्थापित करने में यह करने के लिए बराबर #right के scrollTop() करके, आप छोटे से क्षेत्र में ऊपर और नीचे स्क्रॉल कर सकते हैं या, इसके scrollTop() की परवाह किए बिना कम से कम किया जा रहा है बड़ा क्षेत्र इसका एक उदाहरण फेसबुक पर एक उपयोगकर्ता पेज है।

जब मैं यहां आया तो मुझे यही चाहिए, इसलिए मैंने सोचा कि मैं साझा करूंगा।

संबंधित मुद्दे