Pozycjonowanie okna dialogowego jQuery UI

116

Próbuję użyć interfejsu użytkownika okna dialogowego jQuery biblioteki w celu umieszczenia okna dialogowego obok tekstu po najechaniu kursorem. Okno dialogowe jQuery przyjmuje parametr pozycji, który jest mierzony od lewego górnego rogu bieżącej rzutni (innymi słowy, [0, 0]zawsze umieszcza go w lewym górnym rogu okna przeglądarki, niezależnie od tego, gdzie jesteś aktualnie przewijany). Jednak jedynym sposobem, w jaki znam, aby pobrać lokalizację, jest element powiązany z CAŁĄ stroną.

Oto, co mam obecnie. position.topoblicza się na około 1200, co umieszcza okno dialogowe znacznie poniżej pozostałej zawartości strony.

$(".mytext").mouseover(function() {
    position = $(this).position();
    $("#dialog").dialog('option', 'position', [position.top, position.left]);
}

Jak mogę znaleźć właściwą pozycję?

Dzięki!

Wickethewok
źródło
2
Od wersji 1.9 istnieje natywny widżet podpowiedzi.
theblang

Odpowiedzi:

13

Sprawdź niektóre wtyczki jQuery dla innych implementacji okna dialogowego. Cluetip wydaje się być bogatą w funkcje wtyczką w stylu podpowiedzi / okien dialogowych. Czwarte demo brzmi podobnie do tego, co próbujesz zrobić (chociaż widzę, że nie ma precyzyjnej opcji pozycjonowania, której szukasz).

Ben Koehler
źródło
Uszkodzony link. Śmiem twierdzić, że ta wtyczka nie jest już obsługiwana. Może mądrze byłoby wybrać inną odpowiedź?
JohnK
109

Alternatywnie możesz użyć narzędzia jQuery UI Position, np

$(".mytext").mouseover(function() {
    var target = $(this);
    $("#dialog").dialog("widget").position({
       my: 'left',
       at: 'right',
       of: target
    });
}
Brian M. Hunt
źródło
29
To jest najlepsze podejście. Zwrócę jednak uwagę, że jeśli tworzysz okno dialogowe po raz pierwszy, będziesz potrzebować dodatkowego połączenia, dialogtakiego jak:$('#dialog').dialog({ width: 300 /* insert your options */ }).dialog('widget').position({ my: 'left', at: 'right', of: $(this) });
wsanville
26
Narzędzie do pozycjonowania interfejsu użytkownika jQuery nie działa na ukrytych elementach, więc musisz otworzyć okno dialogowe przed umieszczeniem go za pomocą tego kodu.
Toadmyster,
1
jQuery UI to najlepszy sposób na zrobienie tego. Scott González szczegółowo wyjaśnia, jak działa interfejs użytkownika jQuery i jak go używać
strangeloops
Uważam za mylące, że np. To musi być: at: 'top+50'zamiastat: 'top + 50'
Lamy
dla każdego, kto boryka się (tak jak ja) z ustawieniem więcej niż jednej pozycji, wygląda to tak: $('dialog').dialog({ position: { my: 'left top', at: 'left+50 top+50'}, });
milpool
81

Dzięki niektórym powyższym odpowiedziom eksperymentowałem i ostatecznie stwierdziłem, że wszystko, co musisz zrobić, to edytować atrybut „pozycja” w definicji okna dialogowego modalnego:

position:['middle',20],

JQuery nie miał problemów z tekstem „środkowym” dla poziomej wartości „X”, a moje okno dialogowe pojawiło się pośrodku, 20 pikseli w dół od góry.

Serce JQuery.

user1288395
źródło
Działa bez dodatkowych wtyczek i jest intuicyjny. Najlepsze rozwiązanie, jakie widziałem.
PlanetUnknown
Fantastycznie proste rozwiązanie, bez dodatkowych wtyczek. To powinna być akceptowana odpowiedź.
kamui
13
Cholera, to miłe, ale jest przestarzałe - „Uwaga: formularze String i Array są przestarzałe”. api.jqueryui.com/dialog/#option-position Więc musiałbyś użyć obiektu pozycji my / at / of thingy. Zobacz łącze o „pozycji jQuery UI Position”. Możesz uzyskać coś takiego jak pozycja: {my: "center top", at: "center top + 20", of: window}, aby działało tak, jak chcesz. Zobacz link po więcej przykładów.
mikato
@mikato ... zgodnie z jquery ui 1.10 pozycja akceptuje ciąg i tablicę. ... ... ale nadal lubię notację obiektową (lubię klawisze).
dsdsdsdsd,
3
Nie mogę uwierzyć, że potrzebujesz tyle kodu, aby umieścić okienko dialogowe.
Gi1ber7
42

Po przeczytaniu wszystkich odpowiedzi, to w końcu zadziałało:

$(".mytext").mouseover(function() {
    var x = jQuery(this).position().left + jQuery(this).outerWidth();
    var y = jQuery(this).position().top - jQuery(document).scrollTop();
    jQuery("#dialog").dialog('option', 'position', [x,y]);
});
Jaymin Patel
źródło
Ta odpowiedź działała dla mnie i prawdopodobnie zaoszczędziła mi wiele minut / godzin na szukanie w Google, jak skonfigurować inne rozwiązania. Dziękuję Ci!
Nathan
1
+1 To bardzo mi pomogło, kiedy zrozumiałem .position () daje względną pozycję i .offset (), bezwzględną pozycję (co mi potrzebne)
daniloquio
16

Idąc krok dalej z przykładem Jaymina, wymyśliłem to, aby umieścić element jQuery ui-dialog nad elementem, który właśnie kliknąłeś (pomyśl „dymek”):

$('#myDialog').dialog( 'open' );
var myDialogX = $(this).position().left - $(this).outerWidth();
var myDialogY = $(this).position().top - ( $(document).scrollTop() + $('.ui-dialog').outerHeight() );
$('#myDialog').dialog( 'option', 'position', [myDialogX, myDialogY] );

Zauważ, że „otwieram” element ui-dialog przed obliczeniem względnych przesunięć szerokości i wysokości. Dzieje się tak dlatego, że jQuery nie może ocenić externalWidth () ani externalHeight () bez fizycznego pojawienia się elementu ui-dialog na stronie.

Po prostu upewnij się, że w opcjach dialogowych ustawiłeś „modalne” na false i powinieneś być OK.

zaznaczone
źródło
1
Myślę, że twoje dwie zmienne miały być myDialogXimyDialogY
casey
16

http://docs.jquery.com/UI/API/1.8/Dialog

Przykład stałego okna dialogowego w lewym górnym rogu:

$("#dialogId").dialog({
    autoOpen: false,
    modal: false,
    draggable: false,
    height: "auto",
    width: "auto",
    resizable: false,
    position: [0,28],
    create: function (event) { $(event.target).parent().css('position', 'fixed');},
    open: function() {
        //$('#object').load...
    }
});

$("#dialogOpener").click(function() {
    $("#dialogId").dialog("open");
});
xhochn
źródło
dla mnie był to najprostszy do naśladowania, tylko atrybut i otrzymujesz rozwiązanie. Nie wiedziałem, że można wspomnieć o „pozycji” za pomocą tej składni nawiasów kwadratowych wraz z wysokością / szerokością itp.
user734028
nie mam pojęcia, jest zbyt dawno temu: D
xhochn
15

Sprawdź swój <!DOCTYPE html>

Zauważyłem, że jeśli przegapisz <!DOCTYPE html> od początku pliku HTML, okno dialogowe jest wyświetlane pośrodku treści dokumentu, a nie w oknie, nawet jeśli określisz pozycję: {my: 'center', at: 'center' , z: okno}

Np . : http://jsfiddle.net/npbx4561/ - Skopiuj zawartość z okna uruchamiania i usuń DocType. Zapisz jako HTML i uruchom, aby zobaczyć problem.

Daniel Flippance
źródło
2
To był dokładnie ten problem, który miałem, i to go rozwiązało.
BobRodes
1
Moja transformacja xml nie mogła dodać doctype, ta odpowiedź wraz z: stackoverflow.com/questions/3387127/set-html5-doctype-with-xslt sprawiła, że wszystko się toczyło.
Daniel Bower
1
Życzę więcej niż jednego głosu za tę wspaniałą odpowiedź. Naprawiło mój problem, z którym walczyłem godzinami.
Dr DS
10

Aby uzyskać pełną kontrolę, możesz użyć tego kodu:

    $("#dialog-edit").dialog({
...    
        position: { 
            my: 'top',
            at: 'top',
            of: $('#myControl')
        },

...
    });
miłość na żywo
źródło
7
$(".mytext").mouseover(function() {
   var width = 250;
   var height = 270;
   var posX = $(this).offset().left - $(document).scrollLeft() - width + $(this).outerWidth();
   var posY = $(this).offset().top - $(document).scrollTop() + $(this).outerHeight();
   $("#dialog").dialog({width:width, height:height ,position:[posX, posY]});
}

Umieszcza okno dialogowe tuż pod elementem. Użyłem funkcji offset () tylko dlatego, że oblicza ona pozycję względem lewego górnego rogu przeglądarki, ale funkcja position () oblicza pozycję względem nadrzędnego elementu div lub iframe tego rodzica elementu.

M. Belen
źródło
6

zamiast robić jquery, zrobiłbym:

$(".mytext").mouseover(function() {
    x= $(this).position().left - document.scrollLeft
    y= $(this).position().top - document.scrollTop
    $("#dialog").dialog('option', 'position', [y, x]);
}

jeśli dobrze rozumiem twoje pytanie, kod, który masz, ustawia okno dialogowe tak, jakby strona nie miała przewijania, ale chcesz, aby uwzględniało przewijanie. mój kod powinien to zrobić.

Samuel
źródło
Z jakiegoś powodu document.scrollleft jest dla mnie niezdefiniowana.
Wickethewok
2
mój błąd, jego scrollLeft scrollTop zapomniał kapitalizować
Samuel
var x = el.position (). left + el.outerWidth (); var y = el.position (). top - $ (dokument) .scrollTop (); pracował dla mnie. Problem polega na tym, że nie mogę uzyskać wysokości i szerokości okna dialogowego po zmianie informacji w nim.
rball
4

Ta strona pokazuje, jak określić przesunięcie przewijania. jQuery może mieć podobną funkcjonalność, ale nie mogłem go znaleźć. Używając funkcji getScrollXY pokazanej na stronie, powinieneś być w stanie odjąć współrzędne x i y od wyników .position ().

Philip Tinney
źródło
4

trochę za późno, ale możesz to zrobić teraz, używając odpowiednio $ j (obiekt) .offset (). left i .top.

user363690
źródło
4

Nie sądzę, żeby bańka mowy była całkiem poprawna. Poprawiłem go trochę, aby działał, a element otwiera się tuż pod linkiem.

function PositionDialog(link) {
    $('#myDialog').dialog('open');
    var myDialogX = $(link).position().left;
    var myDialogY = $(link).position().top + $(link).outerHeight();
    $('#myDialog').dialog('option', 'position', [myDialogX, myDialogY]);
}
Klif
źródło
3

Aby naprawić pozycję środkową, używam:

open : function() {
    var t = $(this).parent(), w = window;
    t.offset({
        top: (w.height() / 2) - (t.height() / 2),
        left: (w.width() / 2) - (t.width() / 2)
    });
}
Eduardo Cuomo
źródło
3

Oto kod ..., jak ustawić okno dialogowe jQuery UI na środku ......

var $about = $("#about");

   $("#about_button").click(function() {
      $about.dialog({
         modal: true,
         title: "About the calendar",
         width: 600,         
         close: function() {
            $about.dialog("destroy");
            $about.hide();
         },
         buttons: {
            close : function() {
               $about.dialog("close");
            }
         }
      }).show();

      $about.dialog("option", "position", 'center');

   });
Manu RS
źródło
3
$("#myid").dialog({height:"auto",
        width:"auto",
        show: {effect: 'fade', speed: 1000},
        hide: {effect: 'fade', speed: 1000},
        open: function( event, ui ) {
          $("#myid").closest("div[role='dialog']").css({top:100,left:100});              
         }
    });
Günes Erdemi
źródło
2

możesz użyć $(this).offset(), pozycja jest związana z rodzicem

neil tang
źródło
2

Wypróbowałem wszystkie proponowane rozwiązania, ale nie zadziałają, ponieważ okno dialogowe nie jest częścią głównego dokumentu i będzie miało własną warstwę (ale to moje wyuczone przypuszczenie).

  1. Zainicjuj okno dialogowe za pomocą $("#dialog").dialog("option", "position", 'top')
  2. Otwórz za pomocą $(dialog).dialog("open");
  3. Następnie pobierz x i y wyświetlonego okna dialogowego (nie innego węzła dokumentu!)

    var xcoord = $(dialog).position().left + ADD_MODIFIER_FOR_X_HERE;

    var ycoord= $(dialog).position().top + ADD_MODIFIER_FOR_Y_HERE;

    $(dialog).dialog('option', 'position', [xcoord , ycoord]);

W ten sposób współrzędne pochodzą z okna dialogowego, a nie z dokumentu, a pozycja jest zmieniana zgodnie z warstwą okna.

Panie Mountain
źródło
1

Próbowałem na wiele sposobów, aby moje okno dialogowe było wyśrodkowane na stronie i zobaczyłem, że kod:

$("#dialog").dialog("option", "position", 'top')

nigdy nie zmieniaj pozycji okna dialogowego, kiedy zostało utworzone.

Zamiast tego zmieniam poziom selektora, aby uzyskać całe okno dialogowe.

$("#dialog").parent() <- To jest obiekt nadrzędny, który funkcja dialog () tworzy w DOM, dzieje się tak, ponieważ selektor $ ("# dialog") nie stosuje atrybutów, góra, lewo.

Aby wyśrodkować okno dialogowe, używam wtyczki jQuery-Client-Centering-Plugin

$ ("# dialog"). parent (). centerInClient ();

jmozko
źródło
1

powyższe rozwiązania są bardzo prawdziwe ... ale okno dialogowe interfejsu użytkownika nie zachowuje pozycji po zmianie rozmiaru okna. poniższy kod to robi

            $(document).ready(function(){

                $(".test").click(function(){
                            var posX = $(".test").offset().left - $(document).scrollLeft() + $(".test").outerWidth();
                            var posY = $(".test").offset().top - $(document).scrollTop() + $(".test").outerHeight();
                            console.log("in click function");
                            $(".abc").dialog({
                                position:[posX,posY]
                            });

                        })

            })

            $(window).resize(function(){
                var posX=$(".test").offset().left - $(document).scrollLeft() + $(".test").outerWidth();
                var posY = $(".test").offset().top - $(document).scrollTop() + $(".test").outerHeight();

            $(".abc").dialog({
                                position:[posX,posY]
                            });
            })
Kaustubh - KAY
źródło
0

Możesz ustawić najwyższą pozycję w stylu do wyświetlania na środku, zobaczyłeś, że kod:

.ui-dialog {góra: 100px! ważne;}

Ten styl powinien pokazywać okno dialogowe 100 pikseli poniżej od góry.

sanjay jangid
źródło