388 votes

Empêcher le défilement du BODY lors de l'ouverture d'une modale

Je veux que mon corps arrête de défiler lorsqu'il utilise la molette de la souris alors que la modale (de http://twitter.github.com/bootstrap ) sur mon site web est ouvert.

J'ai essayé d'appeler le morceau de javascript ci-dessous lorsque la modale est ouverte, mais sans succès.

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

ET

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

Veuillez noter que notre site Web n'est plus compatible avec IE6, mais avec IE7+.

507voto

MartinHN Points 8587

Bootstrap modal ajoute automatiquement la classe modal-open au corps lorsqu'une boîte de dialogue modale est affichée et le supprime lorsque la boîte de dialogue est masquée. Vous pouvez donc ajouter ce qui suit à votre CSS :

body.modal-open {
    overflow: hidden;
}

On pourrait arguer que le code ci-dessus appartient à la base de code CSS de Bootstrap, mais il s'agit d'une correction facile pour l'ajouter à votre site.

Mise à jour du 8 février 2013
Cela ne fonctionne plus dans Twitter Bootstrap v. 2.3.0 -- ils n'ajoutent plus l'élément modal-open au corps.

Une solution de contournement consisterait à ajouter la classe au corps lorsque la modale est sur le point d'être affichée, et à la supprimer lorsque la modale est fermée :

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

Mise à jour du 11 mars 2013 On dirait que le modal-open reviendra dans Bootstrap 3.0, explicitement dans le but d'empêcher le défilement :

Réintroduction de .modal-open sur le corps (pour que l'on puisse y supprimer le scroll)

Voir ça : https://github.com/twitter/bootstrap/pull/6342 - regardez le Modal section.

2 votes

Cela ne fonctionne plus dans bootstrap 2.2.2. Espérons que .modal-open revienne dans le futur... github.com/twitter/bootstrap/issues/5719

2 votes

@ppetrid Je ne m'attends pas à ce qu'il revienne. Sur la base de cette écriture : github.com/twitter/bootstrap/wiki/Upcoming-3.0-changes (regardez en bas). Citation : "Plus de défilement intérieur des modales. Au lieu de cela, les modales grandiront pour accueillir leur contenu et la page défilera pour accueillir la modale."

0 votes

@MartinHN oui je sais, aujourd'hui l'équipe bootstrap a fermé le problème github comme 'wontfix'.

132voto

Brad Points 6009

La réponse acceptée ne fonctionne pas sur les mobiles (iOS 7 et Safari 7, au moins) et je ne veux pas faire tourner PLUS de JavaScript sur mon site alors qu'une CSS suffit.

Cette feuille de style en cascade empêchera le défilement de la page d'arrière-plan sous la modale :

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

Cependant, il a aussi un léger effet secondaire qui consiste à faire défiler les pages vers le haut. position:absolute résout ce problème mais réintroduit la possibilité de défilement sur mobile.

Si vous connaissez votre fenêtre d'affichage ( mon plugin pour ajouter le viewport à la <body> ), vous pouvez simplement ajouter une bascule css pour l'option 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 éviter que la page sous-jacente ne saute à gauche/droite lors de l'affichage/masquage des modales.

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

cette réponse est un x-post.

7 votes

Merci ! Les mobiles (au moins le navigateur natif d'iOS et d'Android) me donnaient un mal de tête et ne fonctionnaient pas sans le position: fixed sur le corps.

0 votes

Merci d'avoir également inclus le code permettant d'empêcher la page de sauter à gauche ou à droite lors de l'affichage ou du masquage des fenêtres modales. C'est extrêmement utile et j'ai vérifié que cela corrige un problème que j'avais dans Safari sur un iPhone 5c fonctionnant sous iOS 9.2.1.

8 votes

Pour corriger le défilement vers le haut, vous pouvez enregistrer la position avant d'ajouter la classe, puis, une fois la classe supprimée, faire défiler window.scroll vers la position enregistrée. C'est ainsi que je l'ai résolu moi-même : pastebin.com/Vpsz07zd .

36voto

Il suffit de cacher le débordement du corps pour que celui-ci ne défile pas. Lorsque vous masquez la modale, revenez à l'automatique.

Voici le code :

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

0 votes

Excellent ! Cela m'a aidé. Merci.

20voto

charlietfl Points 41873

Vous pouvez essayer de définir la taille du corps en fonction de la taille de la fenêtre avec overflow : hidden lorsque la modale est ouverte.

12 votes

Cela déplacerait l'écran à chaque fois que la modale est ouverte, ce qui n'est pas pratique. J'ai juste besoin de désactiver le défilement en arrière-plan.

0 votes

Pas sûr que vous puissiez le faire les barres de défilement sont liées au navigateur et vous ne pouvez pas faire grand chose avec elles

0 votes

Vous pouvez définir la modale sur "fixe" pour qu'elle ne bouge pas lors du défilement.

16voto

merv Points 14713

Attention : L'option ci-dessous ne s'applique pas à Bootstrap v3.0.x, car le défilement dans ces versions est explicitement limité à la modale elle-même. Si vous désactivez les événements de roue, vous risquez d'empêcher par inadvertance certains utilisateurs de visualiser le contenu des modales dont la hauteur est supérieure à celle de la fenêtre d'affichage.


Encore une autre option : Les événements de la roue

El défilement L'événement n'est pas annulable. Il est toutefois possible d'annuler l molette de la souris y roue événements. Le gros problème est que les anciens navigateurs ne les prennent pas tous en charge, Mozilla n'ayant que récemment ajouté la prise en charge de ces derniers dans Gecko 17.0. Je ne connais pas toute la gamme, mais IE6+ et Chrome les prennent en charge.

Voici comment en tirer parti :

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

JSFiddle

0 votes

Votre JSFiddle ne fonctionne pas sur Firefox 24, Chrome 24 ni sur IE9.

0 votes

@AxeEffect devrait fonctionner maintenant. Le seul problème était que les références externes à la bibliothèque Bootstrap avaient changé. Merci de m'avoir prévenu.

3 votes

Cela n'empêche pas les dispositifs tactiles de défiler, le overflow:hidden est mieux pour l'instant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X