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.