¿Cómo centrar automáticamente el cuadro de diálogo de la interfaz de usuario de jQuery al cambiar el tamaño del navegador?

100

Cuando usa el cuadro de diálogo de la interfaz de usuario de jquery, todo funciona bien, excepto por una cosa. Cuando se cambia el tamaño del navegador, el cuadro de diálogo permanece en su posición inicial, lo que puede ser realmente molesto.

Puede probarlo en: http://jqueryui.com/demos/dialog/

Haga clic en el ejemplo de "diálogo modal" y cambie el tamaño de su navegador.

Me encantaría poder permitir que los diálogos se centren automáticamente cuando el navegador cambia de tamaño. ¿Se puede hacer esto de manera eficiente para todos mis cuadros de diálogo en mi aplicación?

¡Muchas gracias!

Jorre
fuente

Respuestas:

160

Establecer la positionopción forzará esto, así que solo use el mismo selector que cubra todos sus cuadros de diálogo donde uso #dialogaquí (si no los encuentra, no se realiza ninguna acción, como todo jQuery):

UI de jQuery antes de la 1.10

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

jQuery UI 1.10 o superior

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

Aquí está la misma página de demostración de la interfaz de usuario de jQuery agregando solo el código anterior , solo estamos agregando un controlador al resizeevento de la ventana con .resize(), por lo que desencadena el re-centro en el momento apropiado.

Nick Craver
fuente
gracias, eso se ve genial. Tal vez debería haber dicho que no siempre sé cuál es el ID de mi diálogo, así (¿cómo puedo apuntar a ese 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, botones: botones, ancho: 840, alto: 500}); $ dialog.dialog ('abrir');
Jorre
11
@Jorre - Todos obtienen la misma clase cuando creas un diálogo, para hacerlo genérico puedes hacer esto:, $(".ui-dialog-content").dialog("option", "position", "center");esto buscará cualquier diálogo :)
Nick Craver
3
Desafortunadamente, la respuesta propuesta afecta mal el cambio de tamaño del diálogo. Cuando intenta cambiar su tamaño con el controlador SE, el diálogo cambia de tamaño en los 4 lados.
2
Recomiendo limitar o eliminar los rebotes del evento de cambio de tamaño. He visto a IE7 e IE8 mover el diálogo "fuera" de la ventana gráfica debido a que el controlador de cambio de tamaño se ejecuta demasiadas veces.
BStruthers
2
En las versiones más recientes de la interfaz de usuario de jQuery, necesitaba usar {my: "center", at: "center", of: window} en lugar de "center". Estoy usando 1.11.0.
Mike Dotterer
20

Alternativamente a la respuesta de Ellesedil,

Esa solución no funcionó para mí de inmediato, así que hice lo siguiente, que también es una versión dinámica pero abreviada:

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

+1 para Ellesedil aunque

EDITAR:

Versión mucho más corta que funciona muy bien para diálogos únicos:

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

No es necesario que .each () se use quizás si tiene algunos cuadros de diálogo únicos que no desea tocar.

Pierre
fuente
el uso de la clase .ui-dialog-content es para todos los diálogos, la respuesta aceptada es para un diálogo específico
Pierre
Ah bien. Lo siento. No noté la distinción a primera vista en la edición.
Ellesedil
Estoy usando este enfoque de forma semi-exitosa. Hace lo que se anuncia, pero iOS 7 Mobile Safari realmente se ahoga si el teclado está arriba. Intenté difuminar () la entrada, pero Gingerbread ve el teclado como un evento de cambio de tamaño y se atasca en un bucle que nunca permite la entrada de entrada. ¿Alguien más enfrenta esto?
Joseph Juhnke
Tal vez agregue un contador afuera .resize()y adentro si el contador llega 10o 20entonces break;, no he tenido este problema, no atiendo esos dispositivos / navegadores. Debe probar una solución que, si se atasca, puede salir de ella
Pierre
Tu primera sugerencia funcionó y la respuesta de @Ellesedil no.
Akousmata
13

Aquí puede encontrar una respuesta más completa, que utiliza la respuesta de Nick de una manera más flexible .

A continuación se muestra una adaptación del código de relevancia de ese hilo. Esta extensión esencialmente crea una nueva configuración de diálogo llamada autoReposition que acepta verdadero o falso. El código tal como está escrito establece la opción por defecto en verdadero. Pon esto en un archivo .js en tu proyecto para que tus páginas puedan aprovecharlo.

    $.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'));
            }
        });
    });

Esto le permite proporcionar un "verdadero" o "falso" para esta nueva configuración cuando crea su diálogo en su 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");
            }
        }
    });
});

Ahora, este diálogo siempre se reposicionará. AutoReposition (o como se llame a la configuración) puede manejar cualquier cuadro de diálogo que no tenga una posición predeterminada y reposicionarlos automáticamente cuando la ventana cambia de tamaño. Dado que está configurando esto cuando crea el diálogo, no necesita identificar un diálogo de alguna manera porque la funcionalidad de reposicionamiento se integra en el diálogo mismo. Y la mejor parte es que, dado que esto se establece por diálogo, puede hacer que algunos diálogos se reposicionen y otros permanezcan donde están.

Crédito al usuario scott.gonzalez en los foros de jQuery por la solución completa.

Ellesedil
fuente
Este complemento / edición parece no funcionar más a partir de julio de 2014. La respuesta de @Pierre todavía funciona.
degenerado
@degenerate: Es posible que las actualizaciones de jQuery requieran cambios un poco en la sintaxis. Ya no estoy trabajando ni tengo acceso al proyecto donde implementé esto (en realidad, actualmente estoy escribiendo API), por lo que no tengo una manera fácil de determinar si se necesitan cambios para las versiones recientes de jQuery.
Ellesedil
Esta respuesta no funciona para versiones recientes. Pero la idea es genial. Este es el contenido de mi controlador de cambio de tamaño de ventana: $(".ui-dialog-content:visible").each(function () { if ($(this).dialog('option', 'autoReposition')) { $(this).dialog('option', 'position', $(this).dialog('option', 'position')); } });funciona muy bien :)
nacho4d
@ nacho4d: No dude en editar la respuesta y agregar el código más nuevo para cualquier versión de jquery en la que esté trabajando en la parte inferior.
Ellesedil
1
@Ellesedil Acabo de cambiar un par de líneas en su primer fragmento de código. En realidad, es lo que scott.gonzalez escribió primero en el hilo. No sé por qué cambió $( "#dialog" ).dialog( "option", "position" ) a $(this).data("dialog").options.positionmás tarde. De todos modos, ¡ahora esta respuesta funciona!
nacho4d
2

Otra opción solo de CSS que funciona es esta. Los márgenes negativos deben ser la mitad de su altura y la mitad de su ancho. Entonces, en este caso, mi diálogo tiene 720 px de ancho por 400 px de alto. Esto lo centra vertical y horizontalmente.

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

Alternativamente, se puede usar la posición de la interfaz de usuario de jQuery ,

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

¡Hola a todos!

Solución 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
fuente
$.isVanillaJS == false
Andrew