web-dev-qa-db-fra.com

Le fond modal de Twitter ne disparaît pas

J'utilise la boîte de dialogue Twitter bootstrap Modal. Lorsque je clique sur le bouton d'envoi de la boîte de dialogue d'amorçage, il envoie une demande AJAX. Mon problème est que le fond modal ne disparaît pas. La boîte de dialogue modale disparaît correctement mais à la place, "l'arrière-plan modal" qui crée l'opacité à l'écran reste

Que puis-je faire?

238
paganotti

Assurez-vous de ne pas remplacer le conteneur contenant la fenêtre modale lorsque vous exécutez la demande AJAX, car Bootstrap ne pourra pas trouver de référence lorsque vous essayez de le fermer. Dans votre gestionnaire complet Ajax, supprimez le modal, puis remplacez les données.

Si cela ne fonctionne pas, vous pouvez toujours le forcer à disparaître en procédant comme suit:

$('#your-modal-id').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
492
ChezFre

Assurez-vous que votre appel initial à $.modal() pour appliquer le comportement modal ne transmet pas plus d'éléments que prévu. Si cela se produit, il finira par créer une instance modale, complétée par un élément d'arrière-plan, pour chaque élément de la collection. Par conséquent, il peut sembler que la toile de fond a été laissée de côté, alors qu’il s’agit en fait d’un des doublons.

Dans mon cas, je tentais de créer le contenu modal à la volée avec un code comme celui-ci:

myModal = $('<div class="modal">...lots of HTML content here...</div><!-- end modal -->');
$('body').append(myModal);
myModal.modal();

Ici, le commentaire HTML après la balise </div> de clôture signifiait que myModal était en réalité une collection jQuery de deux éléments - le div et le commentaire. Les deux ont été consciencieusement transformés en modaux, chacun avec son propre élément de fond. Bien sûr, le modal issu du commentaire était invisible en dehors de la toile de fond, donc lorsque j'ai fermé le modal réel (le div), il semblait que l'arrière-plan avait été oublié.

64
gasman

Je viens de passer beaucoup trop de temps sur ce problème :)

Alors que les autres réponses fournies sont utiles et valables, il m'a semblé un peu compliqué de recréer efficacement la fonctionnalité de masquage modal de Bootstrap. J'ai donc trouvé une solution plus propre.

Le problème est qu’il y a une chaîne d’événements qui se produisent lorsque vous appelez

$("#myModal").modal('hide');
functionThatEndsUpDestroyingTheDOM()

Lorsque vous remplacez ensuite un groupe de HTML à la suite de la demande AJAX, les événements de masquage modal ne se terminent pas. Cependant, Bootstrap déclenche un événement lorsque tout est fini , et vous pouvez vous y accrocher comme ceci:

$("#myModal").modal('hide').on('hidden.bs.modal', functionThatEndsUpDestroyingTheDOM);

J'espère que c'est utile!

49
Bill Huertas

Insérez dans votre bouton d'action ceci:

data-backdrop="false"

et 

data-dismiss="modal" 

exemple:

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

<button type="button" class="btn btn-danger danger" data-dismiss="modal" data-backdrop="false">Action</button>

si vous entrez cette donnée-attr, le fond. modal n'apparaîtra pas . documentation à ce sujet sur ce lien: http://getbootstrap.com/javascript/#modals-usage

31
kampageddon

Si vous utilisez un copier-coller du site getboostrap lui-même dans un sélecteur généré par HTML, veillez à supprimer le commentaire '<! - /.modal ->'. Bootstrap est confus et pense que le commentaire est un deuxième élément modal. Cela crée une autre chute arrière pour ce "deuxième" élément.

18
Jordan

J'ai eu un problème similaire: dans ma fenêtre modale, j'ai deux boutons, "Annuler" et "OK". A l'origine, les deux boutons fermaient la fenêtre modale en appelant $('#myModal').modal('hide') (avec "OK" exécutant précédemment du code) et le scénario serait le suivant:

  1. Ouvre la fenêtre modale
  2. Faites quelques opérations, puis cliquez sur "OK" pour les valider et fermez le modal
  3. Ouvrez à nouveau le modal et fermez-le en cliquant sur "Annuler"
  4. Rouvrez le modal, cliquez à nouveau sur "Annuler" ==> la toile de fond n'est plus accessible!

eh bien, mon collègue du bureau suivant a sauvé ma journée: au lieu d’appeler $('#myModal').modal('hide'), donnez à vos boutons l’attribut data-dismiss="modal" et ajoutez un événement "clic" à votre bouton "Soumettre". Dans mon problème, le code HTML (ainsi que TWIG) du bouton est le suivant:

<button id="modal-btn-ok" class="btn" data-dismiss="modal">OK</button>
<button id="modal-btn-cancel" class="btn" data-dismiss="modal">Cancel</button>

et dans mon code JavaScript, j'ai:

$("#modal-btn-ok").one("click", null, null, function(){
    // My stuff to be done
});

alors qu'aucun événement "clic" n'est attribué au bouton "Annuler". Le modal se ferme maintenant correctement et me permet de rejouer avec la page "normale". Il semble en fait que data-dismiss="modal" devrait être le seul moyen d'indiquer qu'un bouton (ou un élément DOM quelconque) doit fermer un modal Bootstrap. La méthode .modal('hide') semble se comporter de manière non contrôlable.

J'espère que cela t'aides!

9
Dima Gabachov

Ce problème peut également se produire si vous masquez puis affichez à nouveau la fenêtre modale trop rapidement. Cela a été mentionné ailleurs pour la question, mais je vais donner plus de détails ci-dessous.

Le problème est lié au timing et à la transition en fondu. Si vous affichez un modal avant la fin de la transition en fondu pour le modal précédent, vous verrez ce problème de fond persistant (le fond modal restera à l'écran, à votre manière). Bootstrap ne prend explicitement pas en charge plusieurs modaux simultanés, mais cela semble être un problème même si le modal que vous cachez et le modal que vous affichez sont les mêmes.

Si tel est le motif de votre problème, voici quelques options pour l'atténuer. L'option n ° 1 est un test rapide et facile permettant de déterminer si la synchronisation de la transition en fondu est effectivement la cause de votre problème.

  1. Désactiver l'animation de fondu pour le modal (supprimer la classe "fade" de la boîte de dialogue)
  2. Mettez à jour le texte du modal au lieu de le cacher et de le montrer à nouveau.
  3. Corrigez le timing pour qu'il ne montre pas le modal jusqu'à ce qu'il ait fini de cacher le modal précédent. Utilisez les événements du modal pour le faire. http://getbootstrap.com/javascript/#modals-events

Voici quelques publications de tracker de problèmes liées à bootstrap. Il est possible qu'il y ait plus de messages de suivi que ceux énumérés ci-dessous.

8
Mark F Guerra

.modal ('cacher')

Masque manuellement un modal. Renvoie à l'appelant avant que le modal ait été réellement masqué (c'est-à-dire avant l'événement hidden.bs.modal).

Donc au lieu de 

$('#myModal').modal('hide');
$('#someOtherSelector').trigger('click');

faire

$('#myModal').modal('hide');
$('#myModal').on('hidden.bs.modal', function() {
   $('#someOtherSelector').trigger('click');
});

Vous êtes donc sûr d’attendre la fin de l’événement "masquer".

7
Helmut Hackl

Même si j'ai rencontré un problème similaire, j'avais les deux boutons suivants

<button id="confirm-delete-btn" >Yes, Delete this note.</button>
<button id="confirm-delete-cancel" data-dismiss="modal">No</button>

Je voulais effectuer une opération ajax et, si cette opération est réussie, fermez le modal. Alors voici ce que j'ai fait. 

$.ajax({
        url: '/ABC/Delete/' + self.model.get("Id")
            , type: 'DELETE'
            , success: function () {                    
                setTimeout(function () {
                    self.$("#confirm-delete-cancel").trigger("click");
                }, 1200);
            }
            , error: function () {}
        });

J'ai déclenché l'événement click du bouton 'Non' qui possédait la propriété data-dismiss="modal". Et cela a fonctionné :)

5
Yasser

Je sais que c’est un très vieux message mais cela pourrait aider . C’est une très petite solution de contournement que

$('#myModal').trigger('click');

Ça y est, cela devrait résoudre le problème

4

utilisation:

$('.modal.in').modal('hide') 

La source

4
Jamshid Hashimi

Cette solution concerne Ruby on Rails 3.x et un fichier js.erb qui reconstruit une partie du DOM, y compris le modal. Cela fonctionne que l’appel ajax vienne du modal ou d’une autre partie de la page.

if ($("#my-modal").attr("aria-hidden") === "false") {
  $("#my-modal").modal('hide').on('hidden.bs.modal', function (event) {
    functionThatEndsUpDestroyingTheDOM();
  });
} else {
  functionThatEndsUpDestroyingTheDOM();
}

Merci à @BillHuertas pour le point de départ.

3
mindriot

Un autre point de vue à cette question. (J'utilise la version 3.3.6 de bootstrap.js)

Je me suis trompé d'initialiser modal à la fois manuellement en javascript:

$('#myModal').modal({
   keyboard: false
})

et en utilisant 

data-toggle="modal" 

dans ce bouton comme exemple ci-dessous (montré dans le document)

<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Launch demo modal</button>

de sorte que le résultat de sa créer deux instance de 

<div class="modal-backdrop fade in"></div>

ajouter au corps de mon HTML lorsque vous ouvrez le modal. Cela peut être la cause lors de la fermeture du modal à l'aide de la fonction:

$('#myModal').modal('hide');

il supprime une seule instance de fond (comme indiqué ci-dessus) afin que le fond ne disparaisse pas. Mais il a disparu si vous utilisez data-dismiss="modal" add on html comme indiqué dans la documentation d'amorçage. 

La solution à mon problème est donc d’initialiser le modal manuellement en javascript et de ne pas utiliser d’attribut de données. De cette façon, je peux fermer le modal manuellement et en utilisant les fonctionnalités data-dismiss="modal".

J'espère que cela vous aidera si vous rencontrez le même problème que moi.

2
ohm89

Une autre erreur possible qui pourrait produire ce problème,

Assurez-vous que vous n'avez pas inclus le script bootstrap.js plus d'une fois dans votre page!

2
Webinan

problème updatepanel.

Mon problème était dû au placement de updatepanel. J'ai eu l'intégralité du modal dans le Updatepanel. Si vous déclarez le modal en dehors de updatepanel et que vous venez de dire, le corps modal, dans le panneau de mise à jour, alors le. $ ('# myModalID'). modal ('hide'); travaillé.

2
Al Option

Utiliser toggle au lieu de hide a résolu mon problème

1
Yash K

J'ai eu le même problème en essayant de soumettre le formulaire. La solution consistait à changer le type de bouton de submit à button, puis à gérer l'événement de clic de bouton comme suit:

'click .js-save-modal' () {
    $('#myFormId').submit();
    $('#myModalId').modal('hide');
}
1
sym

Assurez-vous que vous n'utilisez pas le même élément Id/class ailleurs, pour un élément non lié au composant modal. 

C’est-à-dire… si vous identifiez vos boutons qui déclenchent les fenêtres contextuelles modales à l’aide du nom de classe «myModal», assurez-vous qu’il n’existe pas d’éléments sans relation ayant le même nom de classe. 

1
user2707674

FYI au cas où quelqu'un se heurterait encore ... J'ai passé environ 3 heures à découvrir que la meilleure façon de le faire est la suivante:

$("#my-modal").modal("hide");
$("#my-modal").hide();
$('.modal-backdrop').hide();
$("body").removeClass("modal-open");

Cette fonction pour fermer le modal est très peu intuitive.

1
Nick M

$ ('# myModal'). trigger ('clic');

Cela a fonctionné pour moi. Sa fermeture n'est pas parce que lorsque vous ouvrez le popup, il déclenche 2 ou 3 fonds de modal. Alors, quand vous faites $ ('# myModal')). Modal ('hide'); cela n'affecte qu'un seul fond modal et le reste reste. 

1
Ashhab

Dans ASP.NET, ajoutez une mise à jour pour UpdatePanel le code après la commande Jquery. Exemple:

    ScriptManager.RegisterStartupScript(Page, Page.GetType(), "myModal", "$('#myModal').modal('hide');", true);
    upModal.Update();
0
mathias.horn

L'ajout de data-dismiss="modal" à n'importe quel bouton de mon modal a fonctionné pour moi. Je voulais que mon bouton appelle une fonction avec angular pour déclencher un appel ajax ET ferme le modal. J'ai donc ajouté une .toggle() dans la fonction et cela a bien fonctionné. (Dans mon cas, j'ai utilisé un bootstrap modal et une certaine angular, pas un contrôleur modal réel).

<button type="button" class="btn btn-primary" data-dismiss="modal"
ng-click="functionName()"> Do Something </button>

$scope.functionName = function () {
angular.element('#modalId').toggle();
  $.ajax({ ajax call })
}
0
wendyg

J'ai eu ce même problème.

Cependant, j'utilisais bootbox.js, donc ça aurait pu être quelque chose à voir avec ça.

Quoi qu'il en soit, j'ai réalisé que le problème était dû à la présence d'un élément de la même classe que son parent. Lorsque l'un de ces éléments est utilisé pour lier une fonction de clic afin d'afficher le modal, le problème se produit.

c'est ce qui cause le problème:

<div class="myElement">
    <div class="myElement">
        Click here to show modal
    </div>
</div>

changez-le pour que l'élément sur lequel vous cliquez n'ait pas la même classe que son parent, aucun de ses enfants ou aucun autre ancêtre. C'est probablement une bonne pratique de faire cela en général lorsque vous liez des fonctions de clic.

0
Vin

Je travaille avec Meteor et je viens d'avoir le même problème. La cause de mon bug était la suivante:

{{#if tourmanager}}
    {{>contactInformation tourmanager}}
{{else}}
    <a href="#addArtistTourmanagerModal" data-toggle="modal"><i class="fa fa-plus"></i> Tourmanager toevoegen</a>
    {{>addArtistTourmanagerModal}}
{{/if}}

Comme vous pouvez le voir, j'ai ajouté le modal dans le paramètre else, donc lorsque mon modal a mis à jour les informations de contact, le if avait un autre état. Cela a eu pour effet de laisser le modèle modal en dehors du DOM juste avant sa fermeture. 

La solution: déplacez le modal hors du if-else:

{{#if tourmanager}}
    {{>contactInformation tourmanager}}
{{else}}
    <a href="#addArtistTourmanagerModal" data-toggle="modal"><i class="fa fa-plus"></i> Tourmanager toevoegen</a>
    {{>addArtistTourmanagerModal}}
{{/if}}
0
Scuba Kay

J'ai eu le même problème. J'ai découvert que c'était dû à un conflit entre Bootstrap et JQueryUI.

Les deux utilisent la classe "close". Changer la classe dans l'un ou l'autre corrige cela.

0
Matthew Andrianakos

la valeur initiale de votre data-backdrop attribut peut être 

"statique", "vrai", "faux". 

static et true ajoute l'ombre modale, tandis que false désactive l'ombre, il vous suffit donc de modifier cette valeur avec le premier clic sur false. comme ça:

$(document).on('ready',function(){
	
	var count=0;
	
$('#id-which-triggers-modal').on('click',function(){
		
		if(count>0){
		
			$(this).attr('data-backdrop','false')
		}
		count++;
});


});

0
Alejandro Quintero

J'ai eu le problème de gel d'écran de fond modal mais dans un scénario légèrement différent: Lorsque 2 modaux dos à dos étaient affichés. par exemple. Le premier demanderait une confirmation pour faire quelque chose et, après avoir cliqué sur le bouton «confirmer», l'action rencontrerait une erreur et le second modal s'afficherait pour afficher le message d'erreur. La deuxième toile de fond modale gèlerait l'écran . Il n'y avait aucun conflit dans les noms de classe ou les identifiants des éléments.

Le problème a été résolu de manière à laisser au navigateur suffisamment de temps pour traiter le fond modal. Au lieu de prendre immédiatement les mesures après avoir cliqué sur le bouton «confirmer», indiquez au navigateur 500 ms pour masquer le premier modal et nettoyer le fond, etc. - puis effectuez l'action qui finirait par afficher le modal d'erreur.

<button type="button" class="btn btn-red" data-dismiss="modal" on-tap="_dialogConfirmed">Confirm</button>
...

La fonction _dialogConfirmed () a le code suivant:

    var that = this;

    setTimeout(function () {
      if (that.confirmAction) {
        (that.confirmAction)();
        that.confirmAction = undefined;
      }
    }, 500);

J'imagine que les autres solutions ont fonctionné, car elles ont pris suffisamment de temps, ce qui a donné au navigateur le temps nécessaire au nettoyage.

0
Behnam
//Create modal appending on body
myModalBackup = null;
$('#myModal').on('hidden.bs.modal', function(){
       $('body').append(myModalBackup.clone());
    myModalBackup = null;
});

//Destroy, clone and show modal
myModalBackup = $('#myModal').clone();
myModalBackup.find('.modal-backdrop').remove();
$('#myModal').modal('hide').remove();
myModalBackup.find('.info1').html('customize element <b>1</b>...');
myModalBackup.find('.info2').html('customize element <b>2</b>...');                             
myModalBackup.modal('show');

violon -> https://jsfiddle.net/o6th7t1x/4/

0
Fábio Zangirolami

Après avoir appliqué la solution la mieux cotée, le problème est que cela ouvre correctement les futurs modaux. J'ai trouvé ma solution qui fonctionne bien

        element.on("shown.bs.modal", function () {
            if ($(".modal-backdrop").length > 1) {
                $(".modal-backdrop").not(':first').remove();
            }
            element.css('display', 'block');
        });
0
Rez

Dans le projet .net MVC4, j'avais la fenêtre contextuelle modale (bootstrap 3.0) dans un Ajax.BeginForm (OnComplete = "addComplete" [code supprimé supprimé]). Dans le javascript "addComplete", j'avais le code suivant. Cela a résolu mon problème.

$ ('# moreLotDPModal'). hide ();

$ ("# moreLotDPModal"). data ('bs.modal'). isShown = false;

$ ('body'). removeClass ('modal-open');

$ ('. modal-backdrop'). remove ();

$ ('# moreLotDPModal'). removeClass ("in");

$ ('# moreLotDPModal'). attr ('aria-hidden', "true");

0
JenonD

De https://github.com/twbs/bootstrap/issues/19385

Les méthodes d'affichage/masquage de Modal sont asynchrones. Par conséquent, code tel que:

foo.modal("hide"); bar.modal("show"); n'est pas valide. Vous devez attendre pour l’affichage/masquage à compléter (en écoutant les événements affichés/masqués; voir http://getbootstrap.com/javascript/#modals-events ) avant d’appeler le afficher ou masquer les méthodes à nouveau.

J'ai eu ce problème quand j'ai ouvert le même modal deux fois trop vite, donc une solution facile était de vérifier s'il était déjà affiché, puis de ne plus le montrer:

$('#modalTitle').text(...);
$('#modalMessage').text(...);
if($('#messageModal').is(':hidden')){
    $('#messageModal').modal('show');
}
0
shinzou

pour moi, la meilleure réponse est la suivante. 

<body>
<!-- All other HTML -->
<div>
    ...
</div>

<!-- Modal -->
<div class="modal fade" id="myModal">
    ...
</div>

Emplacement du marquage modal Essayez toujours de placer le code HTML d'un modal au plus haut niveau de votre document afin d'éviter que d'autres composants nuisent à son apparence et/ou à ses fonctionnalités.

de cette SO répondre

0
PurTahan

Essaye ça 

$('#something_clickable').on('click', function () {
  $("#my_modal").modal("hide");
  $("body").removeClass("modal-open");
  $('.modal-backdrop').remove();
 });

Ça fonctionne bien pour moi.

0
A H K

J'avais un problème similaire. J'utilisais Boostrap conjointement avec Backbone et je capturais des clics du bouton "Do it", puis arrêtais la propagation de ces événements. Bizarrement, cela a fait disparaître le modal, mais pas l'arrière-plan. Si j'appelle event.preventDefault () mais n'appelle pas stopPropagation (), tout fonctionne correctement.

0
gischer