Cara menonaktifkan pemrograman halaman bergulir dengan jQuery


163

Menggunakan jQuery, saya ingin menonaktifkan scrolling dari body:

Ide saya adalah:

  1. Set body{ overflow: hidden;}
  2. Tangkap arus scrollTop();/scrollLeft()
  3. Bind ke acara body scroll, atur scrollTop / scrollLeft ke nilai yang diambil.

Apakah ada cara yang lebih baik?


Memperbarui:

Silakan lihat contoh saya, dan alasannya, di http://jsbin.com/ikuma4/2/edit

Saya sadar seseorang akan berpikir "mengapa dia tidak hanya menggunakan position: fixedpanel?".

Tolong jangan menyarankan ini karena saya punya alasan lain.


7
"Apakah ada cara yang lebih baik?" - selain membiarkan browser berperilaku normal?
Fenton

22
"Secara melodramatik"?
Mike Weller

6
Mungkin secara programatik? Karena ini adalah saran koreksi ejaan atas firefox untuk 'secara programatis'
Michael Shimmins

4
Utas ini berlangsung \ b \
Cipi

3
@Sohnee menonaktifkan scrolling! == buruk
Mansiemans

Jawaban:


136

Satu-satunya cara yang saya temukan untuk melakukan ini mirip dengan apa yang Anda gambarkan:

  1. Raih posisi gulir saat ini (jangan lupa sumbu horizontal!).
  2. Setel overflow ke tersembunyi (mungkin ingin mempertahankan nilai overflow sebelumnya).
  3. Gulir dokumen ke posisi gulir yang tersimpan dengan scrollTo ().

Lalu ketika Anda siap untuk mengizinkan pengguliran lagi, batalkan semua itu.

Sunting: tidak ada alasan saya tidak bisa memberikan kode karena saya kesulitan untuk menggalinya ...

// 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
silakan lihat jsbin.com/ikuma4/2/edit dan jelaskan alasan apa pun kepada saya bahwa Anda lebih baik? apakah saya kehilangan sesuatu (saya minta karena saya tidak dapat melihat alasan untuk panjang jawaban Anda dibandingkan dengan contoh saya)
Hailwood

3
Pendekatan Anda tidak berfungsi di IE7. Saya mencobanya dulu juga. Masalahnya adalah itu tidak bereaksi terhadap acara gulir dengan cukup cepat. Ini memungkinkan dokumen menggulir, lalu mengambilnya kembali ketika JS Anda mengatur ulang posisi gulir kembali ke tempat yang Anda inginkan.
tfe

1
Juga, jika tubuh memiliki kelebihan apa pun selain auto, itu akan ditimpa. Saya perlu mempertahankan pengaturan yang ada, sehingga menambah beberapa overhead juga.
tfe

Apakah ada yang tahu mengapa hanya styling htmldan bodydengan overflow: hiddentidak cukup? Kami masih membutuhkan event handler.
kpozin

4
Ini jawaban yang fantastis. Dan untuk membuatnya berfungsi pada perangkat sentuh, lihat jawaban ini .
Patrick

235

Ini sepenuhnya akan menonaktifkan pengguliran:

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

Untuk mengembalikan:

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

Mengujinya di Firefox dan Chrome.


18
bekerja seperti yang diharapkan. Terima kasih! Ini seharusnya jawaban yang diterima!
Dave Chen

6
Masih bergulir dengan tombol tengah mouse pada chrome.
Lothar

16
Ini kehilangan posisi gulir saat ini. OP secara eksplisit menyebutkan tentang mengambil posisi gulir, jadi saya menganggap dia memerlukan itu. Bagaimanapun, saya memerlukannya, jadi ini adalah penggunaan terbatas untuk saya
zerm

7
PS Menghilangkan height: 100%secara efektif mengunci gulir pada posisi saat ini tanpa melompat - pada Chrome terbaru, setidaknya.
zerm

2
Ini BUKAN jawaban yang benar. Posisi gulir tidak ditangkap
taylorcressy

43

coba ini

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

hanya apa yang saya cari ... hampir. Pokoknya untuk menonaktifkannya selama tombol panah?
Cody

2
@Cody - kombinasikan ini dengan css overflow: hidden
Darius.V

2
@ cubbiu bagaimana cara membalikkannya?
Meer

3
Anda dapat menggunakan$('#element').off('scroll touchmove mousewheel');
arnuschky

1
Solusi bagus Meskipun bagaimana Anda hanya menonaktifkan bodygulir namun memungkinkan gulir dalam elemen anak lain yang dimiliki overflow: scroll?
Fizzix

27

Saya hanya menyediakan sedikit penyetelan untuk solusi dengan TFE . Secara khusus, saya menambahkan beberapa kontrol tambahan untuk memastikan bahwa tidak ada pergeseran konten halaman (alias pergeseran halaman ) ketika bilah gulir diatur ke hidden.

Dua fungsi Javascript lockScroll()dan unlockScroll()dapat didefinisikan, masing-masing, untuk mengunci dan membuka kunci gulir halaman.

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

di mana saya berasumsi bahwa <body>tidak memiliki margin awal.

Perhatikan bahwa, sementara solusi di atas bekerja di sebagian besar kasus praktis, itu tidak definitif karena perlu beberapa penyesuaian lebih lanjut untuk halaman yang mencakup, misalnya, header dengan position:fixed. Mari kita masuk ke kasus khusus ini dengan sebuah contoh. Misalkan punya

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

dengan

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

Kemudian, seseorang harus menambahkan fungsi berikut ini lockScroll()dan unlockScroll():

function lockScroll(){
    //Omissis   


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

function unlockScroll(){
    //Omissis   

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

Akhirnya, berhati-hatilah dengan beberapa nilai awal yang mungkin untuk margin atau bantalan.


4
Anda memiliki kesalahan dalam $ javascript $ body.css Anda ({'margin-right': 0, 'margin-bottom', 0}); seharusnya $ body.css ({'margin-right': 0, 'margin-bottom': 0});
Johansrk

Sebenarnya, cukup gunakan marginRightdan marginLeft:)
Martijn

25

Anda dapat menggunakan kode ini:

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

8
Anda masih dapat menggunakan tombol tengah mouse untuk menggulir.
Roger Far

2
Tidak, ini tidak masalah dan tidak ada gulir dengan ini!
mr.soroush

Jika Anda menggunakan beberapa css tambahan, Anda BISA sepenuhnya menonaktifkan pengguliran, lihat jawaban saya untuk lebih jelasnya.
gitaarik

21

Untuk mematikan, gulir, cobalah ini:

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

untuk mengatur ulang:

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

Ini adalah solusi fantastis untuk apa yang saya butuhkan.
Terry Carter

@EveryScreamer tidak, itu membuat layar bergetar seperti orang gila. Mencoba mencari solusinya.
Telarian

5

Saya telah menulis plugin jQuery untuk menangani ini: $ .disablescroll .

Ini mencegah bergulir dari roda mouse, touchmove, dan acara menekan tombol, seperti Page Down.

Ada demo di sini .

Pemakaian:

$(window).disablescroll();

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

Saya sudah mencoba menggunakan plugin disablescroll () untuk menonaktifkan sementara pengguliran saat mendengar acara roda mouse / gulir, tetapi tidak berhasil. Adakah kesempatan Anda tahu cara untuk mencapai efek itu?
yellow-santo

@ JP Saya mungkin bisa membantu, tetapi komentar bukanlah tempat terbaik. Bergabunglah dengan saya dalam obrolan overflow tumpukan ini dan saya akan melihat apa yang dapat saya lakukan: chat.stackoverflow.com/rooms/55043/disablescroll-usage
Josh Harrison

Maaf, tetapi plugin ini bahkan tidak berfungsi di jsfiddle Anda.
markj

Anda dapat membantu saya memeriksa ini dengan memberi tahu saya browser / platform mana yang sepertinya tidak berfungsi?
Josh Harrison


4

Satu liner untuk menonaktifkan scroll termasuk tombol tengah mouse.

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

sunting : Tidak perlu untuk jQuery, di bawah sama seperti di atas di vanilla JS (itu berarti tidak ada kerangka kerja, hanya JavaScript):

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

this.documentElement.scrollTop - standar

this.body.scrollTop - kompatibilitas IE


4
  • Untuk Menyembunyikan Gulir: $("body").css("overflow", "hidden");
  • Untuk Mengembalikan Gulir: $("body").css("overflow", "initial");


3

Seseorang mem-posting kode ini, yang memiliki masalah tidak mempertahankan posisi gulir ketika dipulihkan. Alasannya adalah bahwa orang cenderung menerapkannya ke html dan tubuh atau hanya tubuh tetapi harus diterapkan ke html saja. Dengan cara ini ketika dikembalikan posisi gulir akan disimpan:

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

Untuk mengembalikan:

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

tidak 'overflow': 'auto',digunakan'overflow': 'initial',
evtuhovdo

2

Ini mungkin atau mungkin tidak berfungsi untuk tujuan Anda, tetapi Anda dapat memperluas jScrollPane untuk mem - flash fungsionalitas lain sebelum melakukan gulir. Saya baru saja menguji ini sedikit, tetapi saya dapat mengonfirmasi bahwa Anda dapat melompat masuk dan mencegah pengguliran sepenuhnya. Yang saya lakukan adalah:

  • Unduh zip demo: http://github.com/vitch/jScrollPane/archives/master
  • Buka demo "Acara" (events.html)
  • Edit untuk menggunakan sumber skrip non-minified: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • Di dalam jquery.jscrollpane.js, masukkan "return;" pada baris 666 (nomor baris keberuntungan! tetapi jika versi Anda sedikit berbeda, ini adalah baris pertama dari positionDragY(destY, animate)fungsi

Jalankan events.html, dan Anda akan melihat kotak yang biasanya bergulir karena intervensi pengkodean Anda tidak akan bergulir.

Anda dapat mengontrol seluruh scrollbar browser dengan cara ini (lihat fullpage_scroll.html).

Jadi, mungkin langkah selanjutnya adalah menambahkan panggilan ke beberapa fungsi lain yang padam dan melakukan sihir penahan Anda, kemudian memutuskan apakah akan melanjutkan dengan gulir atau tidak. Anda juga mendapat panggilan API untuk mengatur scrollTop dan scrollLeft.

Jika Anda ingin bantuan lebih lanjut, poskan di tempat Anda bangun!

Semoga ini bisa membantu.



1

Jika Anda hanya ingin menonaktifkan gulir dengan navigasi papan ketik, Anda dapat mengesampingkan acara keydown.

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

1

Coba kode ini:

    $(function() { 
        // ...

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

        // ...
    });

0

Anda dapat menutupi jendela dengan div yang dapat digulir untuk mencegah pengguliran konten pada halaman. Dan, dengan menyembunyikan dan menunjukkan, Anda dapat mengunci / membuka kunci gulir Anda.

Lakukan sesuatu seperti ini:

#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
Tolong jangan gunakan singkatan seperti "u" dan "smth". Luangkan waktu untuk mengeja dengan benar, agar mudah dibaca.
Manusia Timah

0

Untuk orang-orang yang memiliki tata letak terpusat (via margin:0 auto;), berikut ini adalah gabungan dari position:fixedsolusi bersama dengan solusi yang diajukan oleh @tfe .

Gunakan solusi ini jika Anda mengalami gertakan halaman (karena bilah gulir menampilkan / menyembunyikan).

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

... dikombinasikan dengan ...

// 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])

... dan akhirnya, CSS untuk .modal-noscroll...

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

Saya berani mengatakan ini adalah lebih dari memperbaiki yang tepat daripada solusi lain di luar sana, tapi saya belum diuji yang menyeluruh belum ...: P


Sunting: harap dicatat bahwa saya tidak tahu seberapa buruk hal ini (baca: meledakkan) pada perangkat sentuh.


0

Anda juga dapat menggunakan DOM untuk melakukannya. Katakanlah Anda memiliki fungsi yang Anda panggil seperti ini:

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

Dan hanya itu yang ada untuk itu! Semoga ini bisa membantu selain semua jawaban lain!


0

Inilah yang akhirnya saya lakukan:

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

Tidak yakin apakah ada yang mencoba solusi saya. Yang ini berfungsi pada seluruh tubuh / html tetapi tidak diragukan lagi itu dapat diterapkan ke elemen apa pun yang mengaktifkan acara gulir.

Cukup setel dan hapus set scrollLock sesuai kebutuhan.

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

Inilah contoh JSFiddle

Semoga yang ini membantu seseorang.


Yang ini berfungsi sebagaimana mestinya, dengan satu pengecualian. Ketika gulir terkunci, dan saya gulir, itu agak berkedut sedikit, sebelum benar-benar mengunci gulir ...
Thomas Teilmann

0

Saya pikir solusi terbaik dan bersih adalah:

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

Dan dengan jQuery:

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

Pendengar acara tersebut harus memblokir gulir. Hapus saja untuk mengaktifkan kembali gulir

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.