Jak automatycznie wyśrodkować okno dialogowe interfejsu użytkownika jQuery podczas zmiany rozmiaru przeglądarki?

101

Kiedy używasz okna dialogowego jquery UI, wszystko działa dobrze, z wyjątkiem jednej rzeczy. Po zmianie rozmiaru przeglądarki okno dialogowe pozostaje w początkowej pozycji, co może być naprawdę denerwujące.

Możesz to przetestować na: http://jqueryui.com/demos/dialog/

Kliknij przykład „modalnego okna dialogowego” i zmień rozmiar przeglądarki.

Chciałbym móc automatycznie wyśrodkować okna dialogowe przy zmianie rozmiaru przeglądarki. Czy można to zrobić w efektywny sposób dla wszystkich okien dialogowych w mojej aplikacji?

Wielkie dzięki!

Jorre
źródło

Odpowiedzi:

161

Ustawienie tej positionopcji wymusi to, więc po prostu użyj tego samego selektora obejmującego wszystkie okna dialogowe, których #dialogtutaj używam (jeśli ich nie znajdzie, nie zostanie podjęta żadna akcja, jak wszystkie jQuery):

jQuery UI przed 1.10

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

jQuery UI 1.10 lub nowszy

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

Oto ta sama strona demonstracyjna interfejsu użytkownika jQuery, która dodaje tylko powyższy kod , po prostu dodajemy procedurę obsługi do resizezdarzenia okna za pomocą .resize(), więc wyzwala ponowne wyśrodkowanie w odpowiednim czasie. Wcześniejsze

Nick Craver
źródło
dzięki, wygląda świetnie. Może powinienem był powiedzieć, że nie zawsze wiem jaki jest identyfikator mojego okna dialogowego, na przykład (jak mogę ustawić kierowanie na to okno dialogowe?): Var $ dialog = $ ('<div> <a href = "#" title = "Anuluj"> Anuluj </a> </a> </div> ') .html (assetBrowser) .dialog ({autoOpen: false, title:' Menedżer zasobów ', modal: true, closeOnEscape: true, przyciski: przyciski, szer. 840, wys. 500}); $ dialog.dialog ('open');
Jorre
11
@Jorre - Wszystkie mają tę samą klasę podczas tworzenia okna dialogowego, aby uczynić go ogólnym, możesz zrobić to:, $(".ui-dialog-content").dialog("option", "position", "center");to sprawdzi każde okno dialogowe :)
Nick Craver
3
Niestety proponowana odpowiedź źle wpływa na zmianę rozmiaru okna. Kiedy spróbujesz zmienić jego rozmiar za pomocą uchwytu SE, okno dialogowe zostanie zmienione ze wszystkich 4 stron.
2
Zalecam ograniczanie lub usuwanie zdarzenia zmiany rozmiaru. Widziałem, jak IE7 i IE8 przesuwały okno dialogowe „poza” widok z powodu zbyt częstego wykonywania funkcji obsługi zmiany rozmiaru.
BStruthers
2
W nowszych wersjach interfejsu użytkownika jQuery potrzebowałem użyć {my: "center", at: "center", of: window} zamiast "center". Używam 1.11.0.
Mike Dotterer
20

Alternatywnie do odpowiedzi Ellesedila,

To rozwiązanie nie zadziałało u mnie od razu, więc zrobiłem następującą wersję, która również jest dynamiczna, ale skrócona:

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

Jednak +1 dla Ellesedila

EDYTOWAĆ:

Znacznie krótsza wersja, która świetnie sprawdza się w pojedynczych dialogach:

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

Nie jest konieczne używanie .each (), jeśli masz jakieś unikalne okna dialogowe, których nie chcesz dotykać.

Pierre
źródło
używając klasy .ui-dialog-content dotyczy wszystkich okien dialogowych, akceptowana odpowiedź dotyczy konkretnego okna dialogowego
Pierre
Ah, tak. Przepraszam. Na pierwszy rzut oka nie zauważyłem rozróżnienia w edycji.
Ellesedil
Używam tego podejścia częściowo skutecznie. Działa zgodnie z reklamą, ale mobilne safari na iOS 7 naprawdę dusi, jeśli klawiatura jest włączona. Próbowałem zamazać () dane wejściowe, ale Gingerbread widzi klawiaturę jako zdarzenie zmiany rozmiaru i utknie w pętli, która nigdy nie pozwala na wejście. Czy ktoś jeszcze się z tym mierzy?
Joseph Juhnke
Może dodaj licznik na zewnątrz .resize()i wewnątrz, jeśli licznik osiągnie 10lub 20wtedy break;, nie miałem tego problemu, nie obsługuję tych urządzeń / przeglądarek. Musisz wypróbować rozwiązanie, które jeśli utknie, możesz się z niego wydostać
Pierre,
Twoja pierwsza sugestia zadziałała, a odpowiedź @Ellesedil nie.
akousmata
13

Bardziej wyczerpującą odpowiedź, która wykorzystuje odpowiedź Nicka w bardziej elastyczny sposób, można znaleźć tutaj .

Poniżej znajduje się adaptacja odpowiedniego kodu z tego wątku. To rozszerzenie zasadniczo tworzy nowe ustawienie okna dialogowego o nazwie autoReposition, które akceptuje wartość true lub false. Kod w postaci zapisanej domyślnie przyjmuje wartość true. Umieść to w pliku .js w swoim projekcie, aby Twoje strony mogły to wykorzystać.

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

Umożliwia to podanie wartości „prawda” lub „fałsz” dla tego nowego ustawienia podczas tworzenia okna dialogowego na stronie.

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

Teraz to okno dialogowe zawsze będzie się zmieniać. AutoReposition (lub jakkolwiek nazywasz to ustawienie) może obsłużyć wszystkie okna dialogowe, które nie mają domyślnej pozycji i automatycznie zmienić ich położenie, gdy okno zmieni rozmiar. Ponieważ ustawiasz to podczas tworzenia okna dialogowego, nie musisz w jakiś sposób identyfikować okna dialogowego, ponieważ funkcja zmiany położenia zostaje wbudowana w samo okno dialogowe. A najlepsze jest to, że ponieważ jest to ustawiane w oknie dialogowym, możesz zmienić położenie niektórych dialogów, a inne pozostać na swoim miejscu.

Podziękowania dla użytkownika scott.gonzalez na forach jQuery za kompletne rozwiązanie.

Ellesedil
źródło
Ten dodatek / edycja nie wydaje się już działać od lipca 2014. Odpowiedź od @Pierre nadal działa.
zdegenerowany
@degenerate: Możliwe, że aktualizacje jQuery mogą wymagać nieco zmian w składni. Nie pracuję już ani nawet nie mam dostępu do projektu, w którym to zaimplementowałem (obecnie piszę API), więc nie mam łatwego sposobu na określenie, czy potrzebne są jakieś zmiany w ostatnich wersjach jQuery.
Ellesedil,
Ta odpowiedź nie działa w przypadku najnowszych wersji. Ale pomysł jest świetny. To jest zawartość mojego programu do zmiany rozmiaru okna: $(".ui-dialog-content:visible").each(function () { if ($(this).dialog('option', 'autoReposition')) { $(this).dialog('option', 'position', $(this).dialog('option', 'position')); } });Działa świetnie :)
nacho4d
@ nacho4d: Możesz edytować odpowiedź i dodać do dołu nowszy kod dla dowolnej wersji jquery, w której pracujesz.
Ellesedil,
1
@Ellesedil Właśnie zmieniłem kilka linii w Twoim pierwszym fragmencie kodu. Właściwie to właśnie scott.gonzalez napisał jako pierwszy w wątku. Nie wiem, dlaczego zmienił się $( "#dialog" ).dialog( "option", "position" ) na $(this).data("dialog").options.positionpóźniej. W każdym razie, teraz ta odpowiedź działa!
nacho4d
2

Inną działającą tylko opcją CSS jest ta. Ujemne marginesy powinny równać się połowie wysokości i połowie szerokości. W tym przypadku moje okno dialogowe ma szerokość 720 pikseli i wysokość 400 pikseli. Powoduje to wyśrodkowanie go w pionie i poziomie.

.ui-dialog {
  top:50% !important;
  margin-top:-200px !important; 
  left:50% !important;
  margin-left:-360px !important
}
Kirk Ross
źródło
2

Alternatywnie można użyć pozycji jQuery ui ,

$(window).resize(function ()
{
    $(".ui-dialog").position({
        my: "center", at: "center", of: window
    });
});
AkilaI
źródło
0

Cześć wszystkim!

Rozwiązanie 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
źródło
$.isVanillaJS == false
Andrew,