Kaydırma geçici olarak nasıl devre dışı bırakılır?


434

ScrollTo jQuery eklentisini kullanıyorum ve geçici olarak Javascript aracılığıyla pencere öğesinde kaydırma devre dışı bırakmanın mümkün olup olmadığını bilmek istiyorum? Kaydırmayı devre dışı bırakmamın nedeni, scrollTo animasyonu yaparken kaydırma yaptığınızda gerçekten çirkinleşmesi;)

Tabii ki, bir $("body").css("overflow", "hidden");animasyon yapabilir ve sonra animasyon durduğunda otomatik olarak geri koyabilirim, ancak kaydırma çubuğunun hala görünür ancak etkin olmasa daha iyi olurdu.


12
Hala gösteriliyorsa, kullanıcı işlevini yerine getirmesi gerektiğini düşünerek eğitilir. Doz hareket etmiyorsa veya doz yanıt vermiyorsa, sayfanın nasıl çalıştığına dair zihinsel modeli kırar ve karışıklığa neden olur. Animasyon sırasında kaydırma ile uğraşmanın daha iyi bir yolunu bulurdum, örneğin animasyonu durdurmak gibi.
Marcus Whybrow

Yanıtlar:


731

scrollOlay iptal edilemez. Ancak şu etkileşim olaylarını iptal ederek yapabilirsiniz :
Fare ve Dokunmatik kaydırma ve Kaydırma ile ilişkili düğmeler .

[ Çalışma demosu ]

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

GÜNCELLEME: sabit Chrome masaüstü ve pasif dinleyicilere sahip modern mobil tarayıcılar


114
Bu tuzağa sıkışmış diğer geliştiriciler için ipucu: Diğer jQuery çağrılarından herhangi bir ve tüm 'e.stopPropagation ()' çağrısını kaldırdığınızdan emin olun, çünkü yalnızca çalışmaz, olayın BU kodda köpürmesini engeller Bu işe yarar. İnşallah benim 30 dakika boşa başkasının zamandan tasarruf yardımcı olacaktır :)
Dirk van Bergen

4
Devre dışı bırakılmış anahtarlar dizisine 32 (boşluk) ekleyebilirsiniz (kod yorumlarında göster).
gblazex

14
Bunu her zaman yaptığım gibi kaydırabilirim: orta düğmeye basmak ve fareyi hareket ettirmek ... Bu nedenle bu hile benim gibi kullanıcıları etkilemez;)
Denis V

11
Kaydırma çubuğu devre dışı değil.
verizm

8
Bu artık Chrome'da çalışmıyor
PerrierCitror

427

Sadece vücuda bir sınıf ekleyerek yapın:

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

Sınıfı ekleyin ve IE, FF, Safari ve Chrome'da test edilen kaydırmayı yeniden etkinleştirmek istediğinizde kaldırın.

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

İçin mobil cihazlar , sen işlemek gerekir touchmoveolayı:

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

Kaydırmayı yeniden etkinleştirmek için bağlantıyı kaldırın. İOS6 ve Android 2.3.3'te test edildi

$('body').unbind('touchmove')

4
Anladım! Sen işlemek zorunda touchmoveolduğu gibi, olayı $('body').bind('touchmove', function(e){e.preventDefault()}). Bu yanıtı, bu mobil çözümü içerecek şekilde düzenledi.
MusikAnimal

3
Serin, sadece dokunmatik cihazın modalında herhangi bir iç kaydırmanın çalışabileceğinden emin olmanız gerekir. Modalın hemen altında bir kaplama yapabilir ve kaplamanın gövde yerine varsayılan dokunma hareketini önleyebilir.
hallodom

63
Bu çözüm işe yarar, ancak sayfanın üst kısmına geri gitmenin (potansiyel olarak) istenmeyen bir etkisi vardır.
Matt

3
$('body,html')
Seçicim

22
Bu çözüm işe yarıyor ancak kaydırma çubuğu kayboluyor ve bu sınıfı gövdeye uyguladığınızda (pencere os altında) bir `` çarpma '' efekti oluşturuyor (örneğin)
Georgio

57

İşte bunu yapmanın gerçekten temel bir yolu:

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

IE6'da biraz ürkek.


14
Gerçekten bir devre dışı bırakma değil, kaydırma denendiğinde varsayılan olarak bir çırpıdakine benzer.
Marcus Whybrow

11
@Marcus İptal edilemeyen bir olayla alacağı kadar iyi.
sdleihssirhc

3
Gerçekte devre dışı bırakmasa da, simüle eder ve bu benim için yeterince iyi.
Chris Bier

11
IMHO - en iyi cevap burada. Ayrıca, kilitlemek zorunda değilsiniz (0, 0), sadece geçerli kaydırma konumunu kullanın.
YemSalat

4
Ama nasıl yeniden etkinleştirebiliriz?
Sibernetik

41

Aşağıdaki çözüm temel ancak saf JavaScript'tir (jQuery yok):

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

function enableScrolling(){
    window.onscroll=function(){};
}

3
Safari 7.1 ve IE 11'de jumpy. Yeni Chrome, Firefox, Opera tamam.
Timo Kähkönen

En yeni Chrome'da hala küçük bir
gerginlik

İyi çalışıyor, Safari'de, kromda, ancak IE'de
titriyor

Bu çözüm bazı tarayıcılar için işe
yaramıyorsa

Başka bir cevapta belirtildiği gibi, scroll-behavior: smoothbunu alır. Ayrıca, Oto'ya tarayıcının hatası olduğunu söyleyerek katılmıyorum. Temelde gerçekte asenkron olduğunda bir şeyin anında gerçekleşeceğini varsayıyorsunuz
Matt Fletcher

25

Bu çözüm, kullanıcıyı devre dışı bırakarak, kullanıcının üste geri atlamasından farklı olarak, mevcut kaydırma konumunu koruyacaktır.

Galambalazs'ın cevabına dayanıyor , ancak dokunmatik cihazlar için destekle ve jquery eklenti sarıcısı ile tek bir nesne olarak yeniden düzenlendi.

Burada demo.

Burada github üzerinde.

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

Yararlı olduğuna sevindim. Not jQuery eklenti biçiminde bunun için bir bağlantı ile düzenledim .
Josh Harrison

Kaydırma düğmesini devre dışı bırakma gerçekten işe yaradıysa yardımcı olabilir
cameronjonesweb

@ user1672694, burada Chrome'da çalışır. Tarayıcınız nedir ve hangi demo sayfasında hata buldunuz? Konsolda herhangi bir JS hatası var mı?
Josh Harrison

Chrome'da (38, Windows 7), orta düğmeyi basılı tutup sürükleyerek yine de kaydırabilirim.
Sethi

1
Lütfen dikkate almayın, bağlayıcı mousewheelbir cazibe çalıştı bulundu
adamj

17

Eski bir gönderiyi cevapladığım için üzgünüm ama bir çözüm arıyordum ve bu soruya rastladım.

Bu konunun kaydırma çubuğunu görüntülemesine yönelik, konteynere% 100 yükseklik ve overflow-y: scrollstil verme gibi birçok geçici çözüm vardır .

Benim durumumda overflow: hidden, gövdeye eklerken görüntülediğim kaydırma çubuğuna sahip bir div oluşturdum :

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

Öğe kaydırma çubuğunda şu stiller bulunmalıdır:

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

Bu gri bir kaydırma çubuğu gösterir, umarım gelecekteki ziyaretçilere yardımcı olur.


8

Bu soruna bir çözüm arıyordum ama yukarıdaki çözümlerden herhangi birinden memnun kalmadım ( bu cevabı yazarken ), bu yüzden bu çözümü buldum ..

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

Eklediğim bu benim için çalıştı bulundu overflow-y: scrolletmek .scrollDisabledtarzında. Aksi takdirde, kaydırma çubuğu her seferinde saklandığında küçük bir sıçrama oldu. Tabii ki, bu sadece benim için çalışıyor çünkü sayfam en büyük ekranlarda bile bir kaydırma çubuğuna ihtiyaç duyacak kadar uzun.
Andrew Miner,

7

Galambalazlar mesajına göre, dokunmamıza izin veren ancak yukarı veya aşağı kaydırma yapmamıza izin veren dokunmatik cihazlar için destek ekleyeceğim:

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

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}

3
Bunun yalnızca diğer cevabın bir yorumu değil, bir cevap olduğuna emin misiniz?
IvanH

6

Chrome 56 ve diğer modern tarayıcılardan itibaren, iş yapmak passive:falseiçin addEventListenerçağrıyı eklemelisiniz preventDefault. Mobilde kaydırmayı durdurmak için bunu kullanıyorum:

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

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

5

Hayır, olay işleme ile gitmek olmaz çünkü:

  • tüm olayların vücuda ulaşması garanti edilmez,

  • metin seçmek ve aşağı doğru hareket etmek aslında belgeyi kaydırır,

  • olay ayrılma aşamasında sth yanlış giderse mahkumdur.

Bunu gizli bir textarea ile kopyala yapıştır eylemi yaparak ısırdım ve tahmin edin, kopya yaptığımda sayfa kaydırıyor çünkü arama yapmadan önce textarea'yı seçmek zorundayım document.execCommand('copy') .

Her neyse, bu şekilde gidiyorum, dikkat edin setTimeout():

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

Kaydırma çubukları geçici olarak kaybolurken bir momentum yanıp sönüyor, ancak kabul edilebilir bir şey.


4

Kaldırılan kaydırmayla ne elde etmek istediğinize bağlı olarak, kaydırmayı kaldırmak istediğiniz öğeyi (tıklama sırasında veya kaydırmayı geçici olarak devre dışı bırakmak istediğiniz diğer tetikleyiciler) düzeltebilirsiniz.

Bir "temp no scroll" çözümü arıyordum ve ihtiyaçlarım için bu çözüldü

sınıf yap

.fixed{
    position: fixed;
}

sonra Jquery ile

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

Bunun tüm tarayıcılarda iyi çalışan ve aynı zamanda taşınabilir cihazlarda (yani iPhone'lar, tabletler vb.) Basit kullanım için yeterince basit bir çözüm olduğunu buldum. Öğe geçici olarak sabitlendiğinden kaydırma yok :)

NOT! "ContentContainer" öğenizin yerleşimine bağlı olarak, öğeyi soldan ayarlamanız gerekebilir. Sabit sınıf aktifken o öğeye bir css sol değeri ekleyerek kolayca yapılabilir

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

4

Başka bir çözüm:

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

Bu şekilde her zaman dikey bir kaydırma çubuğunuz olur, ancak içeriğimin çoğu görünüm penceresinden daha uzun olduğu için bu benim için uygun. İçerik ayrı bir div ile ortalanır, ancak tekrar vücutta marj koymadan içeriğim solda kalır.

Bunlar açılır penceremi / modumu göstermek için kullandığım iki işlev:

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

Sonuç: kaydırılamayan arka plan ve sol kaydırma çubuğu nedeniyle içeriğin yeniden konumlandırılması yok. Mevcut FF, Chrome ve IE 10 ile test edilmiştir.


Bu benim için çalıştı ve pozisyonu kullandıktan sonra yukarı kaydırma sorunu: sabit. Teşekkür ederim!
Annia Martinez

3

Buna ne dersin? (JQuery kullanıyorsanız)

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

biraz gergin, ama bu IE 7 için çalışır (istemci kullanır). diğer çözümler yoktur.
niki b

3

Kalıcı iletişim kutusu olarak ikincil sayfa göstermek için showModalDialog kullanıyorum .

ana pencere kaydırma çubuklarını gizlemek için:

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

ve kalıcı iletişim kutusunu kapatırken, ana pencere kaydırma çubuklarını gösterir:

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

ana penceredeki öğelere iletişim kutusundan erişmek için:

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

showModalDialog hakkında arama yapan herkes için : (orijinal kodun 29. satırından sonra)

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

Bu, jQuery'nin bulunmadığı ve React'ın vücut etiketinin durumunu yönetme erişiminin olmadığı React'te benim için çalıştı.
Jon

3

Etkinliğin kabul edilen cevaptaki gibi iptal edilmesi bence korkunç bir yöntem: /

Bunun yerine position: fixed; top: -scrollTop();aşağıda kullandım .

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

JQuery popup projemden: 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": ""});
    }
}

Bu kod, genişlik, yükseklik, kaydırma çubuğu ve sayfa atlama sorunlarını dikkate alır.

Yukarıdaki kodla ilgili olası sorunlar:

  • genişlik, konum ayarı sabitlendiğinde html öğesi genişliği% 100'den küçük olabilir
  • yükseklik, yukarıdaki ile aynı
  • konumu sabit olarak ayarlandığında, sayfa içeriğinin yatay bir sayfa sıçramasıyla sonuçlanmadan önce kaydırma çubuğu olsa bile artık kaydırma çubuğu yoktur
  • pagejump, konum ayarı düzeltildiğinde sayfa scrollTop artık etkili değil, dikey bir sayfa atlama

Herkes yukarıdaki sayfa donma / çözme kodunda herhangi bir iyileştirme varsa, bana bu iyileştirmeleri projeme ekleyebilirsiniz böylece bana bildirin.


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

1
Buradaki en iyi çözüm bu.
jfunk

@jfunk katılıyorum, basit ve özlü, küçük kod, mükemmel. Teşekkür ederim
Florent Roques

2

Aynı problemim var, aşağıda ele alma şeklim.

/* 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;
}

umarım bu yardım.


1

Cheyenne Forbes'ın cevabı ve burada fcalderan aracılığıyla bulduğum bir cevap üzerine inşa etmek: Kaydırmayı devre dışı bırakmak değil mi? ve Hallodom'un kaydırma çubuğundaki kaybolması sorununu düzeltmek için

CSS:

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

JS:

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

Bu kod sizi sayfanın üstüne atlar, ancak fcalderan'ın kodunun bir çözümü olduğunu düşünüyorum.


1

Bunun eski bir soru olduğunu biliyorum, ama çok benzer bir şey yapmak zorunda kaldım ve bir süre sonra bir cevap aramaya ve farklı yaklaşımları denemeye başladıktan sonra çok kolay bir çözüm kullandım.

Benim sorunum çok benzerdi, neredeyse aynı, tek fark aslında kaydırma çubuğunu göstermek zorunda kalmadım - sadece genişliğinin hala kullanıldığından emin olmak zorunda kaldım, bu yüzden bindirmem görüntülenirken sayfanın genişliği değişmeyecekti .

Yer paylaşımımı ekrana kaydırmaya başladığımda şunu yaparım:

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

ve yer paylaşımımı ekranın dışına kaydırdıktan sonra şunları yaparım:

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

ÖNEMLİ: my bindirme konumlandırılmış çünkü bu mükemmel çalışıyor absolute, right: 0pxzaman visible.


1

En basit yöntem:

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

Geri almak için:

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

Uygulaması kolaydır, ancak tek dezavantajı:

  • Sayfa merkeze hizalanmışsa (yatay olarak) biraz sola atlar.

Bu, kaydırma çubuğunun kaldırılmasından ve görünümün biraz daha genişlemesinden kaynaklanmaktadır.


1
konumunu sıfırlar
Angel David Calderaro Pacciott

@AngelDavidCalderaroPacciott Hayır, kaydırma konumu aynı yükseklik / mesafe olarak kalacaktır.
Daan

@Daan, Chrome'daki kaydırma konumunu sıfırlıyor
Tom

@Tom sadece kontrol ettim, sadece bazı durumlarda yapıyor (vücut yüksekliği çocuklarına göreceli olmadığında). Değiştirmeyi deneyin bodyiçin htmlyerine.
Daan

Bahse girerim overflow:hidden,
Iphone'daki

1

İşte kaydırma durdurmak için benim çözüm (jQuery yok). Yan menü göründüğünde kaydırmayı devre dışı bırakmak için kullanıyorum.

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

Kaydırma çubuğunun kaybolmasını telafi etmek için 17 piksel dolgu hakkı koydum. Ancak bu, çoğunlukla mobil tarayıcılar için de sorunludur. Uygun genişlik çubuğu alarak çözüldü bu .

Hep birlikte bu Kalemde.



1

Bu şimdiye kadar aldığım en basit çözüm. Ve inan bana diğerlerini denedim ve bu en kolayı. Sistem kaydırma çubuğuna ve tarayıcılardaki kaydırma çubukları için yer gerektirmeyen IOS cihazlarına yer açmak için sayfayı sağdan iten Windows cihazlarında harika çalışır . Yani bunu kullanarak sağda dolgu eklemeniz gerekmeyecek, böylece css ile gövdenin veya html'nin taşmasını gizlediğinizde sayfa titremiyor .

Bunu düşünürseniz çözüm oldukça basittir. Fikir, bir açılır pencere açıldığı anda window.scrollTop () işlevine aynı konumu vermektir . Ayrıca pencere yeniden boyutlandırıldığında bu konumu değiştirin (kaydırma konumu gerçekleştikçe değişir).

İşte başlıyoruz ...

İlk olarak, açılır pencerenin açık olduğunu bildiren değişkeni oluşturmanıza ve onu stopWindowScroll olarak adlandırmanıza izin verir . Bunu yapmazsak, sayfanızda tanımlanmamış bir değişkente hata alırsınız ve bunu 0 - etkin değil olarak ayarlarsınız.

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

Şimdi açık açılır pencere işlevinin, kodunuzda eklenti veya özel olarak kullandığınız açılır pencereyi tetikleyen herhangi bir işlev olmasını sağlayalım. Bu durumda, tıklama işlevi ile ilgili basit bir belge ile basit bir özel açılır pencere olacaktır.

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

Böylece yaptığımız bir sonraki şey, tekrar tekrar yaptığım yakın pop-up işlevini oluşturmak, zaten oluşturduğunuz veya bir eklentide kullandığınız herhangi bir işlev olabilir. Önemli olan, stopWindowScroll değişkenini ne zaman açık veya kapalı olduğunu bilmek için bu 2 işleve ihtiyaç duymamızdır .

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

Daha sonra window.scroll işlevini oluşturalım, böylece yukarıda belirtilen stopWindowScroll öğesi 1 - etkin olarak ayarlandığında kaydırmayı önleyebiliriz .

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

Bu kadar. Bunun çalışması için sayfa için kendi stilleriniz dışında hiçbir CSS gerekmez. Bu benim için bir cazibe gibi çalıştı ve umarım size ve başkalarına yardımcı olur.

İşte JSFiddle'da çalışan bir örnek:

JS Fiddle Örneği

Bunun yardımcı olup olmadığını bana bildirin. Saygılarımızla.


1

Kaydırma uzunluğunu global bir değişkende saklayın ve gerektiğinde geri yükleyin!

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

1

Bu kod Chrome 56'da çalışacaktır ve sonraki (orijinal yanıt artık Chrome'da çalışmaz).

kullanım DomUtils.enableScroll()Kaydırmayı etkinleştirmek için .

DomUtils.disableScroll()Kaydırmayı devre dışı bırakmak için kullanın .

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

1

Atlamayı önlemek için kullandığım şey bu

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

ve benim css

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

0

Bu yanıtı başka bir sitede buldum :

Kaydırmayı devre dışı bırak:

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

Açılır pencereyi kapattıktan sonra kaydırma:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});

Bu sadece dokunmatik kaydırmayı durduruyor gibi görünüyor, ancak fare kaydırma, ok tuşları, sayfa yukarı ve aşağı tuşları, vb. -1
markasoftware

Bu 'etkinlikler' dokunmatik kaydırma içindir, sadece ihtiyacınız olan olayların yerine kullanılabilir.
pennstump

1
ayrıca, bu çok spesifik başka bir durumda da kullanılıyor gibi görünmektedir. popupbeforeposition? Bunun ne için olması gerekiyordu? Bunun kaydırmayı geçici olarak devre dışı bırakmakla ne ilgisi var? En azından bu durumla alakalı olmasını sağlayın. Bunu doğrudan bir web sitesinden kopyalamışsınız gibi görünüyor.
markasoftware

0

galambalazs'ın çözümü harika! Chrome ve Firefox'ta benim için mükemmel çalıştı. Ayrıca tarayıcı penceresinden herhangi bir varsayılan olayı önlemek için genişletilebilir. Tuvalde bir uygulama yaptığınızı varsayalım. Bunu yapabilirsin:

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

Ve sonra uygulamanızda diyelim ki fare, klavye, dokunma olayları vb.Gibi kendi olaylarınızı işleyeceksiniz ... Fare tuvalin içine girdiğinde varsayılan olayları devre dışı bırakabilir ve fare söner:

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

Bu saldırı ile sağ tıklama menüsünü bile devre dışı bırakabilirsiniz:

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

0

Mobil ekranda benzer bir animasyon problemim vardı, ancak jquery'nin animate komutunu kullanarak bir div canlandırmaya çalışırken dizüstü bilgisayarlarda değil. Bu yüzden pencerenin kaydırma konumunu o kadar sık ​​geri yükleyen bir zamanlayıcı kullanmaya karar verdim ki çıplak gözle belge durağan görünecek. Bu çözüm, Samsung Galaxy-2 veya iphone-5 gibi küçük ekranlı bir mobil cihazda mükemmel çalıştı.

Bu yaklaşımın Ana Mantığı : Pencerenin kaydırma konumunu orijinal kaydırma konumuna ayarlamak için zamanlayıcı, jquery animate komutundan önce başlatılmalıdır ve ardından animasyon tamamlandığında bu zamanlayıcıyı temizlememiz gerekir ( original scroll positionanimasyon başlamadan hemen önceki konumdur).

Zamanlayıcı aralığı olsaydı, belgenin animasyon süresi boyunca aslında statik olarak göründüğünü hoş bir sürpriz buldum1 millisecond .

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

Çalıştı BAŞKA ÇÖZÜM : / devre dışı kaydırmayı etkinleştirmek için bu yazı altında Mohammad Anini tarafından cevap dayanarak, ben de kodun değiştirilmiş versiyonu aşağıda çalıştı bulundu.

//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() {};
});

0

Benim için çalışan basit bir çözüm (pencere kaydırmayı geçici olarak devre dışı bırakma).

Bu kemandan yola çıkarak: http://jsfiddle.net/dh834zgw/1/

aşağıdaki snippet (jquery kullanarak) pencere kaydırmasını devre dışı bırakır:

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

Ve css'inizde:

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

Modal'ı kaldırdığınızda, html etiketindeki noscroll sınıfını kaldırmayı unutmayın:

$('html').toggleClass('noscroll');
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.