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.

Hailwood
sumber
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])
tfe
sumber
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.

gitaarik
sumber
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;
})
cubbiu
sumber
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.

JeanValjean
sumber
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");
Tuan .ousoush
sumber
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');
Patrick DaVader
sumber
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");
Josh Harrison
sumber
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
5

Anda dapat melampirkan fungsi untuk menggulir acara dan mencegah perilaku defaultnya.

var $window = $(window);

$window.on("mousewheel DOMMouseScroll", onMouseWheel);

function onMouseWheel(e) {
    e.preventDefault();
}

https://jsfiddle.net/22cLw9em/

dzimi
sumber
1
Ini adalah jawaban yang benar. Tidak tahu mengapa ini tidak diatur seperti itu
Guilherme Ferreira
Berhasil. Hanya perlu kode reset diposting untuk mencocokkan jawaban Patricks
Hastig Zusammenstellen
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

Pawel
sumber
4
  • Untuk Menyembunyikan Gulir: $("body").css("overflow", "hidden");
  • Untuk Mengembalikan Gulir: $("body").css("overflow", "initial");
Joan Alberto Aguilar Peña
sumber
3

Tidak bisakah Anda mengatur tinggi badan menjadi 100% dan melimpah disembunyikan? Lihat http://jsbin.com/ikuma4/13/edit

Adrian Schmidt
sumber
$ ("html"). css ({height: '100%', overflow: 'hidden'}); Sederhananya, terima kasih Adrian
Alexey
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'
});
Mescalina
sumber
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.

Jeremy Warne
sumber
2

Saya memberikan jawaban yang mungkin membantu di sini: jQuery simplemodal disable scrolling

Ini menunjukkan cara mematikan bilah gulir tanpa menggeser teks di sekitar. Anda dapat mengabaikan bagian tentang simplemodal.

mhenry1384
sumber
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();
});
sean
sumber
1

Coba kode ini:

    $(function() { 
        // ...

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

        // ...
    });
Jopie
sumber
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();
}
Appex
sumber
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.

Matthemattics
sumber
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!

Brendan
sumber
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");
});
Marz
sumber
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.

FosilMFC
sumber
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

Tiziano
sumber