स्क्रॉलिंग चाइल्ड डि विंडो को स्क्रॉल करता है, मैं इसे कैसे रोकूं?


94

मेरे पास एक div है, एक स्क्रॉल बार के साथ, जब यह अंत तक पहुंचता है, तो मेरा पृष्ठ स्क्रॉल करना शुरू कर देता है। वैसे भी क्या मैं इस व्यवहार को रोक सकता हूं?


2
@NGLN एक डुप्लिकेट नहीं, अलग सवाल।
sidewinderguy

जवाबों:


68

आप कुछ ऐसा करके पूरे पृष्ठ की स्क्रॉलिंग को निष्क्रिय कर सकते हैं:

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>

33
अच्छा है, लेकिन यह ब्राउज़र के स्क्रॉलबार को गायब कर देता है जब भी आप div पर होवर करते हैं।
cstack

@ आप सही हैं कि ओपी (जीवन) का खुद का जवाब बेहतर है।
इमरान बुगियो जूल

2
कई ब्राउज़र स्क्रॉल व्हील गायब हो जाते हैं और माउस को स्थानांतरित करने वाले उपयोगकर्ता के आधार पर फिर से दिखाई देते हैं, इसलिए उपरोक्त टिप्पणी अब समस्या नहीं है।
कीथ हॉलिडे

यह समाधान तब काम नहीं करता है जब पृष्ठ को iframe में एम्बेड किया गया हो।
गौतम कृष्णन

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

43

समाधान मिल गया।

http://jsbin.com/itajok

यह वही है जो मुझे चाहिए था।

और यह कोड है।

http://jsbin.com/itajok/edit#javascript,html

एक jQuery प्लग-इन का उपयोग करता है।


पदावनति सूचना के कारण अद्यतन

से jQuery-माउसव्हील :

तीन तर्कों (जोड़ने के पुराने व्यवहार delta, deltaXऔर deltaY) ईवेंट हैंडलर को अब हटा दिया गया है और बाद में विज्ञप्ति में निकाल दिया जाएगा।

तो, event.deltaYअब इस्तेमाल किया जाना चाहिए:

var toolbox = $('#toolbox'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});

डेमो


6
आपका लिंक js और ब्रेक के लिए github का उपयोग करता है क्योंकि सामग्री-प्रकार blah blah यहाँ यह एक काम करता है: jsbin.com/itajok/207
माइकल जे।

क्रोम डिवाइस एमुलेटर और आईफोन पर दोनों jsbins काम नहीं करते हैं। किसी को पता है अगर यह अभी भी काम करता है?
डिर्क बोअर

2
आपका "समाधान" केवल माउस स्क्रॉल ईवेंट के लिए काम करता है, पेज अप / डाउन या एरो कीज़ के लिए नहीं।
स्कॉट

यहाँ "बंद" क्यों आवश्यक है?
ब्रैड जॉनसन

16

चयनित समाधान कला का एक काम है। सोचा कि यह एक प्लगइन के योग्य है ...।

$.fn.scrollGuard = function() {
    return this
        .on( 'wheel', function ( e ) {
            var event = e.originalEvent;
            var d = event.wheelDelta || -event.detail;
            this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
            e.preventDefault();
        });
};    

यह मेरे लिए चल रही असुविधा है और मैंने देखा है अन्य हैक की तुलना में यह समाधान बहुत साफ है। यह जानने के लिए उत्सुक है कि यह कैसे काम करता है और इसका व्यापक रूप से समर्थन कैसे किया जाएगा, लेकिन जीवन और जो कोई भी मूल रूप से इसके लिए आता है। BTW - स्टैकओवरफ़्लो उत्तर संपादक को इसकी आवश्यकता है!

अपडेट करें

मेरा मानना ​​है कि यह बेहतर है कि यह डोम में हेरफेर करने की कोशिश नहीं करता है, केवल सशर्त रूप से बुदबुदाहट को रोकता है ...

$.fn.scrollGuard2 = function() {
  return this
    .on( 'wheel', function ( e ) {
      var $this = $(this);
      if (e.originalEvent.deltaY < 0) {
        /* scrolling up */
        return ($this.scrollTop() > 0);
      } else {
        /* scrolling down */
        return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
      }
    })
  ;
};    

क्रोम में महान काम करता है और अन्य समाधानों की तुलना में बहुत सरल है ... मुझे पता है कि यह कहीं और किराए पर कैसे ...

बेला


3
DOMMouseScroll घटना को जोड़ने से यह फ़ायरफ़ॉक्स के साथ काम करता है → jsfiddle.net/chodorowicz/egqy7mbz/1
chodorowicz

मुझे आश्चर्य है कि यह jquery में नहीं लिखा गया है। मुझे लगा कि मुख्य बिंदुओं में से एक को यह ध्यान नहीं रखना है कि आप किस ब्राउज़र का उपयोग कर रहे हैं।
रोबिस्रोब

वास्तव में ऐसा लगता है कि दोनों पदावनत हैं ... wheelघटना
डकैतीस्रो

इसका परिणाम मेरी मैकबुक पर क्रोम में विशेष रूप से जर्कियर स्क्रॉलिंग है। स्वीकृत समाधान में यह समस्या नहीं है।
danvk

निराशाजनक। इसके कई अलग-अलग संस्करण हैं। ऐसा लगता है कि यूआई का एक महत्वपूर्ण पहलू है, और वास्तव में यह आश्चर्यजनक है कि यह डिफ़ॉल्ट व्यवहार है जब यह बहुत अनपेक्षित है। जाहिर है कि ब्राउज़र को यह जानने के लिए सुसज्जित किया गया है कि आंतरिक स्क्रॉलिंग डिव इसकी सीमा पर है कि वह ईवेंट को विंडो पर लागू करने में सक्षम हो, इसलिए इसे क्वेरी करने के लिए उपलब्ध हैंडल क्यों नहीं हैं?
रोबिस्रोब

8

आप फिर से सक्रिय करने के लिए बॉडी स्क्रॉलबार और फिर माउसआउट इवेंट को अक्षम करने के लिए div पर एक माउसओवर इवेंट का उपयोग कर सकते हैं?

जैसे HTML

<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
    content
</div>

और फिर जावास्क्रिप्ट की तरह:

var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
    body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
    body.style.overflowY = 'auto';
}

12
आप document.bodyइसके बजाय भी उपयोग कर सकते हैं ।
Ry-

8

यहां Y अक्ष पर ऐसा करने के लिए एक क्रॉस-ब्राउज़र तरीका है, यह डेस्कटॉप और मोबाइल पर काम करता है। OSX और iOS पर परीक्षण किया गया।

var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var deltaY = event.deltaY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
}, {passive:false});

scrollArea.addEventListener("touchstart", function(event) {
    this.previousClientY = event.touches[0].clientY;
}, {passive:false});

scrollArea.addEventListener("touchmove", function(event) {
    var scrollTop = this.scrollTop;
    var maxScroll = this.scrollHeight - this.offsetHeight;
    var currentClientY = event.touches[0].clientY;
    var deltaY = this.previousClientY - currentClientY;
    if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
        event.preventDefault();
    }
    this.previousClientY = currentClientY;
}, {passive:false});

यह कमाल का काम करता है! वाह, बिल्कुल मैंने क्या खोजा। यह निश्चित रूप से अधिक upvotes की जरूरत है।
१०:१६

यह समाधान बहुत अच्छी तरह से काम करता है, लेकिन थोड़ा सा समायोजन की आवश्यकता है: इसके scrollTop === maxScroll द्वारा बदलने की आवश्यकता है scrollTop >= maxScroll। यह 1 मामले पर अजीब लगता है, इसकी आवश्यकता थी
tchiot.ludo

7

मैंने इस मुद्दे को हल करने के लिए लिखा था

  var div;
  div = document.getElementsByClassName('selector')[0];

  div.addEventListener('mousewheel', function(e) {
    if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
      e.preventDefault();
      div.scrollTop = div.scrollHeight;
    } else if (div.scrollTop + e.deltaY <= 0) {
      e.preventDefault();
      div.scrollTop = 0;
    }
  }, false);

यहाँ पर कुछ समाधानों में से एक जो पृष्ठ तत्वों के बिना काम करता है, जो ओवरफ्लो होने के कारण छिपे हुए सेट से छिपकर काम करता है।
संक्राति

+1 यह एक ठोस समाधान है। यदि आप इसे स्क्रॉल करने योग्य कंटेनर में संलग्न करते हैं, तो आप इस उदाहरण में div चाहते हैं e.currentTarget
मैट

बहुत साफ समाधान। धन्यवाद
Thinh Bui

Chrome 61.0.3163.100 और Safari 11.0 में काम किया, लेकिन फ़ायरफ़ॉक्स 56.0 में नहीं (मैक ओएस एल कैपिटन)
BigJ

यह सबसे अच्छा देशी समाधान है। हालाँकि, डिफ़ॉल्ट के falseलिए इसे निर्दिष्ट करने की आवश्यकता नहीं है addEventListener। इसके अलावा, तुलना सरल असमानताओं ( >और <) होनी चाहिए , >=या नहीं <=
क्वोलोन प्रश्न

6

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

संभवतः इसके लिए निम्नलिखित तरीके से कुछ मार्कअप परिवर्तनों की आवश्यकता होती है:

<div id="wrapper"> 
    <div id="content"> 
    </div> 
</div> 
<div id="sidebar"> 
</div> 

देखें कि यह इस नमूना फ़िडल में काम कर रहा है और तुलना करें कि इस सैंपल फ़िडल के साथ जो साइडबार का थोड़ा अलग माउस छोड़ता है।

ब्राउज़र के मुख्य स्क्रॉलबार के साथ केवल एक विशेष div स्क्रॉल करें देखें ।


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

"इस मामले" से आपका मतलब है आपका मामला? यदि नहीं: आप बिल्कुल सही हैं। यदि ऐसा है: यदि आपका पृष्ठ डिव स्क्रॉलिंग के अंत में स्क्रॉल करता है, तो स्क्रॉल संदेश डिव जनक तक पहुंच जाता है, इसलिए मुझे लगता है कि आपका पृष्ठ और डिव भाई-बहन नहीं, बल्कि माता-पिता और बच्चे हैं।
NGLN

हां, पेज मेरी डिव का अभिभावक है, इसलिए अंत तक पहुंचने पर, यह पेज को स्क्रॉल करना शुरू कर देता है, जिसे मैं नहीं चाहता।
जीवन

यदि आप अपनी div को मुख्य सामग्री का सहोदर नहीं बना सकते हैं, तो यह समस्या केवल HTML + CSS के साथ तय नहीं की जा सकती। यह डिफ़ॉल्ट व्यवहार है।
NGLN

1
मुझे लगता है कि यह सभी प्रदान किए गए उत्तरों का सबसे कुशल समाधान है; एक पृष्ठ के आधार पर अच्छे साफ मार्कअप के साथ, वांछित व्यवहार प्राप्त करने के लिए बहुत कम सीएसएस और जेएस हैक की आवश्यकता होती है।

6

जैसा कि यहां बताया गया है , अधिकांश आधुनिक ब्राउज़र अब overscroll-behavior: none;CSS संपत्ति का समर्थन करते हैं, जो स्क्रॉल चाइनिंग को रोकता है। और वह यह है, बस एक लाइन!


2
यह 2020 में सही उत्तर होना चाहिए। मेरे उपयोग के मामले में सबसे अच्छा समाधान था overscroll-behavior: contain;
पियर

3

यदि आप चयनकर्ता तत्व दर्ज करते हैं तो यह विंडो पर स्क्रॉल को अक्षम करता है। आकर्षण की तरह काम करता है।

elements = $(".selector");

elements.on('mouseenter', function() {
    window.currentScrollTop = $(window).scrollTop();
    window.currentScrollLeft = $(window).scrollTop();
    $(window).on("scroll.prevent", function() {
        $(window).scrollTop(window.currentScrollTop);
        $(window).scrollLeft(window.currentScrollLeft);
    });
});

elements.on('mouseleave', function() {
    $(window).off("scroll.prevent");
});

यह वास्तव में एक कार्यशील समाधान है। मुझे शुद्ध जेएस में इसकी आवश्यकता थी, इसलिए मैंने इसे फिर से लिखा। अगर किसी को इसकी जरूरत है, तो यह है यहां है । समाधान की तलाश में किसी के लिए, आपको नीचे दिए गए मेरे उत्तर की जांच करनी चाहिए ।
एंड्री स्टॉलेयर

2

आप कुछ ऐसा करके पूरे पृष्ठ की स्क्रॉलिंग को निष्क्रिय कर सकते हैं लेकिन स्क्रॉलबार को प्रदर्शित कर सकते हैं!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>

2
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
  var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
  var scrollTop = this.scrollTop;
  if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
    e.preventDefault();
  }
});

1

सीड के जवाब के आधार पर, यहां एक संस्करण है जो घोंसले को स्क्रॉल करने वाले तत्वों की अनुमति देता है। केवल वह तत्व जो माउस खत्म हो गया है, स्क्रॉल करेगा, और यह काफी आसानी से स्क्रॉल करता है। यह संस्करण फिर से प्रवेश भी है। यह एक ही तत्व पर कई बार उपयोग किया जा सकता है और हैंडलर को सही ढंग से हटा और पुनः स्थापित करेगा।

jQuery.fn.scrollGuard = function() {
    this
        .addClass('scroll-guarding')
        .off('.scrollGuard').on('mouseenter.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g[0].myCst = $g.scrollTop();
            $g[0].myCsl = $g.scrollLeft();
            $g.off("scroll.prevent").on("scroll.prevent", function() {
                $g.scrollTop($g[0].myCst);
                $g.scrollLeft($g[0].myCsl);
            });
        })
        .on('mouseleave.scrollGuard', function() {
            var $g = $(this).parent().closest('.scroll-guarding');
            $g = $g.length ? $g : $(window);
            $g.off("scroll.prevent");
        });
};

उपयोग करने का एक आसान तरीका एक वर्ग जोड़ना है, जैसे कि scroll-guard, पृष्ठ के सभी तत्वों को जिस पर आप स्क्रॉल करने की अनुमति देते हैं। फिर $('.scroll-guard').scrollGuard()उन्हें संरक्षित करने के लिए उपयोग करें।


0

यदि आप एक overflow: hiddenशैली लागू करते हैं तो इसे दूर जाना चाहिए

संपादित करें: वास्तव में मैंने आपके प्रश्न को गलत पढ़ा है, जो केवल स्क्रॉल बार को छिपाएगा, लेकिन मुझे नहीं लगता कि आप वही देख रहे हैं जो आप देख रहे हैं।


1
मुझे स्क्रॉलबार दोनों की जरूरत है। व्यवहार के बारे में बात कर रहा हूँ। जब मैं अपने माउस ट्रैकबॉल का उपयोग करके div के स्क्रॉल के अंत तक पहुँचता हूँ तो उसे पूरे पृष्ठ को स्क्रॉल नहीं करना चाहिए।
जीवन

0

मुझे क्रोम और फ़ायरफ़ॉक्स में काम करने का कोई जवाब नहीं मिला, इसलिए मैं इस समामेलन के साथ आया:

$someElement.on('mousewheel DOMMouseScroll', scrollProtection);

function scrollProtection(event) {
    var $this = $(this);
    event = event.originalEvent;
    var direction = (event.wheelDelta * -1) || (event.detail);
    if (direction < 0) {
        if ($this.scrollTop() <= 0) {
            return false;
        }
    } else {
        if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
            return false;
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.