Wie zentriere ich den jQuery UI-Dialog automatisch, wenn ich die Größe des Browsers ändere?

100

Wenn Sie das Dialogfeld "jquery UI" verwenden, funktioniert alles gut, bis auf eine Sache. Wenn die Größe des Browsers geändert wird, bleibt der Dialog nur in seiner Ausgangsposition, was sehr ärgerlich sein kann.

Sie können es testen unter: http://jqueryui.com/demos/dialog/

Klicken Sie auf das Beispiel "Modaler Dialog" und ändern Sie die Größe Ihres Browsers.

Ich würde gerne in der Lage sein, Dialoge automatisch zentrieren zu lassen, wenn die Größe des Browsers geändert wird. Kann dies für alle meine Dialoge in meiner App auf effiziente Weise durchgeführt werden?

Vielen Dank!

Jorre
quelle

Antworten:

160

Wenn Sie die positionOption festlegen, wird dies erzwungen. Verwenden Sie daher denselben Selektor, der alle Ihre Dialoge abdeckt, die ich #dialoghier verwende (wenn sie nicht gefunden werden, werden keine Aktionen ausgeführt, wie bei allen jQuery-Programmen):

jQuery-Benutzeroberfläche vor 1.10

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

jQuery UI 1.10 oder höher

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

Hier ist dieselbe Demoseite der jQuery-Benutzeroberfläche, auf der nur der obige Code hinzugefügt wird. Wir fügen dem resizeEreignis des Fensters lediglich einen Handler hinzu .resize(), damit die Neuzentrierung zum richtigen Zeitpunkt ausgelöst wird. .

Nick Craver
quelle
danke, das sieht toll aus. Vielleicht hätte ich sagen sollen, dass ich nicht immer weiß, wie die ID meines Dialogs lautet (wie kann ich auf diesen Dialog abzielen?): Var $ dialog = $ ('<div> <a href = "#" title = "Abbrechen"> Abbrechen </a> </a> </ div> ') .html (assetBrowser) .dialog ({autoOpen: false, Titel:' Assets Manager ', modal: true, closeOnEscape: true, Schaltflächen: Knöpfe, Breite: 840, Höhe: 500}); $ dialog.dialog ('open');
Jorre
11
@Jorre - Sie alle erhalten die gleiche Klasse, wenn Sie einen Dialog erstellen. Um ihn generisch zu machen, können Sie dies tun : $(".ui-dialog-content").dialog("option", "position", "center");, dies wird nach jedem Dialog
suchen
3
Leider wirkt sich die vorgeschlagene Antwort auf eine schlechte Größenänderung des Dialogs aus. Wenn Sie versuchen, die Größe mit dem SE-Handle zu ändern, wird die Größe des Dialogfelds auf allen vier Seiten geändert.
2
Ich empfehle, das Größenänderungsereignis zu drosseln oder zu entprellen. Ich habe gesehen, dass IE7 und IE8 den Dialog "außerhalb" des Ansichtsfensters verschoben haben, da der Handler für die Größenänderung zu oft ausgeführt wurde.
BStruthers
2
In neueren Versionen der jQuery-Benutzeroberfläche musste ich {my: "center", at: "center", of: window} anstelle von "center" verwenden. Ich benutze 1.11.0.
Mike Dotterer
20

Alternativ zu Ellesedils Antwort:

Diese Lösung hat bei mir nicht sofort funktioniert, also habe ich Folgendes getan, was ebenfalls eine dynamische, aber verkürzte Version ist:

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

+1 für Ellesedil

BEARBEITEN:

Viel kürzere Version, die sich hervorragend für einzelne Dialoge eignet:

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

Es ist nicht erforderlich, dass .each () verwendet wird, wenn Sie einige eindeutige Dialoge haben, die Sie nicht berühren möchten.

Pierre
quelle
Die Verwendung der Klasse .ui-dialog-content gilt für alle Dialoge. Die akzeptierte Antwort gilt für einen bestimmten Dialog
Pierre
Ah richtig. Es tut uns leid. Ich habe den Unterschied auf den ersten Blick in der Bearbeitung nicht bemerkt.
Ellesedil
Ich benutze diesen Ansatz halb erfolgreich. Es funktioniert wie angekündigt, aber die mobile Safari für iOS 7 verschluckt sich wirklich, wenn die Tastatur aktiv ist. Ich habe versucht, die Eingabe zu verwischen (), aber Gingerbread sieht die Tastatur als Größenänderungsereignis an und bleibt in einer Schleife stecken, die keine Eingabe von Eingaben zulässt. Ist noch jemand damit konfrontiert?
Joseph Juhnke
Vielleicht fügen Sie einen Zähler außerhalb .resize()und innerhalb hinzu, wenn der Zähler erreicht 10oder 20dann break;, ich hatte dieses Problem nicht, ich kümmere mich nicht um diese Geräte / Browser. Sie müssen eine Lösung ausprobieren, die Sie verlassen können, wenn sie nicht weiterkommt
Pierre
Ihr erster Vorschlag funktionierte und @Ellesedils Antwort nicht.
Akousmata
13

Eine umfassendere Antwort, die Nicks Antwort flexibler verwendet, finden Sie hier .

Eine Anpassung des relevanten Codes aus diesem Thread finden Sie unten. Diese Erweiterung erstellt im Wesentlichen eine neue Dialogeinstellung namens autoReposition, die ein wahr oder falsch akzeptiert. Der geschriebene Code ist standardmäßig auf true gesetzt. Fügen Sie dies in eine .js-Datei in Ihrem Projekt ein, damit Ihre Seiten es nutzen können.

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

Auf diese Weise können Sie beim Erstellen Ihres Dialogfelds auf Ihrer Seite ein "wahr" oder "falsch" für diese neue Einstellung angeben.

$(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");
            }
        }
    });
});

Jetzt positioniert sich dieser Dialog immer neu. AutoReposition (oder wie auch immer Sie die Einstellung nennen) kann alle Dialoge verarbeiten, die keine Standardposition haben, und sie automatisch neu positionieren, wenn die Fenstergröße geändert wird. Da Sie dies beim Erstellen des Dialogfelds festlegen, müssen Sie kein Dialogfeld identifizieren, da die Neupositionierungsfunktion in das Dialogfeld selbst integriert wird. Und das Beste daran ist, dass Sie, da dies pro Dialog festgelegt ist, einige Dialoge neu positionieren können und andere dort bleiben, wo sie sind.

Gutschrift an den Benutzer scott.gonzalez in den jQuery-Foren für die vollständige Lösung.

Ellesedil
quelle
Dieses Addon / Edit scheint ab Juli 2014 nicht mehr zu funktionieren. Die Antwort von @Pierre funktioniert immer noch.
entartet
@degenerate: Es ist möglich, dass Aktualisierungen von jQuery Änderungen an der Syntax erforderlich machen. Ich arbeite nicht mehr oder habe nicht einmal Zugriff auf das Projekt, in dem ich dies implementiert habe (derzeit schreibe ich APIs), sodass ich nicht einfach feststellen kann, ob Änderungen für aktuelle jQuery-Versionen erforderlich sind.
Ellesedil
Diese Antwort funktioniert nicht für neuere Versionen. Aber die Idee ist großartig. Dies ist der Inhalt meines Fensters Resize Handler: $(".ui-dialog-content:visible").each(function () { if ($(this).dialog('option', 'autoReposition')) { $(this).dialog('option', 'position', $(this).dialog('option', 'position')); } });Es funktioniert
super
@ nacho4d: Sie können die Antwort jederzeit bearbeiten und den neueren Code für die JQuery-Version, an der Sie arbeiten, unten hinzufügen.
Ellesedil
1
@Ellesedil Ich habe gerade ein paar Zeilen in deinem ersten Codeblock geändert. Eigentlich ist es das, was scott.gonzalez zuerst im Thread geschrieben hat. Ich weiß nicht , warum er sich verändert , $( "#dialog" ).dialog( "option", "position" ) um $(this).data("dialog").options.positionspäter. Wie auch immer, jetzt funktioniert diese Antwort!
Nacho4D
2

Eine andere Nur-CSS-Option, die funktioniert, ist diese. Die negativen Ränder sollten der Hälfte Ihrer Höhe und der Hälfte Ihrer Breite entsprechen. In diesem Fall ist mein Dialogfeld also 720 Pixel breit und 400 Pixel hoch. Dies zentriert es vertikal und horizontal.

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

Alternativ kann die Position jQuery ui verwendet werden.

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

Hallo, alle miteinander!

Vanilla JS-Lösung:

(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
quelle
$.isVanillaJS == false
Andrew