JQuery ile sayfa kaydırmayı programlı olarak devre dışı bırakma


163

JQuery kullanarak, vücudun kaydırma devre dışı bırakmak istiyorum:

Benim fikrim:

  1. Ayarlamak body{ overflow: hidden;}
  2. Akımı yakalayın scrollTop();/scrollLeft()
  3. Gövde kaydırma olayına bağlama, scrollTop / scrollLeft öğesini yakalanan değere ayarlayın.

Daha iyi bir yol var mı?


Güncelleme:

Lütfen örneğime ve bunun nedenine http://jsbin.com/ikuma4/2/edit adresinden bakın.

Birisinin "neden sadece position: fixedpanelde kullanmıyor" diye düşüneceğini biliyorum .

Başka nedenlerim olduğu için lütfen bunu önermeyin.


7
"Daha iyi bir yol var mı?" - tarayıcının normal davranmasına izin vermek dışında?
Fenton

22
"melodramatik"?
Mike Weller

6
Belki de programlı olarak mı demek istediniz? 'Programlı' için firefox üst yazım düzeltme önerisi olduğu için
Michael Shimmins

4
Bu konu \ b \
Cipi

3
@Sohnee kaydırmayı devre dışı bırakıyor! == kötü
Mansiemans

Yanıtlar:


136

Bunu yapmanın tek yolu tarif ettiğinize benzer:

  1. Geçerli kaydırma konumunu yakalayın (yatay ekseni unutmayın!).
  2. Taşmayı gizli olarak ayarla (muhtemelen önceki taşma değerini korumak istiyor).
  3. ScrollTo () ile belgeyi kayıtlı kaydırma konumuna kaydırın.

Sonra tekrar kaydırmaya izin vermeye hazır olduğunuzda, tüm bunları geri alın.

Düzenleme: Ben kazmak için sorun gitti beri size kodu veremiyorum hiçbir neden ...

// lock scroll position, but retain settings for later
var scrollPosition = [
  self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
  self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);


// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])

2
lütfen jsbin.com/ikuma4/2/edit adresine bakın ve bana neyin daha iyi olduğuna dair bir neden açıklayın? Ben bir şey eksik mi (benim örnek ile karşılaştırıldığında cevabınızın uzunluğu için herhangi bir neden göremiyorum gibi soruyorum)
Hailwood

3
Yaklaşımınız IE7'de çalışmıyor. Önce ben de denedim. Sorun, scroll olayına yeterince hızlı tepki vermemesidir. Belgenin kaydırılmasını sağlar, ardından JS'niz kaydırma konumunu istediğiniz yere sıfırladığında geri çeker.
tfe

1
Ayrıca, eğer vücut başka bir şeyden taşmış autoolsaydı, üzerine yazılacaktır. Mevcut ayarı korumam gerekiyordu, böylece ek yük de ekler.
tfe

Herkes sadece stil htmlve bodyile neden overflow: hiddenyetersiz olduğunu biliyor mu ? Yine de olay işleyicisine ihtiyacımız var.
kpozin

4
Bu harika bir cevap. Ve dokunmatik cihazlarda çalışmasını sağlamak için bu cevaba göz atın.
Patrick

235

Bu, kaydırmayı tamamen devre dışı bırakacaktır:

$('html, body').css({
    overflow: 'hidden',
    height: '100%'
});

Yenilemek:

$('html, body').css({
    overflow: 'auto',
    height: 'auto'
});

Firefox ve Chrome'da test edildi.


18
beklendiği gibi çalışır. Teşekkürler! Bu kabul edilen cevap olmalı!
Dave Chen

6
Hala orta fare düğmesiyle kromun üzerinde kayar.
Lothar

16
Bu, geçerli kaydırma konumunu kaybeder. OP açıkça kaydırma konumunu yakalama hakkında bahsedilen, bu yüzden o gerekli olduğunu varsayalım. Her neyse, buna ihtiyacım var, bu yüzden bu benim için sınırlı bir kullanım
zerm

7
PS height: 100%Etkin bir şekilde atlamak , en azından en son Chrome'da atlamadan mevcut konumdaki kaydırmayı etkin bir şekilde kilitler.
zerm

2
Bu doğru cevap DEĞİLDİR. Kaydırma konumu yakalanmadı
taylorcressy

43

bunu dene

$('#element').on('scroll touchmove mousewheel', function(e){
  e.preventDefault();
  e.stopPropagation();
  return false;
})

tam aradığım şey ... neredeyse. Yine de ok tuşları sırasında devre dışı bırakmak için?
Cody

2
@Cody - bu css taşması ile birleştirin: gizli
Darius.V

2
@cubbiu nasıl geri alınır?
Meer

3
Kullanabilirsiniz$('#element').off('scroll touchmove mousewheel');
arnuschky

1
Harika bir çözüm. Yalnızca bodykaydırmayı nasıl devre dışı bırakabilseniz de, diğer alt öğelerde kaydırmaya nasıl izin veriyorsunuz overflow: scroll?
Fizzix

27

Çözüme tfe ile biraz ayar yapıyorum . Özellikle, kaydırma çubuğu olarak ayarlandığında sayfa içeriğinin (aka sayfa kaydırma ) kaymamasını sağlamak için bazı ek kontroller ekledim hidden.

İki Javascript işlevi lockScroll()ve unlockScroll()sırasıyla, sayfa kaydırma kilitlemek ve kilidini açmak için tanımlanabilir.

function lockScroll(){
    $html = $('html'); 
    $body = $('body'); 
    var initWidth = $body.outerWidth();
    var initHeight = $body.outerHeight();

    var scrollPosition = [
        self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
        self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
    ];
    $html.data('scroll-position', scrollPosition);
    $html.data('previous-overflow', $html.css('overflow'));
    $html.css('overflow', 'hidden');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);   

    var marginR = $body.outerWidth()-initWidth;
    var marginB = $body.outerHeight()-initHeight; 
    $body.css({'margin-right': marginR,'margin-bottom': marginB});
} 

function unlockScroll(){
    $html = $('html');
    $body = $('body');
    $html.css('overflow', $html.data('previous-overflow'));
    var scrollPosition = $html.data('scroll-position');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);    

    $body.css({'margin-right': 0, 'margin-bottom': 0});
}

burada <body>ilk marjı olmadığını varsaydım .

Yukarıdaki çözümün pratik uygulamaların çoğunda işe yaramasına rağmen, örneğin üstbilgi içeren sayfalar için daha fazla özelleştirme gerektirdiğinden bunun kesin olmadığına dikkat edin position:fixed. Bu özel duruma bir örnekle geçelim. Varsayalım

<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>

ile

#header{position:fixed; padding:0; margin:0; width:100%}

Sonra, bir fonksiyonlarda aşağıdakileri eklemek gerekir lockScroll()ve unlockScroll():

function lockScroll(){
    //Omissis   


    $('#header').css('margin-right', marginR);
} 

function unlockScroll(){
    //Omissis   

    $('#header').css('margin-right', 0);
}

Son olarak, kenar boşlukları veya dolgular için olası başlangıç ​​değerlerine dikkat edin.


4
Javascript $ body.css ({'margin-right': 0, 'margin-bottom', 0}); $ body.css ({'margin-right': 0, 'margin-bottom': 0}) olmalıdır;
Johansrk

Aslında, sadece kullanın marginRightve marginLeft:)
Martijn

25

bu kodu kullanabilirsiniz:

$("body").css("overflow", "hidden");

8
Kaydırmak için hala orta fare düğmesini kullanabilirsiniz.
Roger Far

2
Hayır, bu tamam ve bununla kaydırma yok!
mr.soroush

Ekstra css kullanıyorsanız, kaydırmayı tamamen devre dışı bırakabilirsiniz, daha fazla ayrıntı için cevabıma bakın.
gitaarik

21

Kaydırmayı KAPALI duruma getirmek için şunu deneyin:

var current = $(window).scrollTop();
$(window).scroll(function() {
    $(window).scrollTop(current);
});

sıfırlamak:

$(window).off('scroll');

Bu ihtiyacım olan şey için harika bir çözümdü.
Terry Carter

@EveryScreamer hayır, ekranın çılgınca sallanmasını sağlıyor. Bir geçici çözüm bulmaya çalışıyorum.
Telarian

5

Bunu işlemek için bir jQuery eklentisi yazdım: $ .disablescroll .

Fare tekerleği, touchmove ve gibi tuşlara basma olaylarının ilerlemesini önler Page Down.

Burada bir demo var .

Kullanımı:

$(window).disablescroll();

// To re-enable scrolling:
$(window).disablescroll("undo");

Fare tekerleği / kaydırma olayını duyurken kaydırmayı geçici olarak devre dışı bırakmak için disablescroll () eklentinizi kullanmaya çalıştım, ancak çalışmıyor. Bu etkiyi elde etmenin bir yolunu bilme şansın var mı?
sarı aziz

@JB Muhtemelen yardımcı olabilirim, ancak yorumlar en iyi yer değil. Bu yığın taşması sohbetinde bana katılın ve ne yapabileceğimi göreceğim: chat.stackoverflow.com/rooms/55043/disablescroll-usage
Josh Harrison

Üzgünüm, ama bu eklenti jsfiddle'ınızda bile çalışmıyor.
markj

Hangi tarayıcı / platformda işe yaramadığını söyleyerek bunu incelememe yardımcı olabilir misiniz?
Josh Harrison


4

Orta fare düğmesi de dahil olmak üzere kaydırmayı devre dışı bırakmak için bir astar.

$(document).scroll(function () { $(document).scrollTop(0); });

edit : Vanilla JS'de yukarıdakiyle aynı şekilde yine de jQuery'ye gerek yoktur (bu, hiçbir çerçeve, sadece JavaScript anlamına gelir):

document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })

this.documentElement.scrollTop - standart

this.body.scrollTop - IE uyumluluğu




3

Birisi geri yüklendiğinde kaydırma konumunu koruma sorunu olan bu kodu yayınladı. Bunun nedeni, insanların bunu html ve vücuda veya sadece vücuda uygulama eğilimindedir, ancak yalnızca html'ye uygulanması gerekir. Bu şekilde geri yüklendiğinde kaydırma konumu korunur:

$('html').css({
    'overflow': 'hidden',
    'height': '100%'
});

Yenilemek:

$('html').css({
    'overflow': 'auto',
    'height': 'auto'
});

değil 'overflow': 'auto',kullanımı'overflow': 'initial',
evtuhovdo

2

Bu, sizin amaçlarınız için işe yarayabilir veya çalışmayabilir, ancak jScrollPane öğesini kaydırmadan önce diğer işlevleri çalıştıracak şekilde genişletebilirsiniz . Sadece bunu biraz test ettim, ama atlayabildiğini ve kaydırmayı tamamen engelleyebildiğini doğrulayabilirim. Tek yaptığım:

  • Demo zip dosyasını indirin: http://github.com/vitch/jScrollPane/archives/master
  • "Etkinlikler" demosunu açın (events.html)
  • Küçültülmemiş komut dosyası kaynağını kullanmak için düzenleyin: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • Jquery.jscrollpane.js içine bir "return;" ekleyin 666 satırında (hayırlı satır numarası! ancak sürümünüzün biraz farklı olması durumunda, bu positionDragY(destY, animate)işlevin ilk satırıdır)

Events.html dosyasını etkinleştirdiğinizde, kodlama müdahaleniz nedeniyle kaydırma yapmayacağı normal bir kaydırma kutusu görürsünüz.

Tarayıcının kaydırma çubuklarının tamamını bu şekilde kontrol edebilirsiniz (bkz. Fullpage_scroll.html).

Bu nedenle, muhtemelen bir sonraki adım, sönen ve sabitleme sihrinizi yapan başka bir işleve bir çağrı eklemektir, daha sonra kaydırma ile devam edip etmeyeceğinize karar verir. ScrollTop ve scrollLeft'i ayarlamak için API çağrılarınız da var.

Daha fazla yardım istiyorsanız, ulaştığınız yere gönderin!

Umarım bu yardımcı olmuştur.



1

Yalnızca klavye gezinme özelliğiyle kaydırmayı devre dışı bırakmak istiyorsanız, tuş kilidi etkinliğini geçersiz kılabilirsiniz.

$(document).on('keydown', function(e){
    e.preventDefault();
    e.stopPropagation();
});

1

Bu kodu deneyin:

    $(function() { 
        // ...

        var $body = $(document);
        $body.bind('scroll', function() {
            if ($body.scrollLeft() !== 0) {
                $body.scrollLeft(0);
            }
        });

        // ...
    });

0

Sayfadaki içeriğin kaydırılmasını önlemek için pencereyi kaydırılabilir bir div ile kapatabilirsiniz. Ve gizleyerek ve göstererek, kaydırmanızı kilitleyebilir / kilidini açabilirsiniz.

Bunun gibi bir şey yapın:

#scrollLock {
    width: 100%;
    height: 100%;
    position: fixed;
    overflow: scroll;
    opacity: 0;
    display:none
}

#scrollLock > div {
    height: 99999px;
}

function scrollLock(){
    $('#scrollLock').scrollTop('10000').show();
}

function scrollUnlock(){
    $('#scrollLock').hide();
}

7
Lütfen "u" ve "smth" gibi kısaltmalar kullanmayın. Okunabilirlik için doğru hecelemek için zaman ayırın.
Tin Man

0

Düzenleri (üzerinden margin:0 auto;) merkezleyen kişiler için position:fixed, @tfe'nin önerdiği çözümle birlikte çözümün bir karışımı .

Sayfa yapışması yaşıyorsanız (kaydırma çubuğunun gösterilmesi / gizlenmesi nedeniyle) bu çözümü kullanın.

// lock scroll position, but retain settings for later
var scrollPosition = [
    window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
    window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var $html = $('html'); // bow to the demon known as MSIE(v7)
$html.addClass('modal-noscroll');
$html.data('scroll-position', scrollPosition);
$html.data('margin-top', $html.css('margin-top'));
$html.css('margin-top', -1 * scrollPosition[1]);

…ile kombine…

// un-lock scroll position
var $html = $('html').removeClass('modal-noscroll');
var scrollPosition = $html.data('scroll-position');
var marginTop = $html.data('margin-top');
$html.css('margin-top', marginTop);
window.scrollTo(scrollPosition[0], scrollPosition[1])

… Ve son olarak, CSS .modal-noscroll

.modal-noscroll
{
    position: fixed;
    overflow-y: scroll;
    width: 100%;
}

Bunu daha düzgün bir düzeltmenin orada başka çözümler birini daha söylemek girişim olacaktır, ama onu test etmedim o iyice henüz ...: P


Düzenleme: Bu bir dokunmatik cihaz üzerinde ne kadar kötü performans (okuma: havaya uçurmak) hakkında hiçbir ipucu olmadığını lütfen unutmayın.


0

Bunu yapmak için DOM'u da kullanabilirsiniz. Dediğiniz bir fonksiyonunuz olduğunu varsayalım:

function disable_scroll() {
document.body.style.overflow="hidden";
}

Ve hepsi bu kadar! Umarım bu tüm diğer cevaplara ek olarak yardımcı olur!


0

Sonunda bunu yaptım:

CoffeeScript:

    $("input").focus ->
        $("html, body").css "overflow-y","hidden"
        $(document).on "scroll.stopped touchmove.stopped mousewheel.stopped", (event) ->
            event.preventDefault()

    $("input").blur ->
        $("html, body").css "overflow-y","auto"
        $(document).off "scroll.stopped touchmove.stopped mousewheel.stopped"

JavaScript:

$("input").focus(function() {
 $("html, body").css("overflow-y", "hidden");
 $(document).on("scroll.stopped touchmove.stopped mousewheel.stopped", function(event) {
   return event.preventDefault();
 });
});

$("input").blur(function() {
 $("html, body").css("overflow-y", "auto");
 $(document).off("scroll.stopped touchmove.stopped mousewheel.stopped");
});

0

Çözümümü kimse denedi mi emin değilim. Bu tüm vücut / html üzerinde çalışır, ancak şüphesiz bir scroll olayı başlatan herhangi bir öğeye uygulanabilir.

ScrollLock'u istediğiniz gibi ayarlayın ve ayarını kaldırın.

var scrollLock = false;
var scrollMem = {left: 0, top: 0};

$(window).scroll(function(){
    if (scrollLock) {
        window.scrollTo(scrollMem.left, scrollMem.top);
    } else {
        scrollMem = {
            left: self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
            top: self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
        };
    }
});

Örnek JSFiddle

Umarım bu birine yardım eder.


Bu, bir istisna dışında olması gerektiği gibi çalışır. Kaydırma kilitlendiğinde ve
kaydırdığımda

0

Bence en iyi ve temiz çözüm:

window.addEventListener('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y);
});

Ve jQuery ile:

$(window).on('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y)
})

Bu olay dinleyicisi kaydırmayı engellemelidir. Kaydırmayı yeniden etkinleştirmek için kaldırmanız yeterlidir

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.