स्टिकी साइडबार: नीचे स्क्रॉल करते समय स्टिक नीचे, ऊपर स्क्रॉल करते समय


94

मैं अपनी चिपचिपी साइडबार समस्या के समाधान के लिए कुछ समय से देख रहा हूं। मेरे पास एक विशिष्ट विचार है कि मैं इसे कैसे काम करना चाहूंगा; प्रभावी रूप से, मैं आपको नीचे स्क्रॉल करने के लिए छड़ी करना चाहूंगा, और फिर जैसे ही आप वापस ऊपर स्क्रॉल करेंगे, मैं चाहूंगा कि यह एक तरल पदार्थ गति (कोई कूदते हुए) में शीर्ष पर चिपक जाए। मैं जो हासिल करने की कोशिश कर रहा हूं उसका एक उदाहरण नहीं मिल पा रहा है, इसलिए मैंने एक ऐसी छवि बनाई है जिससे मुझे उम्मीद है कि मैं इस बिंदु को स्पष्ट करूंगा:

स्टिकी साइडबार: नीचे स्क्रॉल करते समय स्टिक नीचे, ऊपर स्क्रॉल करते समय

  1. साइडबार हेडर के नीचे बैठता है।
  2. जैसे ही आप पेज के कंटेंट के साथ साइडबार का लेवल नीचे रहता है, ताकि आप साइडबार और कंटेंट दोनों को स्क्रॉल कर सकें।
  3. साइडबार के नीचे तक पहुँचें, साइडबार व्यूपोर्ट के निचले भाग में चिपक जाता है (अधिकांश प्लगइन्स केवल शीर्ष पर चिपके रहने की अनुमति देते हैं, कुछ ऐसे जो नीचे से चिपके रहने की अनुमति देते हैं दोनों के लिए अनुमति नहीं देते हैं)।
  4. नीचे तक पहुंचें, साइडबार पाद के ऊपर बैठता है।
  5. जैसा कि आप बैक अप स्क्रॉल करते हैं, साइडबार सामग्री के साथ स्तर पर रहता है ताकि आप सामग्री और साइडबार फिर से स्क्रॉल कर सकें।
  6. साइडबार के शीर्ष पर पहुंचें, साइडबार व्यूपोर्ट के शीर्ष पर चिपक जाता है।
  7. शीर्ष पर पहुंचें और साइडबार हेडर के नीचे वापस बैठता है।

मुझे उम्मीद है कि यह पर्याप्त जानकारी है। मैंने किसी भी प्लगइन्स / स्क्रिप्ट का परीक्षण करने के लिए एक jsfiddle बनाया है, जिसे मैंने इस प्रश्न के लिए रीसेट किया है: http://jsfiddle.net/jslucas/yr9gV/2/ .

जवाबों:


25

बहुत अच्छी और ilustrative छवि के लिए +1

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन मैंने लापरवाही से वही प्रश्न आपके द्वारा forum.jquery.com में पोस्ट किया और वहाँ एक उत्तर (@ tucker973 द्वारा) पाया , एक अच्छा पुस्तकालय इसे बनाने का सुझाव दिया और इसे यहाँ साझा करना चाहता था।

इसे @leafo द्वारा स्टिकी-किट कहा जाता है

यहां आपके पास एक बहुत ही मूल उदाहरण का कोड है जिसे मैंने तैयार किया था और परिणाम देखने के लिए एक कार्यशील डेमो।

बेशक, सभी क्रेडिट प्लगइन के निर्माता के पास जाते हैं, मैंने केवल इसे यहां दिखाने के लिए यह उदाहरण बनाया है। मुझे वही परिणाम प्राप्त करने की आवश्यकता है जो आप बाद में थे और इस प्लगइन को बहुत उपयोगी पाया।


जैसा कि आप सुझाव देते हैं, मैं इस छोटे प्लगइन का उपयोग करता हूं, लेकिन शीर्ष पर छड़ी के बाद चौड़ाई बदल जाती है। मैं इसे कैसे अपरिवर्तित कर सकता हूं?
vijayrana

हाय @gmo! मैं एक ही चीज़ की तलाश कर रहा हूं लेकिन यह काम नहीं करता है (स्क्रॉल पर ऊपर नहीं चिपकता है) जब व्यूपोर्ट की तुलना में स्क्रॉलबार लंबे समय तक ...
इगोर लास्ज़लो

13

महान ग्राफिक के लिए धन्यवाद। मैं भी इस चुनौती का हल ढूंढ रहा था!

दुर्भाग्य से, यहां पोस्ट किया गया अन्य उत्तर # 5 की आवश्यकता को संबोधित नहीं करता है जो साइडबार के माध्यम से वापस स्क्रॉल करने की क्षमता को आसानी से निर्धारित करता है।

मैंने एक फिडेल बनाया जो सभी आवश्यकताओं को लागू करता है: http://jsfiddle.net/bN4qu/5/

लागू करने के लिए आवश्यक मुख्य तर्क है:

If scrolling up OR the element is shorter than viewport Then
  Set top of element to top of viewport If scrolled above top of element
If scrolling down then
  Set bottom of element at bottom of viewport If scrolled past bottom of element

फ़िडल में, मैं टार्गेट एलिमेंट को चारों ओर ले जाने के लिए CSS3 ट्रांसफ़ॉर्म का उपयोग करता हूँ, इसलिए यह उदाहरणार्थ IE <9 में काम नहीं करेगा। तर्क एक अलग दृष्टिकोण का उपयोग करने के लिए ध्वनि है।

इसके अलावा, मैंने आपकी फ़ाइडल को संशोधित किया ताकि चिपचिपा साइडबार में एक ढाल पृष्ठभूमि हो। यह दिखाने में मदद करता है कि उचित व्यवहार प्रदर्शित किया जा रहा है।

मुझे आशा है कि यह किसी के लिए उपयोगी है!


2
उत्तर की खोज करने वाले किसी व्यक्ति के लिए, ट्रैविस द्वारा यह एक सबसे निर्दोष है जो मैंने अब तक पाया है। धन्यवाद दोस्त।
मार्कोवेगा

एक महान प्रयास, यह मूल रूप से सिर्फ तब काम करता है जब मैंने इसे गिरा दिया, जो कि मैं अन्य प्लगइन्स के लिए कह सकता हूं :) प्रदर्शन ने एक बड़ा हिट लिया, लेकिन मुझे लगता है कि यह बहुत अधिक है किसी भी गैर-देशी चिपचिपा कार्यान्वयन के साथ।
jClark

यह एक उत्कृष्ट प्रारंभिक बिंदु था! मैंने $.cssफ़ंक्शन को एक में लपेटा requestAnimationFrameऔर आधुनिक फ़्रंट फ्रेमवर्क में उपयोग के लिए विध्वंस / प्रतिक्रिया के लिए एक विनाश / अनबाइंड फ़ंक्शन जोड़ा। प्रदर्शन उसके बाद एक मुद्दा नहीं है!
क्रिस्टोफ मारोस

@ क्रिस्तोफ़ मारियो क्या आप jsfiddle कृपया पर एक उदाहरण प्रदान कर सकते हैं?
ड्यूरामे

धन्यवाद, लेकिन यह कोड छोटे साइडबार के लिए काम नहीं करता है जो व्यूपोर्ट से कम है (व्यूपोर्ट की ऊंचाई)
सीड अब्बास सेयदी

12

इसे कैसे लागू किया जाए, इसका एक उदाहरण इस प्रकार है:

जावास्क्रिप्ट:

$(function() {

var $window = $(window);
var lastScrollTop = $window.scrollTop();
var wasScrollingDown = true;

var $sidebar = $("#sidebar");
if ($sidebar.length > 0) {

    var initialSidebarTop = $sidebar.position().top;

    $window.scroll(function(event) {

        var windowHeight = $window.height();
        var sidebarHeight = $sidebar.outerHeight();

        var scrollTop = $window.scrollTop();
        var scrollBottom = scrollTop + windowHeight;

        var sidebarTop = $sidebar.position().top;
        var sidebarBottom = sidebarTop + sidebarHeight;

        var heightDelta = Math.abs(windowHeight - sidebarHeight);
        var scrollDelta = lastScrollTop - scrollTop;

        var isScrollingDown = (scrollTop > lastScrollTop);
        var isWindowLarger = (windowHeight > sidebarHeight);

        if ((isWindowLarger && scrollTop > initialSidebarTop) || (!isWindowLarger && scrollTop > initialSidebarTop + heightDelta)) {
            $sidebar.addClass('fixed');
        } else if (!isScrollingDown && scrollTop <= initialSidebarTop) {
            $sidebar.removeClass('fixed');
        }

        var dragBottomDown = (sidebarBottom <= scrollBottom && isScrollingDown);
        var dragTopUp = (sidebarTop >= scrollTop && !isScrollingDown);

        if (dragBottomDown) {
            if (isWindowLarger) {
                $sidebar.css('top', 0);
            } else {
                $sidebar.css('top', -heightDelta);
            }
        } else if (dragTopUp) {
            $sidebar.css('top', 0);
        } else if ($sidebar.hasClass('fixed')) {
            var currentTop = parseInt($sidebar.css('top'), 10);

            var minTop = -heightDelta;
            var scrolledTop = currentTop + scrollDelta;

            var isPageAtBottom = (scrollTop + windowHeight >= $(document).height());
            var newTop = (isPageAtBottom) ? minTop : scrolledTop;

            $sidebar.css('top', newTop);
        }

        lastScrollTop = scrollTop;
        wasScrollingDown = isScrollingDown;
    });
}
});

सीएसएस:

#sidebar {
  width: 180px;
  padding: 10px;
  background: red;
  float: right;
}

.fixed {
  position: fixed;
  right: 50%;
  margin-right: -50%;
}

डेमो: http://jsfiddle.net/ryanmaxwell/25QaE/

यह सभी परिदृश्यों में अपेक्षित रूप से काम करता है और IE में भी अच्छी तरह से समर्थित है।


इस उत्तर को देखें और stackoverflow.com/questions/28428327/…
theinlwin

@ अनोप नाइक - यह लगभग अच्छा है जो मैं देख रहा हूँ ... चिपचिपा किट साइडबार के लिए काम नहीं करता है जो व्यूपोर्ट से अधिक लंबा है, आपका काम करता है। हालाँकि मैं इसके विपरीत पसंद करूंगा: जब मैं नीचे स्क्रॉल करता हूं, तो यह शीर्ष पर चिपक जाता है, और ऊपर स्क्रॉल करने पर, यह नीचे की ओर चिपक जाता है ... क्या आप मेरी मदद कर सकते हैं कृपया एक छोटी सी फ़ेल्ट में बदल रहे हैं?
इगोर

1
@IgorLaszlo ज़रूर, कुछ समय पहले, कुछ समय में आपको अपडेट कर दूंगा ...
अनूप नाइक

यह मेरी समस्या भी बताता है: "जब स्थिति के साथ तत्व: चिपचिपा" अटक गया है "और व्यूपोर्ट से अधिक लंबा है, तो कंटेनर के नीचे स्क्रॉल करने के बाद ही आप इसकी सामग्री देख सकते हैं। यह" अटक "तत्व स्क्रॉल होने पर शांत होगा। दस्तावेज़ के साथ और रुकने के बाद, एक बार यह अपने निचले किनारे पर पहुंच जाता है। यदि उपयोगकर्ता ने वापस स्क्रॉल किया, तो वही बात फिर से होगी, लेकिन रिवर्स में। - एक अन्य व्यक्ति द्वारा लिखी गई है, जिसकी समस्या एक ही है ( stackoverflow.com/questions/47618271/… )
इगोर लास्ज़लो

@ अनोप नाइक! आपके प्रयास के लिए धन्यवाद, लेकिन इसे कृपया, मुझे मेरी समस्या को हल करने के लिए स्टिकी jquery प्लगइन मिला: abouolia.github.io/sticky-sidebar फिर से धन्यवाद!
इगोर

0

मैं ठीक उसी चीज की तलाश में था। जाहिर है मुझे ग्राफिक के साथ एक समान प्रश्न खोजने के लिए कुछ अस्पष्ट शब्दों की खोज करने की आवश्यकता थी। पता चला कि यह वही है जो मैं देख रहा था। मुझे कोई प्लगइन्स नहीं मिला, इसलिए मैंने इसे स्वयं बनाने का निर्णय लिया। उम्मीद है कि कोई इसे देखेगा और इसे निखारेगा।

यहां एक त्वरित और गंदा नमूना html मैं उपयोग कर रहा हूं।

<div id="main">
    <div class="col-1">
    </div>
    <div class="col-2">
        <div class="side-wrapper">
            sidebar content
        </div>
    </div>
</div>

यहाँ मैंने बनाया jQuery है:

var lastScrollPos = $(window).scrollTop();
var originalPos = $('.side-wrapper').offset().top;
if ($('.col-2').css('float') != 'none') {
    $(window).scroll(function(){
        var rectbtfadPos = $('.rectbtfad').offset().top + $('.rectbtfad').height();
        // scroll up direction
        if ( lastScrollPos > $(window).scrollTop() ) {
            // unstick if scrolling the opposite direction so content will scroll with user
            if ($('.side-wrapper').css('position') == 'fixed') {
                $('.side-wrapper').css({
                    'position': 'absolute',
                    'top': $('.side-wrapper').offset().top + 'px',
                    'bottom': 'auto'
                });
            } 
            // if has reached the original position, return to relative positioning
            if ( ($(window).scrollTop() + $('#masthead').height()) < originalPos ) {
                $('.side-wrapper').css({
                    'position': 'relative',
                    'top': 'auto',
                    'bottom': 'auto'
                });
            } 
            // sticky to top if scroll past top of sidebar
            else if ( ($(window).scrollTop() + $('#masthead').height()) < $('.side-wrapper').offset().top && $('.side-wrapper').css('position') == 'absolute' ) {
                $('.side-wrapper').css({
                    'position': 'fixed',
                    'top': 15 + $('#masthead').height() + 'px', // padding to compensate for sticky header
                    'bottom': 'auto'
                });
            }
        } 
        // scroll down
        else {
            // unstick if scrolling the opposite direction so content will scroll with user
            if ($('.side-wrapper').css('position') == 'fixed') {
                $('.side-wrapper').css({
                    'position': 'absolute',
                    'top': $('.side-wrapper').offset().top + 'px',
                    'bottom': 'auto'
                });
            } 
            // check if rectbtfad (bottom most element) has reached the bottom
            if ( ($(window).scrollTop() + $(window).height()) > rectbtfadPos && $('.side-wrapper').css('position') != 'fixed' ) {
                $('.side-wrapper').css({
                    'width': $('.col-2').width(),
                    'position': 'fixed',
                    'bottom': '0',
                    'top': 'auto'
                });
            }
        }
        // set last scroll position to determine if scrolling up or down
        lastScrollPos = $(window).scrollTop();

    });
}

कुछ नोट:

  • मेरे साइडबार में .tbtfad सबसे नीचे का तत्व है
  • मैं अपने # मास्टहेड की ऊंचाई का उपयोग कर रहा हूं क्योंकि यह एक चिपचिपा हैडर है इसलिए इसे इसकी भरपाई करने की आवश्यकता है
  • जब से मैं एक उत्तरदायी डिजाइन का उपयोग कर रहा हूं और छोटे स्क्रीन पर इसे सक्रिय नहीं करना चाहता, तब से कॉल -2 फ्लोट के लिए एक चेक है

अगर किसी को यह थोड़ा और अधिक परिष्कृत कर सकते हैं जो बहुत अच्छा होगा।


0
function fixMe(id) {
    var e = $(id);
    var lastScrollTop = 0;
    var firstOffset = e.offset().top;
    var lastA = e.offset().top;
    var isFixed = false;
    $(window).scroll(function(event){
        if (isFixed) {
            return;
        }
        var a = e.offset().top;
        var b = e.height();
        var c = $(window).height();
        var d = $(window).scrollTop();
        if (b <= c - a) {
            e.css({position: "fixed"});
            isFixed = true;
            return;
        }           
        if (d > lastScrollTop){ // scroll down
            if (e.css("position") != "fixed" && c + d >= a + b) {
                e.css({position: "fixed", bottom: 0, top: "auto"});
            }
            if (a - d >= firstOffset) {
                e.css({position: "absolute", bottom: "auto", top: lastA});
            }
        } else { // scroll up
            if (a - d >= firstOffset) {
                if (e.css("position") != "fixed") {
                    e.css({position: "fixed", bottom: "auto", top: firstOffset});
                }
            } else {
                if (e.css("position") != "absolute") {
                    e.css({position: "absolute", bottom: "auto", top: lastA});
                }               
            }
        }
        lastScrollTop = d;
        lastA = a;
    });
}

fixMe("#stick");

काम करने का उदाहरण: https://jsfiddle.net/L7xoopst/6/


थोड़ा सा स्पष्टीकरण जोड़ें?
HaveNoDisplayName

यदि आप चिपचिपे आइटम के भीतर की ऊंचाई को अपडेट करते हैं तो इसमें कुछ समस्याएं हैं
Callam

0

वर्डप्रेस रिपॉजिटरी में एक अपेक्षाकृत अज्ञात प्लगइन है जिसे WP स्टिकी साइडबार के रूप में जाना जाता है। प्लगइन ठीक वही करता है जो आप चाहते थे (स्टिकी साइडबार: नीचे स्क्रॉल करते समय चिपकाएँ, ऊपर स्क्रॉल करते समय) WP स्टिकी साइडबार वर्डप्रेस रिपॉजिटरी लिंक: https://wordpress.org/plugins/mystickysidebar/


जानकारी के लिए धन्यवाद! पूरी तरह से काम किया। यह अजीब है कि व्यवहार चित्रण प्लगइन चित्रित छवि के लिए समान है :)
ओक्साना रोमनिव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.