Je veux que mon corps arrête de faire défiler le texte lorsque j'utilise la molette lorsque le modal (de http://Twitter.github.com/bootstrap ) est ouvert.
J'ai essayé d'appeler le morceau de javascript ci-dessous quand le modal est ouvert mais sans succès
$(window).scroll(function() { return false; });
AND
$(window).live('scroll', function() { return false; });
Veuillez noter que notre site Web a cessé de prendre en charge IE6, mais que IE7 + doit être compatible.
La variable modal
de Bootstrap ajoute automatiquement la classe modal-open
au corps lorsqu'une boîte de dialogue modale est affichée et la supprime lorsque la boîte de dialogue est masquée. Vous pouvez donc ajouter ce qui suit à votre CSS:
body.modal-open {
overflow: hidden;
}
Vous pourriez faire valoir que le code ci-dessus appartient à la base de code CSS Bootstrap, mais il s'agit d'une solution facile pour l'ajouter à votre site.
Mise à jour du 8 février 2013
Cela ne fonctionne plus dans Twitter Boostrap v. 2.3.0 - ils n’ajoutent plus la classe modal-open
au corps.
Une solution de contournement consisterait à ajouter la classe au corps lorsque le modal est sur le point d'être affiché et à la supprimer lorsque le modal est fermé:
$("#myModal").on("show", function () {
$("body").addClass("modal-open");
}).on("hidden", function () {
$("body").removeClass("modal-open")
});
Mise à jour du 11 mars 2013 On dirait que la classe modal-open
va revenir dans Bootstrap 3.0, explicitement dans le but d'empêcher le défilement:
Réintroduit .modal-open sur le corps (afin que nous puissions nuancer le parchemin là-bas)
Voir ceci: https://github.com/Twitter/bootstrap/pull/6342 - consultez la section Modal.
La réponse acceptée ne fonctionne pas sur mobile (iOS 7 avec Safari 7, au moins) et je ne veux pas que JavaScript de MOAR s'exécute sur mon site lorsque CSS le fera.
Ce CSS empêchera la page d’arrière-plan de défiler sous le modal:
body.modal-open {
overflow: hidden;
position: fixed;
}
Cependant, il a également un léger effet secondaire de faire défiler essentiellement vers le haut. position:absolute
résout ce problème, mais réintroduit la possibilité de faire défiler sur mobile.
Si vous connaissez votre fenêtre d'affichage ( mon plugin permettant d'ajouter une fenêtre d'affichage à <body>
), vous pouvez simplement ajouter une bascule CSS pour la variable position
.
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;
}
J'ajoute également ceci pour empêcher la page sous-jacente de sauter gauche/droite lors de l'affichage/du masquage des modaux.
body {
// STOP MOVING AROUND!
overflow-x: hidden;
overflow-y: scroll !important;
}
Il suffit de masquer le débordement du corps pour que le corps ne défile pas. Lorsque vous masquez le modal, rétablissez-le en mode automatique.
Voici le code:
$('#adminModal').modal().on('shown', function(){
$('body').css('overflow', 'hidden');
}).on('hidden', function(){
$('body').css('overflow', 'auto');
})
Vous pouvez essayer de définir la taille du corps sur la taille de la fenêtre avec dépassement: masqué lorsque modal est ouvert
Attention: L'option ci-dessous n'est pas pertinente pour Bootstrap v3.0.x car le défilement dans ces versions a été explicitement limité au modal lui-même. Si vous désactivez les événements de roue, vous pouvez empêcher par inadvertance l'affichage de certains utilisateurs. contenu dans les modaux dont les hauteurs sont supérieures à la hauteur de la fenêtre.
L'événement scroll n'est pas annulable. Cependant, il est possible d'annuler les événements mousewheel et wheel . Le gros inconvénient est que tous les navigateurs traditionnels ne les prennent pas en charge, Mozilla n’ayant que récemment ajouté la prise en charge de ce dernier dans Gecko 17.0. Je ne connais pas la diffusion complète, mais IE6 + et Chrome les prennent en charge.
Voici comment les exploiter:
$('#myModal')
.on('shown', function () {
$('body').on('wheel.modal mousewheel.modal', function () {
return false;
});
})
.on('hidden', function () {
$('body').off('wheel.modal mousewheel.modal');
});
Vous devez aller au-delà de la réponse de @ charlietfl et rendre compte des barres de défilement, sinon vous risquez de voir un document redistribuer.
body
body
overflow sur hidden
Définir explicitement la largeur du corps à ce qu’elle était à l’étape 1.
var $body = $(document.body);
var oldWidth = $body.innerWidth();
$body.css("overflow", "hidden");
$body.width(oldWidth);
body
overflow sur auto
Définissez body
width sur auto
var $body = $(document.body);
$body.css("overflow", "auto");
$body.width("auto");
Inspiré par: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
Essaye celui-là:
.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
height: 100%;
}
cela a fonctionné pour moi. (supporte IE8)
/* =============================
* 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(); });
});
Impossible de le faire fonctionner sur Chrome en changeant simplement CSS, car je ne voulais pas que la page revienne au début. Cela a bien fonctionné:
$("#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);
});
Je ne suis pas sûr de ce code, mais ça vaut le coup.
Dans jQuery:
$(document).ready(function() {
$(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
$("#Modal").css("overflow", "hidden");
});
});
Comme je l'ai déjà dit, je ne suis pas sûr à 100% mais essayez quand même.
L'ajout de la classe 'is-modal-open' ou la modification du style d'une balise body avec javascript est correct et fonctionne comme prévu. Mais le problème auquel nous allons faire face est lorsque le corps devient débordé: caché, il sautera au sommet (scrollTop deviendra 0). Cela deviendra un problème d'utilisabilité plus tard.
En guise de solution à ce problème, au lieu de modifier le débordement de balise body: masqué, changez-le en balise HTML.
$('#myModal').on('shown.bs.modal', function () {
$('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
$('html').css('overflow','auto');
});
Pour Bootstrap , vous pouvez essayer ceci (en travaillant sur
Firefox
,Chrome
etMicrosoft Edge
):
body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}
J'espère que cela t'aides...
La meilleure solution est la solution css body{overflow:hidden}
utilisée par la plupart de ces réponses. Certaines réponses offrent une solution qui empêche également le "saut" causé par la barre de défilement qui disparaît; Cependant, aucun n'était trop élégant. J'ai donc écrit ces deux fonctions et elles semblent fonctionner assez bien.
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');
}
Découvrez this jsFiddle pour le voir en cours d’utilisation.
Vous pouvez utiliser la logique suivante, je l'ai testée et cela fonctionne (même dans 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>
J'avais une barre latérale générée par la case à cocher hack . Mais l'idée principale est de sauvegarder le document scrollTop et de ne pas le changer pendant le défilement de la fenêtre.
Je n'ai simplement pas aimé que la page saute quand le corps devient 'débordement: caché'.
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);
}
});
})
});
Malheureusement, aucune des réponses ci-dessus n'a résolu mes problèmes.
Dans ma situation, la page Web a initialement une barre de défilement. Chaque fois que je clique sur le modal, la barre de défilement ne disparaît pas et l'en-tête se déplace légèrement vers la droite.
Ensuite, j'ai essayé d'ajouter .modal-open{overflow:auto;}
(recommandé par la plupart des gens). Il a en effet corrigé les problèmes: la barre de défilement apparaît après l’ouverture du modal. Cependant, un autre effet secondaire apparaît, à savoir que "l'arrière-plan situé sous l'en-tête se déplace légèrement vers la gauche, avec une autre longue barre derrière le modal"
Heureusement, après avoir ajouté {padding-right: 0 !important;}
, tout est parfaitement corrigé. L'en-tête et le fond du corps n'ont pas bougé et le modal conserve toujours la barre de défilement.
J'espère que cela pourra aider ceux qui sont encore aux prises avec ce problème. Bonne chance!
À partir de novembre 2017, Chrome a introduit une nouvelle propriété css
overscroll-behavior: contain;
qui résout ce problème bien que, au moment de l’écriture, ne supporte que plusieurs navigateurs.
voir les liens ci-dessous pour plus de détails et le support du navigateur
Beaucoup suggèrent "débordement: caché" sur le corps, ce qui ne fonctionnera pas (pas du moins dans mon cas), car le site Web défilera jusqu'au sommet.
C'est la solution qui fonctionne pour moi (à la fois sur les téléphones mobiles et les ordinateurs), en utilisant jQuery:
$('.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');
});
Cela fera fonctionner le défilement du modal et empêchera le site Web de défiler en même temps.
D'après ce violon: http://jsfiddle.net/dh834zgw/1/
le fragment de code suivant (utilisant jquery) désactivera le défilement de la fenêtre:
var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');
Et dans votre css:
html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}
Maintenant, lorsque vous supprimez le modal, n'oubliez pas de supprimer la classe noscroll sur la balise html:
$('html').toggleClass('noscroll');
Si modal sont 100% hauteur/largeur, "mouseenter/leave" fonctionnera pour activer/désactiver facilement le défilement Cela a vraiment fonctionné pour moi:
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);
});
Ma solution pour Bootstrap 3:
.modal {
overflow-y: hidden;
}
body.modal-open {
margin-right: 0;
}
car pour moi le seul overflow: hidden
de la classe body.modal-open
n'empêchait pas la page de se déplacer vers la gauche en raison du margin-right: 15px
d'origine.
La plupart des pièces sont ici, mais je ne vois pas de réponse qui rassemble tout.
Le problème est triple.
(1) empêcher le défilement de la page sous-jacente
$('body').css('overflow', 'hidden')
(2) et retirez la barre de défilement
var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)
(3) nettoyer lorsque le modal est licencié
$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')
Si le modal n'est pas en plein écran, appliquez les liaisons .modal à une superposition en plein écran.
Je ne suis pas sûr à 100% que cela fonctionne avec Bootstrap, mais cela vaut la peine d'essayer - cela a fonctionné avec Remodal.js qui peut être trouvé sur github: http://vodkabears.github.io/remodal/ et cela ferait sens pour que les méthodes soient assez similaires.
Pour empêcher la page de sauter en haut et empêcher le décalage correct du contenu, ajoutez une classe à la body
lorsque le modal est déclenché et définissez les règles CSS suivantes:
body.with-modal {
position: static;
height: auto;
overflow-y: hidden;
}
C'est le position:static
et le height:auto
qui se combinent pour empêcher le passage du contenu à droite. Le overflow-y:hidden;
arrête le défilement de la page derrière le modal.
Je viens de le faire de cette façon ...
$('body').css('overflow', 'hidden');
Mais lorsque la roulette disparut, elle déplaça tout droit 20px, alors j’ai ajouté
$('body').css('margin-right', '20px');
juste après.
Travaille pour moi.
a travaillé pour moi
$('#myModal').on({'mousewheel': function(e)
{
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
});
Cacher le débordement et fixer la position fait l'affaire, mais avec ma conception fluide, il serait résolu au-delà de la largeur du navigateur, donc une largeur: 100% corrigée.
body.modal-open{overflow:hidden;position:fixed;width:100%}
J'utilise cette fonction Vanilla js pour ajouter la classe "modal-open" au corps. (Basé sur la réponse de smhmic)
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" : "";
};
C'est la meilleure solution pour moi:
Css:
.modal {
overflow-y: auto !important;
}
Et Js:
modalShown = function () {
$('body').css('overflow', 'hidden');
},
modalHidden = function () {
$('body').css('overflow', 'auto');
}
Utilisez body-scroll-lock
Très léger, très soigné et populaire
Essayez ce 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');
}
});
$('.modal').on('shown.bs.modal', function (e) {
$('body').css('overflow-y', 'hidden');
});
$('.modal').on('hidden.bs.modal', function (e) {
$('body').css('overflow-y', '');
});
Une petite note pour ceux de SharePoint 2013. Le corps a déjà overflow: hidden
. Ce que vous cherchez, c’est de définir overflow: hidden
sur un élément div avec id s4-workspace
, par exemple.
var body = document.getElementById('s4-workspace');
body.className = body.className+" modal-open";
Ce qui précède se produit lorsque vous utilisez un modal dans un autre modal. Lorsque j'ouvre un modal dans un autre modal, la fermeture de ce dernier supprime la classe modal-open
de la body
. La solution du problème dépend de la façon dont vous fermez ce dernier modal.
Si vous fermez le modal avec HTML comme,
<button type="button" class="btn" data-dismiss="modal">Close</button>
Ensuite, vous devez ajouter un auditeur comme celui-ci,
$(modalSelector).on("hidden.bs.modal", function (event) {
event.stopPropagation();
$("body").addClass("modal-open");
return false;
});
Si vous fermez le modal à l'aide de javascript comme,
$(modalSelector).modal("hide");
Ensuite, vous devez exécuter la commande un peu après, comme ceci,
setInterval(function(){$("body").addClass("modal-open");}, 300);
Pour ceux qui se demandent comment obtenir l'événement de défilement pour le modal bootstrap 3:
$(".modal").scroll(function() {
console.log("scrolling!);
});
Ce qui a finalement résolu le problème pour moi, c’est Verrou de défilement du corps .
Les autres solutions ne désactivent pas le défilement sur iOS.
Cela a fonctionné pour moi:
$("#mymodal").mouseenter(function(){
$("body").css("overflow", "hidden");
}).mouseleave(function(){
$("body").css("overflow", "visible");
});
Vous devez ajouter overflow: hidden
en HTML pour une meilleure performance multiplateforme.
J'utiliserais
html.no-scroll {
overflow: hidden;
}
Puisque pour moi ce problème présenté principalement sur iOS, je fournis le code pour résoudre ce problème uniquement sur iOS:
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;
});
}
Pourquoi ne pas le faire comme Bulma le fait? Lorsque modal est actif, ajoutez au code HTML leur classe .is-clipped qui est un débordement: hidden! Important;
Edit: Okey, Bulma a ce bogue, vous devez donc ajouter aussi d'autres choses comme
html.is-modal-active {
overflow: hidden !important;
position: fixed;
width: 100%;
}