Como centralizar automaticamente a caixa de diálogo da IU do jQuery ao redimensionar o navegador?

100

Quando você usa a caixa de diálogo da IU do jquery, tudo funciona bem, exceto por uma coisa. Quando o navegador é redimensionado, a caixa de diálogo apenas permanece em sua posição inicial, o que pode ser realmente irritante.

Você pode testá-lo em: http://jqueryui.com/demos/dialog/

Clique no exemplo de "diálogo modal" e redimensione seu navegador.

Eu adoraria permitir que as caixas de diálogo sejam centralizadas automaticamente quando o navegador for redimensionado. Isso pode ser feito de maneira eficiente para todos os meus diálogos no meu aplicativo?

Muito obrigado!

Jorre
fonte

Respostas:

160

Definir a positionopção forçará isso, então apenas use o mesmo seletor cobrindo todos os seus diálogos onde eu uso #dialogaqui (se não os encontrar, nenhuma ação será realizada, como todo o jQuery):

jQuery UI antes de 1.10

$(window).resize(function() {
    $("#dialog").dialog("option", "position", "center");
});

jQuery UI 1.10 ou superior

$(window).resize(function() {
    $("#dialog").dialog("option", "position", {my: "center", at: "center", of: window});
});

Aqui está a mesma página de demonstração do jQuery UI adicionando apenas o código acima , estamos apenas adicionando um manipulador ao resizeevento da janela com .resize(), portanto, ele aciona o recentramento no momento apropriado.

Nick Craver
fonte
obrigado, isso parece ótimo. Talvez eu devesse ter dito que nem sempre sei qual é o ID da minha caixa de diálogo, assim (como posso direcionar essa caixa de diálogo?): Var $ dialog = $ ('<div> <a href = "#" title = "Cancelar"> Cancelar </a> </a> </div> ') .html (assetBrowser) .dialog ({autoOpen: false, title:' Assets Manager ', modal: true, closeOnEscape: true, buttons: botões, largura: 840, altura: 500}); $ dialog.dialog ('abrir');
Jorre
11
@Jorre - Todos eles recebem a mesma classe quando você cria um diálogo, para torná-lo genérico, você pode fazer o seguinte:, $(".ui-dialog-content").dialog("option", "position", "center");isto irá verificar se há qualquer diálogo :)
Nick Craver
3
Infelizmente, a resposta proposta afeta mal o redimensionamento do diálogo. Quando você tenta redimensioná-lo com a alça SE, o diálogo é redimensionado em todos os 4 lados.
2
Eu recomendo controlar ou eliminar o evento de redimensionamento. Já vi o IE7 e o IE8 moverem a caixa de diálogo "para fora" da janela de visualização devido ao manipulador de redimensionamento ser executado muitas vezes.
BStruthers
2
Em versões mais recentes da UI jQuery, eu precisava usar {my: "center", em: "center", of: window} em vez de "center". Estou usando 1.11.0.
Mike Dotterer
20

Alternativamente à resposta de Ellesedil,

Essa solução não funcionou para mim imediatamente, então fiz o seguinte, que também é uma versão dinâmica, mas abreviada:

$( window ).resize(function() {
    $(".ui-dialog-content:visible").each(function () {
        $( this ).dialog("option","position",$(this).dialog("option","position"));
    });
});

1 para Ellesedil embora

EDITAR:

Versão muito mais curta que funciona muito bem para caixas de diálogo individuais:

$(window).resize(function(){
    $(".ui-dialog-content").dialog("option","position","center");
});

Não é necessário que .each () seja usado, talvez se você tiver alguns diálogos exclusivos que não deseja tocar.

Pierre
fonte
usando a classe .ui-dialog-content é para todos os diálogos, a resposta aceita é para um diálogo específico
Pierre
Ah, certo. Desculpe. Não notei a distinção à primeira vista na edição.
Ellesedil
Estou usando essa abordagem com quase sucesso. Funciona como anunciado, mas o safari móvel iOS 7 realmente engasga se o teclado estiver levantado. Eu tentei desfocar () a entrada, mas o Gingerbread vê o teclado como um evento de redimensionamento e fica preso em um loop que nunca permite a entrada de entrada. Alguém mais está enfrentando isso?
Joseph Juhnke
Talvez adicione um contador fora .resize()e dentro se o contador atingir 10ou 20então break;, eu não tive esse problema, não atendo para esses dispositivos / navegadores. Você deve tentar uma solução que, se ela travar, você poderá sair dela
Pierre
Sua primeira sugestão funcionou bem e a resposta de @Ellesedil não.
akousmata
13

Uma resposta mais abrangente, que usa a resposta de Nick de uma forma mais flexível, pode ser encontrada aqui .

Uma adaptação do código de relevância desse segmento está abaixo. Esta extensão essencialmente cria uma nova configuração de diálogo chamada autoReposition que aceita um verdadeiro ou falso. O código conforme escrito padroniza a opção como verdadeiro. Coloque isso em um arquivo .js em seu projeto para que suas páginas possam aproveitá-lo.

    $.ui.dialog.prototype.options.autoReposition = true;
    $(window).resize(function () {
        $(".ui-dialog-content:visible").each(function () {
            if ($(this).dialog('option', 'autoReposition')) {
                $(this).dialog('option', 'position', $(this).dialog('option', 'position'));
            }
        });
    });

Isso permite que você forneça um "verdadeiro" ou "falso" para esta nova configuração ao criar sua caixa de diálogo em sua página.

$(function() {
    $('#divModalDialog').dialog({
        autoOpen: false,
        modal: true,
        draggable: false,
        resizable: false,
        width: 435,
        height: 200,
        dialogClass: "loadingDialog",
        autoReposition: true,    //This is the new autoReposition setting
        buttons: {
            "Ok": function() {
                $(this).dialog("close");
            }
        }
    });
});

Agora, esta caixa de diálogo sempre se reposicionará. A AutoReposição (ou o que quer que você chame de configuração) pode lidar com qualquer caixa de diálogo que não tenha uma posição padrão e reposicioná-la automaticamente quando a janela for redimensionada. Como você está definindo isso ao criar a caixa de diálogo, não é necessário identificar uma caixa de diálogo de alguma forma, porque a funcionalidade de reposicionamento torna-se integrada à própria caixa de diálogo. E a melhor parte é que, como isso é definido por diálogo, você pode fazer com que alguns diálogos se reposicionem e outros permaneçam onde estão.

Agradecemos ao usuário scott.gonzalez nos fóruns da jQuery pela solução completa.

Ellesedil
fonte
Este addon / edição parece não funcionar mais em julho de 2014. A resposta de @Pierre ainda funciona.
degenerado
@degenerate: é possível que as atualizações para jQuery possam exigir algumas mudanças na sintaxe. Não estou mais trabalhando ou mesmo tendo acesso ao projeto onde implementei isso (na verdade, estou escrevendo APIs), então não tenho uma maneira fácil de determinar se alguma mudança é necessária para versões recentes do jQuery.
Ellesedil
Esta resposta não funciona para versões recentes. Mas a ideia é ótima. Este é o conteúdo do meu manipulador de redimensionamento de janela: $(".ui-dialog-content:visible").each(function () { if ($(this).dialog('option', 'autoReposition')) { $(this).dialog('option', 'position', $(this).dialog('option', 'position')); } });Funciona muito bem :)
nacho4d
@ nacho4d: Sinta-se à vontade para editar a resposta e adicionar o código mais recente para qualquer versão do jquery em que você esteja trabalhando na parte inferior.
Ellesedil de
1
@Ellesedil Acabei de alterar algumas linhas em seu primeiro pedaço de código. Na verdade, é o que scott.gonzalez escreveu primeiro no tópico. Não sei por que ele mudou $( "#dialog" ).dialog( "option", "position" ) para $(this).data("dialog").options.positionmais tarde. Enfim, agora essa resposta funciona!
nacho4d
2

Outra opção somente CSS que funciona é esta. As margens negativas devem ser iguais a metade da altura e metade da largura. Portanto, neste caso, minha caixa de diálogo tem 720 px de largura por 400 px de altura. Isso o centraliza verticalmente e horizontalmente.

.ui-dialog {
  top:50% !important;
  margin-top:-200px !important; 
  left:50% !important;
  margin-left:-360px !important
}
Kirk Ross
fonte
2

Alternativamente, a posição ui do jQuery pode ser usada,

$(window).resize(function ()
{
    $(".ui-dialog").position({
        my: "center", at: "center", of: window
    });
});
AkilaI
fonte
0

Olá a todos!

Solução Vanilla JS:

(function() {
  window.addEventListener("resize", resizeThrottler, false);

  var resizeTimeout;

  function resizeThrottler() {
    if (!resizeTimeout) {
      resizeTimeout = setTimeout(function() {
        resizeTimeout = null;
        actualResizeHandler();
      }, 66);
    }
  }

  function actualResizeHandler() {
    $(".ui-dialog-content").dialog("option", "position", { my: "center", at: "center", of: window });
  }
}());
Alexandr Kazakov
fonte
$.isVanillaJS == false
Andrew