O cenário de inicialização modal do Twitter não desaparece


260

Estou usando a caixa de diálogo Modal de inicialização do Twitter. Quando clico no botão de envio da caixa de diálogo modal de auto-inicialização, ele envia uma solicitação AJAX. Meu problema é que o cenário modal não desaparece. A caixa de diálogo Modal desaparece corretamente, mas, em vez disso, "modal-backdrop in" que cria a opacidade na tela permanece

O que eu posso fazer?


5
Você está usando $('#myModal').modal('hide')? Você pode colocar algum código aqui?
— Pigueiras 17/07

20
Se você estiver usando uma cópia e colagem do próprio site getboostrap em um seletor gerado em html, remova o comentário '<! - /.modal ->'. O Bootstrap fica confuso e pensa que o comentário é um segundo elemento modal. Ele cria outro retorno para esse "segundo" elemento.
— Jordânia

@ Jordânia: Seu comentário precisa ser uma resposta! No meu caso, seu comentário foi a solução correta!
— BlaM 15/06


Eu sei que a pergunta é antiga, mas hoje eu tenho um problema semelhante, na minha situação houve uma remoção incorreta da classe "modal-lg" que foi deixada apenas para "modal", criando confusão quando você fecha o modal com o teclado / clique em algum lugar externo.
— Matteo

Respostas:


550

Certifique-se de não substituir o contêiner que contém a janela modal real ao fazer a solicitação AJAX, porque o Bootstrap não poderá encontrar uma referência a ele ao tentar fechá-la. No manipulador completo do Ajax, remova o modal e substitua os dados.

Se isso não funcionar, você sempre pode forçá-lo a desaparecer fazendo o seguinte:

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

16
Daria esta resposta +2 se eu pudesse. Apenas me salvou horas!
— Andre Lombaard 15/10

9
Ocultar o modal antes da chamada do AJAX é uma solução ruim se você precisar avaliar a resposta do AJAX e atualizar o modal de acordo.
— asciimo

19
Eu acredito que isso também pode ser causado pela chamada modal ('hide') antes que a animação fade seja totalmente concluída. Remover a classe fade do modal pode ajudar.
— EvilPuppetMaster

7
$ ('. modal-backdrop'). remove (); resolvido para mim, não há necessidade de remover classe de fade
— Omar S.

34
$('.modal-backdrop').remove()parece quebrar futuros modais abrindo corretamente.
— krock

65

Certifique-se de que sua chamada inicial $.modal()para aplicar o comportamento modal não esteja passando mais elementos do que você pretendia. Se isso acontecer, ele acabará criando uma instância modal, completa com o elemento backdrop, para EACH elemento na coleção. Consequentemente, pode parecer que o pano de fundo foi deixado para trás, quando na verdade você está olhando para uma das duplicatas.

No meu caso, eu estava tentando criar o conteúdo modal on-the-fly com um código como este:

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

Aqui, o comentário HTML após a </div>tag de fechamento significava que myModal era na verdade uma coleção jQuery de dois elementos - a div e o comentário. Ambos foram obedientemente transformados em modais, cada um com seu próprio elemento de pano de fundo. É claro que o modal feito com o comentário era invisível além do pano de fundo, então, quando fechei o modal real (a div), parecia que o fundo foi deixado para trás.


16
Esse cara estava no dinheiro. Eu removi os comentários de um modal que estava recebendo com $ .html () e agora funciona. Estranhamente estranho.
— Matrym 12/09/2013

2
Este foi o problema para mim também.
— Bob Black

6
Bootstrap estúpido! Seu próprio exemplo de marcação (com os comentários no início e no final) quebra esse paradigma. Remova o comentário e ele funciona!
— usar o seguinte

O mesmo aqui. A remoção dos comentários resolveu o problema. Apenas uma pergunta. Vejo que o modal funciona perfeitamente sem adicioná-lo ao DOM com $ ('body'). Append (myModal). É necessário adicionar o modal ao DOM da página?
— VictorEspina

Eu tinha uma etiqueta incompatível. Mesmo resultado. Obrigado!
— jozxyqk

51

Passei muito tempo neste problema :)

Embora as outras respostas fornecidas sejam úteis e válidas, me pareceu um pouco confuso recriar efetivamente a funcionalidade oculta modal do Bootstrap, por isso encontrei uma solução mais limpa.

O problema é que há uma cadeia de eventos que acontece quando você chama

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

Quando você substitui um monte de HTML como resultado da solicitação AJAX, os eventos de ocultação modal não são concluídos. No entanto, o Bootstrap aciona um evento quando tudo estiver concluído , e você pode conectar-se a ele da seguinte maneira:

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

Espero que isso seja útil!


15
Eu passei muito tempo também! Essa resposta me deu a pista - algo estava atrapalhando meu DOM (angular). Observando o código de autoinicialização, você pode forçar uma remoção imediata do plano de fundo removendo a classe fade primeiro:$('#myModal').removeClass('fade');$(myModal').modal('hide')'
— Ross R

O deve ser a resposta aceito - ele usa a API de inicialização como pretendido e não cortar o corpo com .modal-aberto
— Aaron Hudon

Esta é a resposta mais diligente e consciente.
— precisa saber é

Ótima resposta, meu problema também foi devido a uma chamada ajax substituindo o dom - acho que modal ('hide') retorna a si mesmo ou a referência modal para que possamos anexar a 'hidden.bs.modal'?
— Michael Harper

a declaração de que os eventos ocultos modais não terminam me deu a idéia de como começar meu trabalho.
— SamuelDev

32

Insira no seu botão de ação o seguinte:

data-backdrop="false"

e

data-dismiss="modal" 

exemplo:

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

se você inserir esses dados-attr, o .modal-backdrop não será exibido. documentação sobre isso neste link: http://getbootstrap.com/javascript/#modals-usage


2
Esta é uma resposta verdadeira. Sob nenhuma circunstância tente fazer manualmente o que o Bootstrap pretende fazer. Se essa for sua solução, você está implementando errado. Eu acho que o HTML padrão no site de inicialização é um pouco incompleto e é por isso que muitas pessoas estão enfrentando o comportamento descrito (inclusive eu). Obrigado! +1
— Ben Fransen

3
E se você quiser acionar o modal, não a partir de um botão?
— Shinzou

7
@ ben você está errado. data-backdrop="false"é simplesmente uma opção que diz ao bootstrap para não usar um pano de fundo . Isso não tem nada a ver com o problema real, apenas o evita. Seria como dizer "Eu não sei nadar, então parei de entrar na piscina". Isso é legal, mas você ainda não sabe nadar e se o seu chefe te jogar no fundo, você se afogará. Existem muitos casos em que a intervenção manual é necessária, como quando o Angular entra no DOM no fundo do seu aplicativo.
— Wesley Smith

18

Se você estiver usando uma cópia e colagem do próprio site getboostrap em um seletor gerado em html, remova o comentário '<! - /.modal ->'. O Bootstrap fica confuso e pensa que o comentário é um segundo elemento modal. Ele cria outro retorno para esse "segundo" elemento.


Eu serei amaldiçoado ... esse era exatamente o meu problema. Removido o comentário e funcionou. Como diabos um comentário em HTML tropeça no Bootstrap !?
— Turner Hayes

Eu acredito que está procurando elementos html para obter uma contagem. Como os comentários são considerados elementos, essa contagem está errada com esse comentário.
— 314 Jordan

aconteceu comigo enquanto tinha esse arquivo no modelo do bigode
— Pavel 'PK' Kaminsky

Os comentários existem no DOM de tal maneira que confundiu a metade javascript do componente modal. Eu esqueço exatamente como. Isso foi há um tempo atrás.
— Jordânia

Santo Moley - isso realmente funciona! Isso é um bug tão estranho.
— precisa

14

Eu sei que este é um post muito antigo, mas isso pode ajudar. Esta é uma solução muito pequena para mim

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

É isso, isso deve resolver o problema


1
Isso funcionou perfeitamente para mim. Usando o bootstrap 4 aqui.
— Eddie Teixeira

1
Essa deve ser a resposta padrão. Graças
— Makamu Evans

o que myModaldeveria ser? E por que fecharia o diálogo? As caixas de diálogo modais são fechadas apenas clicando no botão Fechar ou fora da caixa de diálogo. Isso não parece ser uma solução.
— MushyPeas 06/07

o que o myModal deveria ser? -> É o id do modal principal. E por que fecharia o diálogo? -> Funciona porque, por padrão, quando você clica no lado de fora do modal, a ação é propagada para o pai e é manipulada lá.
— Chaitanya Bankanhal 13/07/19

9

Sofri um problema semelhante: na minha janela modal, tenho dois botões, "Cancelar" e "OK". Originalmente, os dois botões fechariam a janela modal chamando $('#myModal').modal('hide')(com "OK" executando anteriormente algum código) e o cenário seria o seguinte:

  1. Abra a janela modal
  2. Faça algumas operações, clique em "OK" para validá-las e feche o modal
  3. Abra o modal novamente e descarte clicando em "Cancelar"
  4. Abra novamente o modal, clique novamente em "Cancelar" ==> o pano de fundo não está mais acessível!

bem, meu colega da próxima mesa salvou meu dia: em vez de chamar $('#myModal').modal('hide'), atribua aos seus botões o atributo data-dismiss="modal"e adicione um evento "click" ao seu botão "Enviar". No meu problema, o código HTML (bem, TWIG) do botão é:

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

e no meu código JavaScript, tenho:

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

enquanto nenhum evento "clique" é atribuído ao botão "Cancelar". O modal agora fecha corretamente e me permite jogar novamente com a página "normal". Na verdade, parece que data-dismiss="modal"deve ser a única maneira de indicar que um botão (ou qualquer elemento DOM) deve fechar um modal de Bootstrap. O .modal('hide')método parece se comportar de uma maneira não totalmente controlável.

Espero que isto ajude!


O mesmo aqui, e se você não quiser acionar o modal a partir de um botão?
— Shinzou

9

Esse problema também pode ocorrer se você ocultar e exibir novamente a janela modal muito rapidamente. Isso foi mencionado em outro lugar para pergunta, mas fornecerei mais alguns detalhes abaixo.

O problema está relacionado ao tempo e à transição do desbotamento. Se você mostrar um modal antes que a transição para o modal anterior seja concluída, você verá esse problema persistente do pano de fundo (o pano de fundo modal permanecerá na tela, à sua maneira). O Bootstrap explicitamente não suporta múltiplos modais simultâneos, mas isso parece ser um problema, mesmo que o modal que você está ocultando e o que você está exibindo sejam os mesmos.

Se esse for o motivo correto do seu problema, aqui estão algumas opções para atenuar o problema. A opção 1 é um teste rápido e fácil para determinar se o tempo de transição do desbotamento é realmente a causa do seu problema.

  1. Desative a animação Fade para o modal (remova a classe "fade" da caixa de diálogo)
  2. Atualize o texto do modal em vez de ocultá-lo e mostrá-lo novamente.
  3. Corrija o tempo para que ele não mostre o modal até que ele oculte o modal anterior. Use os eventos do modal para fazer isso. http://getbootstrap.com/javascript/#modals-events

Aqui estão algumas postagens relacionadas ao rastreador de problemas de inicialização. É possível que haja mais postagens de rastreadores do que as listadas abaixo.


8

.modal ('ocultar')

Oculta manualmente um modal. Retorna ao chamador antes que o modal seja realmente oculto (ou seja, antes do evento hidden.bs.modal ocorrer).

Então, ao invés de

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

Faz

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

Portanto, espere até o evento "ocultar" terminar.


Esta é definitivamente uma solução melhor. Dessa forma, você não precisa mexer nas classes modais, que provavelmente é a maneira mais correta de corrigir esse problema.
— DeanMWake

6

Outro possível erro que poderia produzir esse problema,

Verifique se você não incluiu o bootstrap.jsscript mais de uma vez na sua página!


5

Até eu tive um problema semelhante, eu tinha os dois botões a seguir

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

Eu queria executar alguma operação de ajax e, com sucesso, a operação de ajax fecha o modal. Então aqui está o que eu fiz.

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

Acionei o evento click do botão 'Não' que tinha a data-dismiss="modal"propriedade. E isso funcionou :)


O acionamento manual do evento de clique não fecha o modal no IE9 / IE10 para mim. Tentando encontrar uma solução.
— Antony Mais difícil

Deixa pra lá, o problema era um pouco diferente - eu tinha a condição de habilitação de dados anexada a esse botão e, embora o IE tenha prosseguido com os eventos onclick, ele não levou em consideração a atribuição de dispensa de dados.
— Antony Mais difícil


3

Esta solução é para Ruby on Rails 3.xe um arquivo js.erb que reconstrói parte do DOM, incluindo o modal. Funciona independentemente se a chamada ajax veio do modal ou de uma parte diferente da página.

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

Obrigado a @BillHuertas pelo ponto de partida.


3

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

Isso funcionou para mim. Não está fechando, porque quando você abre o pop-up, ele aciona 2 ou 3 cenários modais. Então, quando você faz $ ('# myModal')). Modal ('hide'); afeta apenas um cenário modal e o restante permanece.


2

problema no updatepanel.

Meu problema ocorreu devido à colocação do painel de atualização. Eu tinha todo o modal no painel de atualização. Se você declarar o modal fora do painel de atualização e apenas digamos, o corpo modal, no painel de atualização, então o $ ('# myModalID'). Modal ('hide'); trabalhou.


Este foi o meu problema. Eu tinha um AjaxManager criando painéis de atualização em torno do meu controle de usuário, que continha todo o modal. Deixei apenas o corpo do modal no controle do usuário e movi tudo na página principal e tudo começou a funcionar como esperado, portanto, não ajaxifique sua parte <div id = "# mymodal">!
— Alexanderd

2

Outro ponto de vista para esta questão. (Estou usando a versão 3.3.6 do bootstrap.js)

Eu enganei inicializar modal tanto manualmente em javascript:

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

e usando

data-toggle="modal"

neste botão, como no exemplo abaixo (mostrado no documento)

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

então o resultado é criar duas instâncias de

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

anexar ao corpo do meu html quando abrir o modal. Essa pode ser a causa ao fechar o modal usando a função:

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

remove apenas uma instância do pano de fundo (como mostrado acima) para que o pano de fundo não desapareça. Mas ele desapareceu se você usar data-dismiss="modal"add on html como mostra no documento de inicialização.

Portanto, a solução para o meu problema é inicializar apenas modal manualmente em javascript e não usar o atributo de dados. Dessa forma, posso fechar o modal manualmente e usando os data-dismiss="modal"recursos.

Espero que isso ajude se você encontrou o mesmo problema que eu.


2

Para sua informação, caso alguém se depare com isso ainda ... Passei cerca de 3 horas para descobrir que a melhor maneira de fazer isso é a seguinte:

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

Essa função para fechar o modal é muito pouco intuitiva.


Funcionou como um encanto.
— Pattu

2

Adicionando data-dismiss="modal"qualquer botão no meu modal funcionou para mim. Eu queria que meu botão chamasse uma função com angular para disparar uma chamada ajax E fechasse o modal, então adicionei um .toggle()dentro da função e funcionou bem. (No meu caso, usei um bootstrap modale usei alguns angular, não um controlador modal real).

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

1

Eu tive o mesmo problema. Eu descobri que era devido a um conflito entre o Bootstrap e o JQueryUI.

Ambos usam a classe "close". Alterar a classe em um ou outro corrige isso.


1

Usando alternar em vez de ocultar, resolvi meu problema


1
compartilhe uma resposta possível (exemplo). Ele vai ajudar os outros a entender bem
— Sachith Muhandiram

1

Verifique se você não está usando o mesmo ID / classe do elemento em outro lugar, para um elemento não relacionado ao componente modal.

Ou seja, se você estiver identificando seus botões que acionam os pop-ups modais usando o nome de classe 'myModal', verifique se não há elementos não relacionados com o mesmo nome de classe.


1

Depois de aplicar a solução mais votada, tive um problema que interrompe os futuros modais abrindo corretamente. Eu encontrei minha solução que funciona bem

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

1

Eu tive o mesmo problema ao tentar enviar o formulário. A solução foi alterar o tipo de botão de submitpara buttone, em seguida, manipular o evento de clique no botão da seguinte forma:

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

0

No projeto .net MVC4, tive o pop-up modal (bootstrap 3.0) dentro de um Ajax.BeginForm (OnComplete = "addComplete" [código extra excluído]). Dentro do javascript "addComplete", eu tinha o seguinte código. Isso resolveu meu problema.

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

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

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

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

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

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


0

Eu tive esse mesmo problema.

No entanto, eu estava usando o bootbox.js, então poderia ter algo a ver com isso.

De qualquer forma, percebi que o problema estava sendo causado por ter um elemento com a mesma classe que é pai. Quando um desses elementos é usado para vincular uma função de clique para exibir o modal, o problema ocorre.

isto é, é o que causa o problema:

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

altere-o para que o elemento que está sendo clicado não tenha a mesma classe que é pai, qualquer um de seus filhos ou qualquer outro ancestral. Provavelmente, é uma boa prática fazer isso em geral ao vincular funções de clique.


0

Estou trabalhando com o Meteor e acabei de ter o mesmo problema. A causa do meu bug foi esta:

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

Como você pode ver, adicionei o modal no else, portanto, quando meu modal atualizou as informações de contato, se tinha outro estado. Isso fez com que o modelo modal fosse deixado de fora do DOM pouco antes de ser fechado.

A solução: mova o modal para fora do 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
//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');

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


0

o valor inicial do seu atributo data-backdrop pode ser

"estático", "verdadeiro", "falso".

static e true adicione a sombra modal, enquanto false desative a sombra, então você só precisa alterar esse valor com o primeiro clique em false. como isso:

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


});


0

Eu tive o problema de congelamento da tela de pano de fundo modal, mas em um cenário um pouco diferente: quando dois modais consecutivos estavam sendo exibidos. por exemplo, o primeiro solicitava confirmação para fazer alguma coisa e após o clique no botão 'confirmar', a ação apresentava um erro e o segundo modal era exibido para exibir a mensagem de erro. O segundo cenário modal congelaria a tela. Não houve conflitos nos nomes das classes ou nos IDs dos elementos.

A maneira como o problema foi corrigido foi dar ao navegador tempo suficiente para lidar com o cenário modal. Em vez de executar imediatamente a ação após o clique em 'confirmar', dê ao navegador 500ms para ocultar o 1º modal e limpar o pano de fundo etc. - em seguida, execute a ação que acabaria mostrando o modal de erro.

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

A função _dialogConfirmed () possui o seguinte código:

    var that = this;

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

Suponho que as outras soluções funcionaram porque levaram tempo extra suficiente, dando ao navegador o tempo de limpeza necessário.


0

No ASP.NET, adicione uma atualização para UpdatePanel no código após o comando jquery. Exemplo:

    ScriptManager.RegisterStartupScript(Page, Page.GetType(), "myModal", "$('#myModal').modal('hide');", true);
    upModal.Update();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.