Bagaimana cara menonaktifkan pengguliran sementara?

434

Saya menggunakan plugin scrollTo jQuery dan ingin tahu apakah ada kemungkinan untuk menonaktifkan sementara bergulir pada elemen jendela melalui Javascript? Alasan saya ingin menonaktifkan pengguliran adalah ketika Anda menggulir saat scrollTo sedang menjiwai, itu menjadi sangat jelek;)

Tentu saja, saya bisa melakukan $("body").css("overflow", "hidden");dan kemudian mengembalikannya ke otomatis ketika animasi berhenti, tetapi akan lebih baik jika scrollbar itu masih terlihat tetapi tidak aktif.

Olivier Lalonde
sumber
12
Jika masih ditampilkan, maka pengguna dilatih untuk berpikir bahwa itu harus berfungsi. Jika dosis tidak bergerak atau dosis tidak merespons, maka itu akan mematahkan model mental pengguna tentang bagaimana halaman Anda bekerja dan menghasilkan kebingungan. Saya hanya akan menemukan cara yang lebih baik untuk menangani pengguliran sambil menghidupkan, seperti misalnya menghentikan animasi.
Marcus Whybrow

Jawaban:

731

The scrollevent tidak dapat dibatalkan. Tetapi Anda dapat melakukannya dengan membatalkan acara interaksi ini: Gulir
mouse & Sentuh dan Tombol yang terkait dengan pengguliran.

[ Demo kerja ]

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

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

function preventDefaultForScrollKeys(e) {
  if (keys[e.keyCode]) {
    preventDefault(e);
    return false;
  }
}

// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () { supportsPassive = true; } 
  }));
} catch(e) {}

var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

// call this to Disable
function disableScroll() {
  window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
  window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
  window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}

// call this to Enable
function enableScroll() {
  window.removeEventListener('DOMMouseScroll', preventDefault, false);
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 
  window.removeEventListener('touchmove', preventDefault, wheelOpt);
  window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

UPDATE: memperbaiki desktop Chrome dan browser ponsel modern dengan pendengar pasif

gblazex
sumber
114
Kiat untuk pengembang lain yang terjebak dalam jebakan ini: Pastikan Anda menghapus semua dan semua panggilan 'e.stopPropagation ()' dari jQuery lain mencoba menghentikan pengguliran, karena tidak hanya itu tidak berfungsi, itu mencegah acara meleleh ke kode INI itu TIDAK bekerja. Semoga 30 menit saya yang terbuang akan membantu menghemat waktu orang lain :)
Dirk van Bergen
4
Anda dapat menambahkan 32 (spasi) ke array kunci yang dinonaktifkan (tunjukkan dalam komentar kode).
gblazex
14
Saya dapat menggulir ini seperti yang selalu saya lakukan: menggunakan tombol tengah tekan dan gerakkan mouse ... Karenanya trik ini tidak akan memengaruhi pengguna seperti saya;)
Denis V
11
Bilah gulir tidak dinonaktifkan.
verism
8
Ini tidak berfungsi lagi di Chrome
PerrierCitror
427

Lakukan itu hanya dengan menambahkan kelas ke tubuh:

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

Tambahkan kelas lalu hapus ketika Anda ingin mengaktifkan kembali pengguliran, diuji di IE, FF, Safari dan Chrome.

$('body').addClass('stop-scrolling')

Untuk perangkat seluler , Anda harus menangani touchmoveacara:

$('body').bind('touchmove', function(e){e.preventDefault()})

Dan lepaskan ikatan untuk mengaktifkan kembali scroll. Diuji di iOS6 dan Android 2.3.3

$('body').unbind('touchmove')
hallodom
sumber
4
Oke! Anda harus menangani touchmoveacara tersebut, seperti dengan $('body').bind('touchmove', function(e){e.preventDefault()}). Diedit jawaban ini untuk memasukkan solusi seluler ini.
MusikAnimal
3
Keren, hanya perlu memastikan pengguliran dalam dapat bekerja di modal untuk perangkat sentuh. Bisa melakukan overlay tepat di bawah modal dan mencegah touchmove default pada overlay alih-alih badan.
hallodom
63
Sementara solusi ini berhasil, ia memiliki (kemungkinan) efek yang tidak diinginkan dengan menggulir kembali ke bagian atas halaman.
Matt
3
Ini tidak berfungsi untuk saya kecuali pemilih saya$('body,html')
PickYourPoison
22
Solusi ini berfungsi tetapi bilah gulir menghilang dan membuat efek 'gundukan' (di bawah jendela os) ketika Anda menerapkan kelas ini ke tubuh (misalnya)
Georgio
57

Inilah cara yang sangat mendasar untuk melakukannya:

window.onscroll = function () { window.scrollTo(0, 0); };

Agak gelisah di IE6.

sdleihssirhc
sumber
14
Tidak benar-benar melumpuhkan, lebih seperti snap ke default ketika gulir dicoba.
Marcus Whybrow
11
@Marcus Sebaiknya dapatkan dengan acara yang tidak dapat dibatalkan.
sdleihssirhc
3
Meskipun itu tidak menonaktifkannya nyata, itu mensimulasikan dan itu cukup baik untuk saya.
Chris Bier
11
IMHO - jawaban terbaik di sini. Plus, Anda tidak harus menguncinya (0, 0), cukup gunakan posisi gulir saat ini.
YemSalat
4
Tetapi bagaimana kita mengaktifkannya kembali?
Cybernetic
41

Solusi berikut ini adalah JavaScript dasar tetapi murni (tanpa jQuery):

function disableScrolling(){
    var x=window.scrollX;
    var y=window.scrollY;
    window.onscroll=function(){window.scrollTo(x, y);};
}

function enableScrolling(){
    window.onscroll=function(){};
}
Mohammad Anini
sumber
3
Gelisah di Safari 7.1 dan IE 11. Chrome Terbaru, Firefox, Opera ok.
Timo Kähkönen
Masih sedikit gelisah pada Chrome terbaru
Jason Allshorn
Bekerja dengan baik, Di safari, chrome, tetapi berkedip di IE
Bhuvan Arora
Jika solusi ini tidak berfungsi untuk beberapa browser, maka itu adalah masalah browser
Oto Shavadze
Seperti disebutkan pada jawaban lain, scroll-behavior: smoothborks this. Juga, saya tidak setuju dengan Oto yang mengatakan bahwa itu adalah kesalahan browser. Anda pada dasarnya berasumsi bahwa sesuatu akan terjadi secara instan padahal kenyataannya asinkron
Matt Fletcher
25

Solusi ini akan mempertahankan posisi gulir saat ini sementara menggulir dinonaktifkan, tidak seperti beberapa yang melompat pengguna kembali ke atas.

Ini didasarkan pada jawaban galambalazs , tetapi dengan dukungan untuk perangkat sentuh, dan di refactored sebagai objek tunggal dengan pembungkus plugin jquery.

Demo di sini.

Di github di sini.

/**
 * $.disablescroll
 * Author: Josh Harrison - aloof.co
 *
 * Disables scroll events from mousewheels, touchmoves and keypresses.
 * Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
 */

;(function($) {

    "use strict";

    var instance, proto;

    function UserScrollDisabler($container, options) {
        // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
        // left: 37, up: 38, right: 39, down: 40
        this.opts = $.extend({
            handleKeys : true,
            scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
        }, options);

        this.$container = $container;
        this.$document = $(document);
        this.lockToScrollPos = [0, 0];

        this.disable();
    }

    proto = UserScrollDisabler.prototype;

    proto.disable = function() {
        var t = this;

        t.lockToScrollPos = [
            t.$container.scrollLeft(),
            t.$container.scrollTop()
        ];

        t.$container.on(
            "mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
            t._handleWheel
        );

        t.$container.on("scroll.disablescroll", function() {
            t._handleScrollbar.call(t);
        });

        if(t.opts.handleKeys) {
            t.$document.on("keydown.disablescroll", function(event) {
                t._handleKeydown.call(t, event);
            });
        }
    };

    proto.undo = function() {
        var t = this;
        t.$container.off(".disablescroll");
        if(t.opts.handleKeys) {
            t.$document.off(".disablescroll");
        }
    };

    proto._handleWheel = function(event) {
        event.preventDefault();
    };

    proto._handleScrollbar = function() {
        this.$container.scrollLeft(this.lockToScrollPos[0]);
        this.$container.scrollTop(this.lockToScrollPos[1]);
    };

    proto._handleKeydown = function(event) {
        for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
            if (event.keyCode === this.opts.scrollEventKeys[i]) {
                event.preventDefault();
                return;
            }
        }
    };


    // Plugin wrapper for object
    $.fn.disablescroll = function(method) {

        // If calling for the first time, instantiate the object and save
        // reference. The plugin can therefore only be instantiated once per
        // page. You can pass options object in through the method parameter.
        if( ! instance && (typeof method === "object" || ! method)) {
            instance = new UserScrollDisabler(this, method);
        }

        // Instance already created, and a method is being explicitly called,
        // e.g. .disablescroll('undo');
        else if(instance && instance[method]) {
            instance[method].call(instance);
        }

    };

    // Global access
    window.UserScrollDisabler = UserScrollDisabler;

})(jQuery);
Josh Harrison
sumber
Senang itu berguna. NB Saya telah mengedit dengan tautan ke ini dalam format plugin jQuery .
Josh Harrison
Mungkin bisa membantu jika tombol gulir penonaktifan benar-benar berfungsi
cameronjonesweb
@ user1672694, ini berfungsi di sini di Chrome. Apa browser Anda dan halaman demo mana Anda menemukan bug? Adakah kesalahan JS di konsol?
Josh Harrison
Di Chrome (38, Windows 7), saya masih bisa menggulir dengan mengklik dan menahan tombol tengah ke bawah, lalu menyeret.
Sethi
1
Tolong abaikan, saya menemukan bahwa mengikat itu mousewheelberhasil pesona
adamj
17

Saya minta maaf untuk menjawab posting lama tetapi saya sedang mencari solusi dan menemukan pertanyaan ini.

Ada banyak solusi untuk masalah ini agar tetap menampilkan bilah gulir, seperti memberi wadah tinggi 100% dan overflow-y: scrollgaya.

Dalam kasus saya, saya baru saja membuat div dengan scrollbar yang saya tampilkan sambil menambahkan overflow: hiddenke badan:

function disableScroll() {
    document.getElementById('scrollbar').style.display = 'block';
    document.body.style.overflow = 'hidden';
}

Bilah gulir elemen harus memiliki gaya ini:

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

Ini menunjukkan scrollbar abu-abu, semoga membantu pengunjung di masa depan.

lisovaccaro
sumber
8

Saya mencari solusi untuk masalah ini tetapi tidak puas dengan salah satu solusi di atas ( saat menulis jawaban ini ), jadi saya datang dengan solusi ini ..

CSS

.scrollDisabled {   
    position: fixed;
    margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
    width: 100%;
}

JS

var y_offsetWhenScrollDisabled=0;

function disableScrollOnBody(){
    y_offsetWhenScrollDisabled= $(window).scrollTop();
    $('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
    $('body').removeClass('scrollDisabled').css('margin-top', 0);
    $(window).scrollTop(y_offsetWhenScrollDisabled);
}
Rajat Gupta
sumber
Saya menemukan ini bekerja untuk saya jika saya menambahkan overflow-y: scrollke .scrollDisabledgaya. Kalau tidak, ada sedikit lompatan ketika bilah gulir bersembunyi setiap kali. Tentu saja, itu hanya berfungsi untuk saya karena halaman saya cukup lama sehingga memerlukan scrollbar bahkan pada layar terbesar.
Andrew Miner
7

Menurut posting galambalazs saya akan menambahkan dukungan untuk perangkat sentuh, memungkinkan kita untuk menyentuh tetapi tidak ada gulir ke atas atau ke bawah:

function disable_scroll() {
   ...
   document.ontouchmove = function(e){ 
        e.preventDefault(); 
   }
}

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}
jvalen
sumber
3
Apakah Anda yakin itu adalah jawaban, bukan hanya komentar dari jawaban lain?
IvanH
6

Pada Chrome 56 dan browser modern lainnya, Anda harus menambahkan passive:falseke addEventListenerpanggilan untuk membuat preventDefaultpekerjaan. Jadi saya menggunakan ini untuk berhenti menggulir di ponsel:

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

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}
Hokascha
sumber
5

Tidak, saya tidak akan pergi dengan penanganan acara karena:

  • tidak semua acara dijamin mencapai tubuh,

  • memilih teks dan bergerak ke bawah sebenarnya menggulung dokumen,

  • jika pada tahap pelepasan sth terjadi kesalahan Anda ditakdirkan.

Saya sudah digigit oleh ini dengan membuat tindakan copy-paste dengan textarea tersembunyi dan coba tebak, halaman gulir setiap kali saya membuat copy karena secara internal saya harus memilih textarea sebelum saya menelepon document.execCommand('copy').

Pokoknya begitulah cara saya pergi, perhatikan setTimeout():

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

Sebuah momentum yang berkedip ada saat bilah gulir menghilang sebentar, tetapi itu bisa diterima.

centurian
sumber
4

Bergantung pada apa yang ingin Anda capai dengan gulir yang dihapus, Anda bisa memperbaiki elemen yang ingin Anda hapus gulir (saat klik, atau pemicu lain apa pun yang ingin Anda matikan sementara gulir)

Saya mencari-cari solusi "temp no scroll" dan untuk kebutuhan saya, ini menyelesaikannya

buat kelas

.fixed{
    position: fixed;
}

lalu dengan Jquery

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from

contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class

//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){

    if(contentContainer.hasClass('notfixed')){
        contentContainer.removeClass('notfixed').addClass('fixed');

    }else if(contentContainer.hasClass('fixed')){
        contentContainer.removeClass('fixed').addClass('notfixed');
    };
});

Saya menemukan bahwa ini adalah solusi yang cukup sederhana yang bekerja dengan baik di semua browser, dan juga membuatnya mudah digunakan pada perangkat portabel (yaitu iPhone, tablet, dll). Karena elemen sementara diperbaiki, tidak ada scroll :)

CATATAN! Bergantung pada penempatan elemen "contentContainer" Anda, Anda mungkin perlu menyesuaikannya dari kiri. Yang dapat dengan mudah dilakukan dengan menambahkan nilai kiri css ke elemen itu ketika kelas tetap aktif

contentContainer.css({
    'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});
axelra82
sumber
4

Solusi lain:

body {
    overflow-y: scroll;
    width: 100%;
    margin: 0 auto;
}

Dengan cara ini Anda selalu memiliki bilah gulir vertikal, tetapi karena sebagian besar konten saya lebih panjang dari viewport, ini ok untuk saya. Konten dipusatkan dengan div terpisah, tetapi tanpa mengatur margin lagi di tubuh konten saya akan tetap di sebelah kiri.

Ini adalah dua fungsi yang saya gunakan untuk menampilkan munculan / modal saya:

var popup_bodyTop = 0;
var popup_bodyLeft = 0;

function popupShow(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');

    // remember current scroll-position
    // because when setting/unsetting position: fixed to body
    // the body would scroll to 0,0
    popup_bodyLeft = $(document).scrollLeft();
    popup_bodyTop  = $(document).scrollTop();

    // invert position
    var x = - popup_bodyLeft;
    var y = - popup_bodyTop;

    $('body').css('position', 'fixed');
    $('body').css('top', y.toString() +'px');
    $('body').css('left', x.toString() +'px');
}

function popupHide(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');
    $('body').css('position', '');
    $('html, body').scrollTop(popup_bodyTop);
    $('html, body').scrollLeft(popup_bodyLeft);
}

Hasil: latar belakang yang tidak dapat digulir dan tidak ada pemosisian ulang konten karena scrollbar kiri. Diuji dengan FF saat ini, Chrome dan IE 10.

Marco
sumber
Ini bekerja untuk saya dan masalah gulir ke atas setelah menggunakan posisi: diperbaiki. Terima kasih!
Annia Martinez
3

Bagaimana dengan ini? (Jika Anda menggunakan jQuery)

var $window = $(window);
var $body = $(window.document.body);

window.onscroll = function() {
    var overlay = $body.children(".ui-widget-overlay").first();

    // Check if the overlay is visible and restore the previous scroll state
    if (overlay.is(":visible")) {
        var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
        window.scrollTo(scrollPos.x, scrollPos.y);
    }
    else {
        // Just store the scroll state
        $body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
    }
};
Dan
sumber
agak gelisah, tetapi ini bekerja untuk IE 7 (klien menggunakannya). solusi lain tidak.
niki b
3

Saya menggunakan showModalDialog , untuk menampilkan halaman sekunder sebagai dialog modal.

untuk menyembunyikan scrollbar jendela utama:

document.body.style.overflow = "hidden";

dan saat menutup dialog modal, menampilkan bilah gulir jendela utama:

document.body.style.overflow = "scroll";

untuk mengakses elemen di jendela utama dari dialog:

parent.document.getElementById('dialog-close').click();

hanya untuk siapa saja yang mencari tentang showModalDialog : (setelah baris 29 dari kode asli)

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
    e.preventDefault();
    document.body.style.overflow = "scroll";//****
    dialog.close();
});
Zolfaghari
sumber
Ini berfungsi untuk saya di Bereaksi di mana jQuery tidak ada dan di mana Bereaksi tidak memiliki akses untuk mengelola keadaan tag tubuh.
Jon
3

Membatalkan acara seperti pada jawaban yang diterima adalah metode yang mengerikan menurut saya: /

Sebaliknya saya gunakan di position: fixed; top: -scrollTop();bawah ini.

Demo: https://jsfiddle.net/w9w9hthy/5/

Dari proyek popup jQuery saya: https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
    if($("html").css("position") != "fixed") {
        var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
        if(window.innerWidth > $("html").width()) {
            $("html").css("overflow-y", "scroll");
        }
        $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
    }
}

//Unfreeze page content scrolling
function unfreeze() {
    if($("html").css("position") == "fixed") {
        $("html").css("position", "static");
        $("html, body").scrollTop(-parseInt($("html").css("top")));
        $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
    }
}

Kode ini mempertimbangkan, lebar, tinggi, scrollbar dan masalah pagejump menjadi pertimbangan.

Kemungkinan masalah teratasi dengan kode di atas:

  • lebar, ketika mengatur posisi tetap, lebar elemen html bisa lebih kecil dari 100%
  • tinggi, sama seperti di atas
  • scrollbar, ketika mengatur posisi memperbaiki konten halaman tidak lagi memiliki scrollbar bahkan ketika itu memiliki scrollbar sebelum menghasilkan pagejump horizontal
  • pagejump, ketika pengaturan posisi diperbaiki halaman ScrollTop tidak lagi efektif menghasilkan pagejump vertikal

Jika ada yang memiliki perbaikan pada kode pembekuan / pembekuan halaman di atas, beri tahu saya agar saya dapat menambahkan peningkatan tersebut ke proyek saya.

kuda laut
sumber
3
var winX = null, winY = null;
window.addEventListener('scroll', function () {
    if (winX !== null && winY !== null) {
        window.scrollTo(winX, winY);
    }
});
function disableWindowScroll() {
    winX = window.scrollX;
    winY = window.scrollY;
};
function enableWindowScroll() {
    winX = null;
    winY = null;
};
Văn Quyết
sumber
1
Ini solusi terbaik di sini.
jfunk
@ jfunk setuju, sederhana dan ringkas, kode kecil, sempurna. Terima kasih
Florent Roques
2

Saya memiliki masalah yang sama, di bawah ini adalah cara saya menanganinya.

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");

/* file.css */
.no-scroll{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

semoga ini membantu.

Robert
sumber
1

Membangun jawaban Cheyenne Forbes, dan yang saya temukan di sini melalui fcalderan: Cukup nonaktifkan scroll bukan menyembunyikannya? dan untuk memperbaiki masalah Hallodom tentang scrollbar menghilang

CSS:

.preventscroll{
    position: fixed;
    overflow-y:scroll;
}

JS:

whatever.onclick = function(){
    $('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
    $('body').removeClass('preventscroll');
}

Kode ini membuat Anda melompat ke bagian atas halaman, tetapi saya pikir kode fcalderan memiliki solusi.

Berdalih
sumber
1

Saya tahu ini adalah pertanyaan lama, tetapi saya harus melakukan sesuatu yang sangat mirip, dan setelah beberapa waktu mencari jawaban dan mencoba pendekatan yang berbeda, saya akhirnya menggunakan solusi yang sangat mudah.

Masalah saya sangat mirip, hampir identik, satu-satunya perbedaan adalah saya tidak harus benar-benar menampilkan bilah gulir - Saya hanya harus memastikan lebarnya masih akan digunakan, sehingga lebar halaman tidak akan berubah saat overlay saya ditampilkan .

Ketika saya mulai menggeser hamparan saya ke layar, saya lakukan:

$('body').addClass('stop-scrolling').css('margin-right', 8);

dan setelah saya geser overlay saya dari layar saya lakukan:

$('body').removeClass('stop-scrolling').css('margin-right', 0);

PENTING: ini berfungsi dengan baik karena overlay saya diposisikan absolute, right: 0pxkapan visible.

pengguna2430829
sumber
1

Metode paling sederhana adalah:

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

Untuk membatalkannya:

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

Mudah diimplementasikan, tetapi satu-satunya downside adalah:

  • Halaman akan melompat sedikit ke kiri jika sejajar tengah (horizontal).

Ini karena bilah gulir dihapus, dan viewport menjadi sedikit lebih lebar.

Daan
sumber
1
yang akan mengatur ulang posisi gulir
Malaikat David Calderaro Pacciott
@AngelDavidCalderaroPacciott Tidak, posisi gulir akan tetap dengan tinggi / jarak yang sama.
Daan
@Daan itu mengatur ulang posisi gulir di Chrome
Tom
@ Tom saya baru saja memeriksanya, itu hanya terjadi pada beberapa kesempatan (ketika tinggi badan tidak relatif terhadap anak-anaknya). Silakan coba ganti bodyke html.
Daan
Saya yakin Anda tidak memeriksa solusi Anda di iPhone karena overflow:hiddentidak berfungsi di sana
Shuvo
1

Ini solusi saya untuk menghentikan scroll (tidak ada jQuery). Saya menggunakannya untuk menonaktifkan gulir ketika menu samping muncul.

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
  if(noscroll_var){
    document.getElementsByTagName("html")[0].style.overflowY = "";
    document.body.style.paddingRight = "0";
    noscroll_var = false
  }else{
    document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
    document.body.style.paddingRight = "17px";
    noscroll_var = true
  }
}/*noscroll()*/
</script>

<!-- Just to fill the page -->
<script>
  for(var i=0; i <= 80; i++){
    document.write(i + "<hr>")
  }
</script>

Saya menempatkan 17px padding-right untuk mengkompensasi hilangnya scroll bar. Tapi ini juga bermasalah, kebanyakan untuk browser seluler. Dipecahkan dengan mendapatkan lebar bilah sesuai dengan ini .

Semua bersama dalam Pena ini.

Josep81
sumber
1

Ini adalah solusi paling sederhana yang saya dapatkan sejauh ini. Dan percayalah, saya sudah mencoba yang lain dan ini yang paling mudah. Ini berfungsi dengan baik pada perangkat Windows , yang mendorong halaman dari kanan untuk memiliki ruang untuk scrollbar sistem dan perangkat IOS yang tidak memerlukan ruang untuk scrollbar mereka di browser. Jadi dengan menggunakan ini Anda tidak perlu menambahkan padding di sebelah kanan sehingga halaman tidak berkedip ketika Anda menyembunyikan overflow tubuh atau html dengan css .

Solusinya cukup sederhana jika Anda memikirkannya. Idenya adalah untuk memberikan window.scrollTop () posisi tepat yang sama pada saat popup dibuka. Juga ubah posisi itu ketika ukuran jendela (karena posisi gulir berubah begitu itu terjadi).

Jadi di sini kita pergi ...

Pertama mari kita buat variabel yang akan memberi tahu Anda bahwa popup terbuka dan menyebutnya stopWindowScroll . Jika kami tidak melakukan ini, maka Anda akan mendapatkan kesalahan dari variabel yang tidak ditentukan pada halaman Anda dan mengaturnya ke 0 - sebagai tidak aktif.

$(document).ready(function(){
    stopWindowScroll = 0;
});

Sekarang mari kita buat penyihir fungsi popup terbuka dapat berupa fungsi apa pun dalam kode Anda yang memicu sembulan apa pun yang Anda gunakan sebagai plugin atau kustom. Dalam hal ini akan menjadi popup kustom sederhana dengan dokumen sederhana pada fungsi klik.

$(document).on('click','.open-popup', function(){
    // Saving the scroll position once opening the popup.
    stopWindowScrollPosition = $(window).scrollTop();
    // Setting the stopWindowScroll to 1 to know the popup is open.
    stopWindowScroll = 1;
    // Displaying your popup.
    $('.your-popup').fadeIn(300);
});

Jadi hal berikutnya yang kita lakukan adalah membuat fungsi tutup sembulan, yang saya ulangi lagi dapat berupa fungsi apa pun yang sudah Anda buat atau gunakan dalam sebuah plugin. Yang penting adalah bahwa kita membutuhkan 2 fungsi untuk mengatur variabel stopWindowScroll menjadi 1 atau 0 untuk mengetahui kapan itu terbuka atau tertutup.

$(document).on('click','.open-popup', function(){
    // Setting the stopWindowScroll to 0 to know the popup is closed.
    stopWindowScroll = 0;
    // Hiding your popup
    $('.your-popup').fadeOut(300);
});

Kemudian mari kita buat fungsi window.scroll sehingga kita dapat mencegah pengguliran begitu stopWindowScroll yang disebutkan di atas diatur ke 1 - sebagai aktif.

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

Itu dia. Tidak diperlukan CSS agar ini berfungsi kecuali gaya Anda sendiri untuk halaman tersebut. Ini berfungsi seperti pesona bagi saya dan saya harap ini membantu Anda dan orang lain.

Berikut ini contoh yang berhasil di JSFiddle:

Contoh JS Fiddle

Beri tahu saya jika ini membantu. Salam.

Arsitek
sumber
1

Simpan panjang gulir dalam variabel global dan pulihkan saat diperlukan!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}
Kareem
sumber
1

Kode ini akan berfungsi di Chrome 56 dan lebih lanjut (jawaban asli tidak berfungsi di Chrome lagi).

Menggunakan DomUtils.enableScroll() untuk mengaktifkan pengguliran.

Gunakan DomUtils.disableScroll()untuk menonaktifkan pengguliran.

class DomUtils {
  // left: 37, up: 38, right: 39, down: 40,
  // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
  static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };

  static preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;
  }

  static preventDefaultForScrollKeys(e) {
    if (DomUtils.keys[e.keyCode]) {
      DomUtils.preventDefault(e);
      return false;
    }
  }

  static disableScroll() {
    document.addEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Disable scrolling in Chrome
    document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
      passive: false,
    });
  }

  static enableScroll() {
    document.removeEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Enable scrolling in Chrome
    document.removeEventListener(
      'keydown',
      DomUtils.preventDefaultForScrollKeys,
      {
        passive: false,
      }
    ); // Enable scrolling in Chrome
  }
}
PerrierCitror
sumber
1

Untuk mencegah lompatan, inilah yang saya gunakan

export function toggleBodyScroll(disable) {
  if (!window.tempScrollTop) {
    window.tempScrollTop = window.pageYOffset; 
    // save the current position in a global variable so I can access again later

  }
  if (disable) {
    document.body.classList.add('disable-scroll');
    document.body.style.top = `-${window.tempScrollTop}px`;
  } else {
    document.body.classList.remove('disable-scroll');
    document.body.style.top = `0px`;
    window.scrollTo({top: window.tempScrollTop});
    window.tempScrollTop = 0;
  }
}

dan di css saya

.disable-scroll {
  height: 100%;
  overflow: hidden;
  width: 100%;
  position: fixed;
}
Milad
sumber
0

Saya menemukan jawaban ini di situs lain :

Nonaktifkan gulir:

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

Setelah menutup gulir rilis popup:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});
Pennstump
sumber
Itu tampaknya hanya berhenti menggulirkan sentuhan, tetapi mouse menggulir, tombol panah, halaman naik dan turun, dll akan tetap berfungsi. -1
markasoftware
'Acara' ini untuk menggulirkan sentuhan, cukup gantikan acara apa pun yang Anda butuhkan.
pennstump
1
juga, ini tampaknya digunakan dalam beberapa situasi yang sangat spesifik lainnya. popupbeforeposisi? Untuk apa itu? Apa hubungannya ini dengan menonaktifkan sementara pengguliran? Setidaknya membuatnya relevan dengan situasi ini. Sepertinya Anda menyalin ini langsung dari situs web.
markasoftware
0

solusi galambalazs luar biasa! Ini bekerja dengan baik untuk saya di Chrome dan Firefox. Dan itu juga dapat diperpanjang untuk mencegah acara default apa pun dari jendela browser. Katakanlah Anda sedang melakukan aplikasi di atas kanvas. Anda bisa melakukan ini:

var events = {
  preventDefault: function(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;  
  },

  //spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
  //left: 37, up: 38, right: 39, down: 40
  keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
  keydown: function(e) {
    for (var i = events.keys.length; i--;) {
      if (e.keyCode === events.keys[i]) {
        events.preventDefault(e);
        return;
      }
    }
  },

  wheel: function(e) {
    events.preventDefault(e);
  },

  disable: function() {
    if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = events.wheel;
    document.onkeydown = helpers.events.keydown;
  },

  enable: function() {
    if (window.removeEventListener) {
      window.removeEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
  }
}

Dan kemudian pada aplikasi Anda katakanlah Anda akan memproses acara Anda sendiri, seperti mouse, keyboard, acara sentuh dan sebagainya ... Anda dapat menonaktifkan acara default ketika mouse masuk ke dalam kanvas dan mengaktifkannya kembali ketika mouse keluar:

function setMouseEvents(canvas) {
  var useCapture = false;

  //Mouse enter event
  canvas.addEventListener('mouseenter', function(event) {
    events.disable();
  }, useCapture);

  //Mouse leave event
  canvas.addEventListener('mouseleave', function(event) {
    events.enable();
  }, useCapture);
}

Anda bahkan dapat menonaktifkan menu klik kanan dengan peretasan ini:

function disableRightClickMenu(canvas) {
  var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
  my_gradient.addColorStop(0, "white");
  my_gradient.addColorStop(1, "white");
  canvas.context.fillStyle = my_gradient;
  canvas.context.fillRect(0, 0, canvas.width, canvas.height);
  canvas.oncontextmenu = function() { return false; };
}
Rafael
sumber
0

Saya memiliki masalah animasi yang serupa pada layar ponsel tetapi tidak pada laptop, ketika mencoba menghidupkan div menggunakan perintah animasi jquery. Jadi saya memutuskan untuk menggunakan timer yang mengembalikan posisi gulir jendela begitu sering sehingga dengan mata telanjang dokumen akan tampak statis. Solusi ini bekerja dengan sempurna pada perangkat seluler layar kecil seperti Samsung Galaxy-2 atau iphone-5.

Logika Utama dari pendekatan ini : Timer untuk mengatur posisi gulir jendela ke posisi gulir asli harus dimulai sebelum perintah animasi jquery, dan kemudian ketika animasi selesai kita perlu menghapus timer ini ( original scroll positionadalah posisi sebelum animasi dimulai).

Saya menemukan kejutan yang menyenangkan bahwa dokumen itu benar-benar tampak statis selama durasi animasi jika interval waktu itu 1 millisecond, yang saya tuju.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

SOLUSI LAIN yang berfungsi : Berdasarkan jawaban oleh Mohammad Anini di bawah posting ini untuk mengaktifkan / menonaktifkan pengguliran, saya juga menemukan bahwa versi kode yang dimodifikasi seperti di bawah ini berfungsi.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});
Sunil
sumber
0

Solusi sederhana yang bekerja untuk saya (menonaktifkan pengguliran jendela sementara).

Berdasarkan biola ini: http://jsfiddle.net/dh834zgw/1/

cuplikan berikut (menggunakan jquery) akan menonaktifkan gulir jendela:

 var curScrollTop = $(window).scrollTop();
 $('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

Dan di css Anda:

html.noscroll{
    position: fixed;
    width: 100%;
    top:0;
    left: 0;
    height: 100%;
    overflow-y: scroll !important;
    z-index: 10;
 }

Sekarang ketika Anda menghapus modal, jangan lupa untuk menghapus kelas noscroll pada tag html:

$('html').toggleClass('noscroll');
ling
sumber