Alt div kaydırıldığında pencere kaydırılır, bunu nasıl durdururum?


Yanıtlar:


68

Bunun gibi bir şey yaparak tüm sayfanın kaydırılmasını devre dışı bırakabilirsiniz:

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

33
İyi, ancak div'in üzerine geldiğinizde tarayıcının kaydırma çubuğunun kaybolmasını sağlıyor.
26'da cstack

@cstack haklısınız, bu yüzden OP (Jeevan) kendi cevabı daha iyidir.
Imran Bughio

2
Birçok tarayıcı kaydırma tekerleği, kullanıcının fareyi şimdi hareket ettirmesine bağlı olarak kaybolur ve yeniden görünür, bu nedenle yukarıdaki yorum artık bir sorun değildir.
Keith Holliday

Bu çözüm, sayfa bir iframe içine gömüldüğünde çalışmaz.
Gautam Krishnan

5
çözüm değil. taşmayı gizli olarak ayarlamak, dış öğenin tüm içeriğini aniden yeniden biçimlendiren kaydırma çubuğunu gizler. ayrıca, bu dış elemanın gövde olduğunu varsayar, ancak bu başka bir kayan div olabilir.
robisrob

43

Çözümü buldum.

http://jsbin.com/itajok

İhtiyacım olan şey bu.

Ve bu koddur.

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

Bir jQuery Eklentisi kullanır.


Kullanımdan kaldırma bildirimi nedeniyle güncelleme

Gönderen jquery-Fare tekerleğini :

Olay işleyicisine üç bağımsız değişken ( delta, deltaXve deltaY) eklemenin eski davranışı artık kullanımdan kaldırılmıştır ve sonraki sürümlerde kaldırılacaktır.

Ardından, event.deltaYşimdi kullanılmalıdır:

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

Demo


6
Bağlantınız js ve breaks için github kullanıyor çünkü burada içerik türü blah blah çalışıyor: jsbin.com/itajok/207
Michael J. Calkins

Her iki jsbin de Chrome cihaz öykünücüsünde ve iPhone'da çalışmıyor. Bunun hala çalışıp çalışmadığını bilen var mı?
Dirk Boer

2
"Çözümünüz" yalnızca fare kaydırma olayları için çalışır, sayfa yukarı / aşağı veya ok tuşları için geçerli değildir.
Scott

Burada neden "kapalı" gerekli?
Brad Johnson

16

Seçilen çözüm bir sanat eseridir. Bir eklentiye layık olduğunu düşündüm ...

$.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();
        });
};    

Bu benim için devam eden bir rahatsızlık oldu ve bu çözüm, gördüğüm diğer hack'lere kıyasla çok temiz. Nasıl çalıştığını ve ne kadar geniş çapta destekleneceğini merak ediyor, ancak Jeevan'a ve bunu ilk ortaya atan kişiye şerefe. BTW - stackoverflow yanıt düzenleyicisinin buna ihtiyacı var!

GÜNCELLEME

Bunun daha iyi olduğuna inanıyorum, çünkü DOM'u hiç manipüle etmeye çalışmıyor, sadece koşullu olarak köpürmeyi engelliyor ...

$.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);
      }
    })
  ;
};    

Kromda harika çalışıyor ve diğer çözümlerden çok daha basit ... başka yerlerde nasıl çalıştığını bana bildirin ...

VAKTİNİ BOŞA HARCAMAK


3
DOMMouseScroll olayı ekleyerek Firefox → ile o işi yapar jsfiddle.net/chodorowicz/egqy7mbz/1
chodorowicz

Bunun jquery'ye yazılmamasına şaşırdım. Ana noktalardan birinin hangi tarayıcıyı kullandığınızı önemsememek olduğunu düşündüm.
robisrob

aslında ikisi de kullanımdan kaldırılmış gibi görünüyor ... wheelevent
robisrob

Bu, Macbook'umdaki Chrome'da fark edilir derecede daha jerkier kaydırmaya neden oluyor. Kabul edilen çözümde bu sorun yok.
danvk

hayal kırıklığı yaratıyor. bunun pek çok farklı versiyonu var. kullanıcı arayüzünün önemli bir yönü gibi görünüyor ve gerçekten şaşırtıcı değil, bu kadar sezgisel olmadığında bunun varsayılan davranış olması. Açıkçası tarayıcı, iç kaydırma div'inin olayı pencereye uygulayabilmek için sınırında olduğunu bilecek şekilde donatılmıştır, öyleyse neden onu sorgulamak için kullanılabilen tutamaçlar yok?
robisrob

8

Gövde kaydırma çubuğunu devre dışı bırakmak için div üzerinde bir fareyle üzerine gelme olayını ve ardından tekrar etkinleştirmek için bir fareyi çekme olayını kullanabilirsiniz.

Örneğin HTML

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

Ve sonra javascript şöyle:

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

12
Bunun document.bodyyerine sen de kullanabilirsin .
Ry-

8

İşte bunu Y ekseninde yapmanın çapraz tarayıcı yolu, masaüstü ve mobil cihazlarda çalışıyor. OSX ve iOS'ta test edilmiştir.

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

Bu harika çalışıyor! Vay canına, tam olarak aradığım şey. Kesinlikle daha fazla oylamaya ihtiyacı var.
delato468

Bu çözüm oldukça iyi çalışıyor ama biraz ayarlamak gerekir: değişikliği yapması gerektiği scrollTop === maxScroll ile scrollTop >= maxScroll. 1 vakada garip görünüyor, buna ihtiyaç vardı
tchiot.ludo

7

Bu sorunu çözmek için yazdım

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

Buradaki birkaç çözümden biri, ayarlanan taşma nedeniyle can sıkıcı bir şekilde atlayan sayfa öğeleri olmadan çalışıyor.
Skeptic

+1 bu sağlam bir çözüm. bunu kaydırılabilir bir kaba eklerseniz, bu örnekte div olmasını isteyeceksiniz e.currentTarget.
Matt

çok temiz çözüm. Teşekkürler
Thinh Bui

Chrome 61.0.3163.100 ve Safari 11.0'da çalıştı, ancak FireFox 56.0'da çalışmadı (Mac OS El Capitan)
BigJ

Bu, en iyi yerel çözümdür. Ancak, varsayılan olduğu falseiçin belirtilmesine gerek yoktur addEventListener. Dahası, karşılaştırmalar basit eşitsizlikler olmalıdır ( >ve <), >=veya değil <=.
Quolonel Soruları

7

Cevap olarak burada , en modern tarayıcılar artık destekleyen overscroll-behavior: none;CSS özelliğini, önler kaydırma zincirleme. Ve işte bu, sadece bir satır!


2
2020'de doğru cevap bu olmalı. Benim kullanım durumum için en iyi çözümdü overscroll-behavior: contain;.
İskele

bu, bazı uç sürümleri için tam olarak desteklenmemektedir. bunu farklı bir şekilde nasıl çözebileceğiniz hakkında bir fikriniz var mı?
YTG

6

Sorunuzu doğru anlarsam, fare bir div'in üzerindeyken ana içeriğin kaydırılmasını önlemek istersiniz (bir kenar çubuğu diyelim). Bunun için, kaydırma olayının ana içeriğe köpürmesini önlemek için, kenar çubuğu ana içeriğin (tarayıcı penceresi olan) kaydırma konteynerinin alt öğesi olmayabilir.

Bu muhtemelen aşağıdaki şekilde bazı işaretleme değişikliklerini gerektirir:

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

Bu örnek keman üzerinde çalıştığını görün ve bunu kenar çubuğundan biraz farklı bir fare bırakma davranışına sahip olan bu örnek kemanla karşılaştırın .

Ayrıca , tarayıcının ana kaydırma çubuğuyla yalnızca belirli bir div kaydırmaya bakın .


Bu durumda kenar çubuğu, sarmalayıcı div'in dışındadır. Ben ebeveyne kaydırma baloncuk sanmıyorum Yani
Jeevan

"Bu dava" derken davanızı mı kastediyorsunuz? Değilse: kesinlikle haklısın. Öyleyse: sayfanız div kaydırma işleminin sonunda kaydırılırsa, kaydırma mesajı, div üst öğesinde kabarcıklar, bu nedenle sayfanızın ve div'in kardeş değil, ebeveyn ve çocuk olduğunu düşünüyorum.
NGLN

Evet, Sayfa bölümümün ebeveynidir, Bu yüzden sona ulaştığında, benim istemediğim sayfayı kaydırmaya başlar.
Jeevan

Div'inizi ana içeriğin kardeşi yapamazsanız, bu sorun yalnızca HTML + CSS ile düzeltilemez. Varsayılan davranıştır.
NGLN

1
Bence bu, verilen tüm cevaplar arasında en verimli çözüm; bir sayfanın tabanında iyi bir temiz işaretleme ile, istenen davranışı elde etmek için çok daha az CSS ve JS korsanlığı gerekir.

3

bu, seçici elemanına girerseniz pencerede kaydırmayı devre dışı bırakır. takılar gibi çalışır.

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

Bu gerçekten çalışan bir çözüm. Saf js'de ihtiyacım vardı, bu yüzden yeniden yazdım. İhtiyaç duyan varsa, burada . Hala çözümü arayanlar için, aşağıdaki cevabımı kontrol etmelisiniz .
Andriy Stolyar

2

Bunun gibi bir şey yaparak tüm sayfanın kaydırılmasını devre dışı bırakabilir, ancak kaydırma çubuğunu görüntüleyebilirsiniz!

<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

Ceed'in cevabına göre, kaydırma korumalı öğelerin iç içe yerleştirilmesine izin veren bir sürüm burada. Yalnızca farenin üzerinde olduğu öğe kayar ve oldukça yumuşak bir şekilde kaydırılır. Bu sürüm aynı zamanda yeniden girişlidir. Aynı eleman üzerinde birden çok kez kullanılabilir ve işleyicileri doğru şekilde kaldırıp yeniden takacaktır.

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

Kullanmanın kolay bir yolu scroll-guard, sayfada kaydırmaya izin verdiğiniz tüm öğelere gibi bir sınıf eklemektir . Sonra $('.scroll-guard').scrollGuard()onları korumak için kullanın .


0

Bir overflow: hiddenstil uygularsanız , gitmeli

edit: aslında sorunuzu yanlış okudum, bu sadece kaydırma çubuğunu gizleyecek, ancak aradığınız şeyin bu olduğunu sanmıyorum.


1
Her iki kaydırma çubuğuna da ihtiyacım var. Davranıştan bahsediyorum. Farenin iztopunu kullanarak div kaydırmasının sonuna ulaştığımda, tüm sayfayı kaydırmamalı.
Jeevan

0

Chrome ve Firefox'ta çalışmak için hiçbir cevabı alamadım, bu yüzden bu birleştirme ile geldim:

$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;
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.