it-swarm.com.de

Verhindern Sie das Scrollen von KÖRPER, wenn ein Modal geöffnet ist

Ich möchte, dass mein Körper das Scrollen stoppt, wenn das Mausrad verwendet wird, während das Modal (von http://Twitter.github.com/bootstrap ) auf meiner Website geöffnet ist.

Ich habe versucht, das Javascript unten aufzurufen, wenn der Modal geöffnet ist, aber ohne Erfolg

$(window).scroll(function() { return false; });

AND

$(window).live('scroll', function() { return false; });

Bitte beachten Sie, dass unsere Website die Unterstützung für IE6 eingestellt hat, IE7 + muss jedoch kompatibel sein.

292
xorinzor

modal von Bootstrap fügt automatisch die Klasse modal-open zum Rumpf hinzu, wenn ein modales Dialogfeld angezeigt wird, und entfernt es, wenn das Dialogfeld ausgeblendet ist. Sie können Ihrem CSS daher Folgendes hinzufügen:

body.modal-open {
    overflow: hidden;
}

Sie könnten argumentieren, dass der obige Code zur Bootstrap-CSS-Codebasis gehört, aber dies ist eine einfache Lösung, um ihn Ihrer Website hinzuzufügen.

Update 8. Februar 2013
Dies funktioniert jetzt in Twitter Boostrap v. 2.3.0 nicht mehr - sie fügen die Klasse modal-open nicht mehr zum body hinzu.

Eine Problemumgehung wäre, die Klasse dem Body hinzuzufügen, wenn das Modal angezeigt wird, und es zu entfernen, wenn das Modal geschlossen ist:

$("#myModal").on("show", function () {
  $("body").addClass("modal-open");
}).on("hidden", function () {
  $("body").removeClass("modal-open")
});

Update 11. März 2013 Sieht aus, als würde die modal-open-Klasse in Bootstrap 3.0 explizit zurückgegeben werden, um das Scrollen zu verhindern: 

Wiedereinführung von .modal-open am Körper (damit wir die Schriftrolle dort nuken können)

Siehe hierzu: https://github.com/Twitter/bootstrap/pull/6342 - siehe Abschnitt Modal.

418
MartinHN

Die akzeptierte Antwort funktioniert nicht auf mobilen Geräten (mindestens iOS 7 mit Safari 7), und ich möchte nicht, dass MOAR JavaScript auf meiner Website ausgeführt wird, wenn CSS dies tut.

Dieses CSS verhindert, dass die Hintergrundseite unter dem Modal-Bildlauf angezeigt wird:

body.modal-open {
    overflow: hidden;
    position: fixed;
}

Es hat jedoch auch einen leichten Nebeneffekt, wenn man im Wesentlichen nach oben scrollen soll. position:absolute löst dieses Problem auf, führt jedoch erneut die Möglichkeit ein, auf dem mobilen Gerät einen Bildlauf durchzuführen.

Wenn Sie Ihren Viewport kennen ( mein Plugin zum Hinzufügen von Viewport zum <body> ), können Sie einfach einen CSS-Schalter für die position hinzufügen.

body.modal-open {
    // block scroll for mobile;
    // causes underlying page to jump to top;
    // prevents scrolling on all screens
    overflow: hidden;
    position: fixed;
}
body.viewport-lg {
    // block scroll for desktop;
    // will not jump to top;
    // will not prevent scroll on mobile
    position: absolute; 
}

Ich füge dies auch hinzu, um zu verhindern, dass die zugrunde liegende Seite beim Anzeigen/Ausblenden von Modalen nach links/rechts springt.

body {
    // STOP MOVING AROUND!
    overflow-x: hidden;
    overflow-y: scroll !important;
}

diese Antwort ist ein X-Post.

103
Brad

Blenden Sie einfach den Körperüberlauf aus und der Körper wird nicht gerollt. Wenn Sie den Modal ausblenden, setzen Sie ihn auf Automatisch zurück. 

Hier ist der Code:

$('#adminModal').modal().on('shown', function(){
    $('body').css('overflow', 'hidden');
}).on('hidden', function(){
    $('body').css('overflow', 'auto');
})
26

Sie können versuchen, die Körpergröße mit Überlauf auf die Fenstergröße einzustellen: ausgeblendet, wenn Modal geöffnet ist

20
charlietfl

Warning: Die unten stehende Option ist für Bootstrap v3.0.x nicht relevant, da das Scrollen in diesen Versionen explizit auf den Modal selbst beschränkt ist. Wenn Sie Wheel-Events deaktivieren, können Sie versehentlich einige Benutzer daran hindern, anzuzeigen der Inhalt in Modalen, deren Höhe größer als die Höhe des Ansichtsfensters ist.


Noch eine weitere Option: Wheel Events

Das scroll -Ereignis kann nicht abgebrochen werden. Es ist jedoch möglich, die Ereignisse mousewheel und wheel zu löschen. Der große Nachteil ist, dass sie nicht von allen älteren Browsern unterstützt werden. Mozilla fügt letzteres erst kürzlich in Gecko 17.0 hinzu. Ich kenne nicht die gesamte Verbreitung, aber IE6 + und Chrome unterstützen sie.

So können Sie sie nutzen:

$('#myModal')
  .on('shown', function () {
    $('body').on('wheel.modal mousewheel.modal', function () {
      return false;
    });
  })
  .on('hidden', function () {
    $('body').off('wheel.modal mousewheel.modal');
  });

JSFiddle

17
merv

Sie müssen über die Antwort und das Konto von @ charlietfl für Bildlaufleisten hinausgehen, andernfalls wird möglicherweise ein Reflow des Dokuments angezeigt.

Modal öffnen:

  1. Notieren Sie die body Breite
  2. body overflow auf hidden setzen
  3. Stellen Sie die Körperbreite explizit so ein, wie sie in Schritt 1 war.

    var $body = $(document.body);
    var oldWidth = $body.innerWidth();
    $body.css("overflow", "hidden");
    $body.width(oldWidth);
    

Modal schließen:

  1. body overflow auf auto setzen
  2. Setze body width auf auto

    var $body = $(document.body);
    $body.css("overflow", "auto");
    $body.width("auto");
    

Inspiriert von: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php

14
jpap

Probier diese:

.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
    height: 100%;
}

es hat für mich funktioniert. (unterstützt IE8)

9
fatCop
/* =============================
 * Disable / Enable Page Scroll
 * when Bootstrap Modals are
 * shown / hidden
 * ============================= */

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

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

function disable_scroll() {
  if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', theMouseWheel, false);
  }
  window.onmousewheel = document.onmousewheel = theMouseWheel;
}

function enable_scroll() {
    if (window.removeEventListener) {
        window.removeEventListener('DOMMouseScroll', theMouseWheel, false);
    }
    window.onmousewheel = document.onmousewheel = null;  
}

$(function () {
  // disable page scrolling when modal is shown
  $(".modal").on('show', function () { disable_scroll(); });
  // enable page scrolling when modal is hidden
  $(".modal").on('hide', function () { enable_scroll(); });
});
8
jparkerweb

In Chrome konnte es nicht einfach durch CSS-Änderungen funktionieren, da die Seite nicht nach oben scrollen sollte. Das hat gut funktioniert:

$("#myModal").on("show.bs.modal", function () {
  var top = $("body").scrollTop(); $("body").css('position','fixed').css('overflow','hidden').css('top',-top).css('width','100%').css('height',top+5000);
}).on("hide.bs.modal", function () {
  var top = $("body").position().top; $("body").css('position','relative').css('overflow','auto').css('top',0).scrollTop(-top);
});
7
tetsuo

Ich bin nicht sicher über diesen Code, aber es ist einen Versuch wert.

In jQuery:

$(document).ready(function() {
    $(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
        $("#Modal").css("overflow", "hidden");
    });
});

Wie gesagt, ich bin nicht 100% ig sicher, aber versuche es trotzdem.

6
Anish Gupta

Das Hinzufügen der Klasse "is-modal-open" oder das Ändern des Stiles des Body-Tags mit Javascript ist in Ordnung und wird wie erwartet funktionieren. Aber das Problem, mit dem wir konfrontiert werden, ist, wenn der Körper überläuft: Versteckt springt er nach oben (scrollTop wird zu 0). Dies wird später zu einem Usability-Problem. 

Als Lösung für dieses Problem sollten Sie den Body-Tag-Überlauf nicht ändern: Versteckte Änderung am HTML-Tag

$('#myModal').on('shown.bs.modal', function () {
  $('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
  $('html').css('overflow','auto');
});

Für Bootstrap versuchen Sie dies (mit Firefox, Chrome und Microsoft Edge):

body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}

Hoffe das hilft...

3
Murat Yıldız

Die beste Lösung ist die css-only-body{overflow:hidden}-Lösung, die von den meisten dieser Antworten verwendet wird. Einige Antworten enthalten ein Update, das auch den durch die verschwindende Bildlaufleiste verursachten "Sprung" verhindert. Keiner war jedoch zu elegant. Also habe ich diese beiden Funktionen geschrieben und sie scheinen ziemlich gut zu funktionieren.

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

function bodyFreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('overflow', 'hidden');
    $body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}

function bodyUnfreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
    $body.css('overflow', 'auto');
}

Check out this jsFiddle um es in Benutzung zu sehen.

3

Du könntest die folgende Logik verwenden, ich habe es getestet und es funktioniert (sogar im IE) 

   <html>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">

var currentScroll=0;
function lockscroll(){
    $(window).scrollTop(currentScroll);
}


$(function(){

        $('#locker').click(function(){
            currentScroll=$(window).scrollTop();
            $(window).bind('scroll',lockscroll);

        })  


        $('#unlocker').click(function(){
            currentScroll=$(window).scrollTop();
            $(window).unbind('scroll');

        })
})

</script>

<div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="locker">lock</button>
<button id="unlocker">unlock</button>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

</div>
3
myriacl

Ich hatte eine Seitenleiste, die durch das Kontrollkästchen Hack .. erstellt wurde. Die Hauptidee ist jedoch, das Dokument scrollTop zu speichern und nicht während des Bildlaufs des Fensters zu ändern.

Ich mochte das Springen der Seite einfach nicht, wenn der Körper zu "Überlauf: Versteckt" wird.

window.addEventListener('load', function() {
    let prevScrollTop = 0;
    let isSidebarVisible = false;

    document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
        
        prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
        isSidebarVisible = event.target.checked;

        window.addEventListener('scroll', (event) => {
            if (isSidebarVisible) {
                window.scrollTo(0, prevScrollTop);
            }
        });
    })

});

Leider hat keine der obigen Antworten meine Probleme behoben.

In meiner Situation hat die Webseite ursprünglich eine Bildlaufleiste. Immer wenn ich auf das Modal klicke, verschwindet die Bildlaufleiste nicht und die Kopfzeile wird nach rechts verschoben.

Dann habe ich versucht, .modal-open{overflow:auto;} hinzuzufügen (was die meisten Leute empfahlen). Das Problem wurde in der Tat behoben: Die Bildlaufleiste erscheint, nachdem ich den Modal geöffnet habe. Es kommt jedoch ein weiterer Nebeneffekt hinzu, der besagt, dass "der Hintergrund unterhalb der Kopfzeile zusammen mit einem weiteren langen Balken hinter dem Modal ein wenig nach links verschoben wird."

 Long bar behind modal

Glücklicherweise ist nach dem Hinzufügen von {padding-right: 0 !important;} alles perfekt fixiert. Sowohl der Kopf- als auch der Körperhintergrund haben sich nicht bewegt und der Modal-Modus behält die Bildlaufleiste bei.

 Fixed image

Ich hoffe, dass dies denjenigen helfen kann, die immer noch an diesem Problem festhalten. Viel Glück!

2
Bocard Wang

Stand: November 2017 Chrome Einführung einer neuen CSS-Eigenschaft

overscroll-behavior: contain;

dies löst dieses Problem, obwohl die Unterstützung für Browserübergreifend eingeschränkt ist.

siehe unten stehende Links für vollständige Details und Browser-Unterstützung 

2
user1095118

Viele schlagen "overflow: hidden" auf dem Körper vor, was nicht funktioniert (zumindest nicht in meinem Fall), da die Website nach oben scrollen wird.

Dies ist die Lösung, die für mich (sowohl auf Mobiltelefonen als auch auf Computern) mit jQuery funktioniert:

    $('.yourModalDiv').bind('mouseenter touchstart', function(e) {
        var current = $(window).scrollTop();
        $(window).scroll(function(event) {
            $(window).scrollTop(current);
        });
    });
    $('.yourModalDiv').bind('mouseleave touchend', function(e) {
        $(window).off('scroll');
    });

Dadurch wird das Scrollen des Modals aktiviert, und die Website kann nicht gleichzeitig scrollen.

2
Danie

Basierend auf dieser Geige: http://jsfiddle.net/dh834zgw/1/

das folgende Snippet (mit Jquery) deaktiviert den Bildlauf des Fensters:

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

Und in deinem CSS:

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

Wenn Sie nun den Modal entfernen, vergessen Sie nicht, die Noscroll-Klasse aus dem HTML-Tag zu entfernen:

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

Wenn der Modalwert 100% Höhe/Breite beträgt, wird durch "Mouseenter/Leave" das Scrollen einfach aktiviert/deaktiviert. Das hat wirklich für mich geklappt:

var currentScroll=0;
function lockscroll(){
    $(window).scrollTop(currentScroll);
} 
$("#myModal").mouseenter(function(){
    currentScroll=$(window).scrollTop();
    $(window).bind('scroll',lockscroll); 
}).mouseleave(function(){
    currentScroll=$(window).scrollTop();
    $(window).unbind('scroll',lockscroll); 
});
1
Mats

Meine Lösung für Bootstrap 3:

.modal {
  overflow-y: hidden;
}
body.modal-open {
  margin-right: 0;
}

weil für mich der einzige overflow: hidden in der body.modal-open-Klasse nicht verhindert hat, dass die Seite aufgrund des ursprünglichen margin-right: 15px nach links verschoben wird.

1
pierrea

Die meisten Stücke sind hier, aber ich sehe keine Antwort, die alles zusammenbringt.

Das Problem ist dreifach.

(1) Verhindern Sie das Blättern der zugrunde liegenden Seite

$('body').css('overflow', 'hidden')

(2) und entfernen Sie die Bildlaufleiste

var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)

(3) aufräumen, wenn der modal abgewiesen wird

$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')

Wenn das Modal nicht im Vollbildmodus ist, wenden Sie die Modal-Bindungen auf ein Vollbild-Overlay an.

1
evoskuil

Ich bin nicht zu 100% sicher, dass dies mit Bootstrap funktioniert, aber einen Versuch wert - es hat mit Remodal.js funktioniert, das auf github zu finden ist: http://vodkabears.github.io/remodal/ und würde es machen Sinn für die Methoden, um ziemlich ähnlich zu sein.

Um zu verhindern, dass die Seite nach oben springt, und um zu verhindern, dass der Inhalt nach rechts verschoben wird, fügen Sie der body eine Klasse hinzu, wenn das Modal ausgelöst wird, und legen Sie die folgenden CSS-Regeln fest:

body.with-modal {
    position: static;
    height: auto;
    overflow-y: hidden;
}

Es sind der position:static und der height:auto, die das Springen des Inhalts nach rechts stoppen. Der overflow-y:hidden; verhindert, dass die Seite hinter dem Modal scrollbar ist.

1
AdamJB

Ich habe es einfach so gemacht ...

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

Aber als der Scroller verschwand, bewegte er alles richtig um 20 Punkte, fügte ich hinzu 

$('body').css('margin-right', '20px');

direkt danach.

Funktioniert bei mir.

1
Cliff

arbeitete für mich

$('#myModal').on({'mousewheel': function(e) 
    {
    if (e.target.id == 'el') return;
    e.preventDefault();
    e.stopPropagation();
   }
});
1
namal

Das Ausblenden des Überlaufs und das Festlegen der Position bewirkt den Trick. Bei meinem fließenden Design würde dies jedoch die Breite des Browsers übersteigen.

body.modal-open{overflow:hidden;position:fixed;width:100%}
0
asked_io

Ich verwende diese Vanilla js-Funktion, um dem Körper die Klasse "modal-open" hinzuzufügen. (Basierend auf smhmics Antwort)

function freezeScroll(show, new_width)
{
    var innerWidth = window.innerWidth,
        clientWidth = document.documentElement.clientWidth,
        new_margin = ((show) ? (new_width + innerWidth - clientWidth) : new_width) + "px";

    document.body.style.marginRight = new_margin;
    document.body.className = (show) ? "modal-open" : "";
};
0
Omer M.

Dies ist die beste Lösung für mich: 

Css:

.modal {
     overflow-y: auto !important;
}

Und Js:

modalShown = function () {
    $('body').css('overflow', 'hidden');
},

modalHidden = function () {
    $('body').css('overflow', 'auto');
}
0
ibrahimyilmaz

Benutze body-scroll-lock

Sehr leicht, sehr ordentlich und beliebt

0
adardesign

Versuchen Sie diesen Code:

$('.entry_details').dialog({
    width:800,
    height:500,
    draggable: true,
    title: entry.short_description,
    closeText: "Zamknij",
    open: function(){
        //    blokowanie scrolla dla body
        var body_scroll = $(window).scrollTop();
        $(window).on('scroll', function(){
            $(document).scrollTop(body_scroll);
        });
    },
    close: function(){
        $(window).off('scroll');
    }
}); 
0
   $('.modal').on('shown.bs.modal', function (e) {
      $('body').css('overflow-y', 'hidden');
   });
   $('.modal').on('hidden.bs.modal', function (e) {
      $('body').css('overflow-y', '');
   });
0

Eine kleine Anmerkung für diejenigen in SharePoint 2013. Der Körper hat bereits overflow: hidden. Sie suchen nach overflow: hidden für das div-Element mit der ID s4-workspace, z.

var body = document.getElementById('s4-workspace');
body.className = body.className+" modal-open";
0
Kristian

Das Obige tritt auf, wenn Sie ein Modal in einem anderen Modal verwenden. Wenn ich ein Modal in einem anderen Modal öffne, wird beim Schließen des Modals die Klasse modal-open aus der body entfernt. Die Behebung des Problems hängt davon ab, wie Sie das letztere Modal schließen.

Wenn Sie das Modal mit HTML schließen,

<button type="button" class="btn" data-dismiss="modal">Close</button>

Dann müssen Sie einen solchen Hörer hinzufügen,

$(modalSelector).on("hidden.bs.modal", function (event) {
    event.stopPropagation();
    $("body").addClass("modal-open");
    return false;
});

Wenn Sie den Modal mit Javascript schließen,

$(modalSelector).modal("hide");

Dann müssen Sie den Befehl einige Zeit danach ausführen,

setInterval(function(){$("body").addClass("modal-open");}, 300);
0

Für diejenigen, die sich fragen, wie sie das Scroll-Ereignis für das Bootstrap 3-Modal erhalten können:

$(".modal").scroll(function() {
    console.log("scrolling!);
});
0
Arie

Was dies für mich endgültig behoben hat, war Body Scroll Lock .

Andere Lösungen deaktivieren das Scrollen unter iOS nicht.

0

Das hat für mich funktioniert:

$("#mymodal").mouseenter(function(){
   $("body").css("overflow", "hidden"); 
}).mouseleave(function(){
   $("body").css("overflow", "visible");
});
0

Sie sollten in HTML overflow: hidden hinzufügen, um eine bessere plattformübergreifende Leistung zu erzielen.

Ich würde ... benutzen

html.no-scroll {
    overflow: hidden;
}
0
Afonso

Da dieses Problem für mich hauptsächlich unter iOS auftrat, biete ich den Code an, um es nur unter iOS zu beheben:

  if(!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) {
    var $modalRep    = $('#modal-id'),
        startScrollY = null, 
        moveDiv;  

    $modalRep.on('touchmove', function(ev) {
      ev.preventDefault();
      moveDiv = startScrollY - ev.touches[0].clientY;
      startScrollY = ev.touches[0].clientY;
      var el = $(ev.target).parents('#div-that-scrolls');
      // #div-that-scrolls is a child of #modal-id
      el.scrollTop(el.scrollTop() + moveDiv);
    });

    $modalRep.on('touchstart', function(ev) {
      startScrollY = ev.touches[0].clientY;
    });
  }
0
LowFieldTheory

Warum dies nicht wie Bulma tun? Wenn modal aktiv ist, fügen Sie zu html die Klasse .is-clipped hinzu, die überläuft: hidden! Important;

Edit: Okey, Bulma hat diesen Fehler, also musst du auch andere Dinge hinzufügen

html.is-modal-active {
  overflow: hidden !important;
  position: fixed;
  width: 100%; 
}
0
nrkz