Позиционирование диалогового окна пользовательского интерфейса jQuery

116

Я пытаюсь использовать библиотеку пользовательского интерфейса диалогового окна jQuery , чтобы разместить диалог рядом с некоторым текстом, когда он наведен. Диалог jQuery принимает параметр позиции, который измеряется от верхнего левого угла текущего окна просмотра (другими словами,[0, 0] окна всегда помещает его в верхний левый угол окна вашего браузера, независимо от того, где вы в данный момент прокручены). Однако единственный известный мне способ получить местоположение - это элемент относительно ВСЕЙ страницы.

Вот что у меня есть сейчас. position.topрассчитывается как примерно 1200, что помещает диалоговое окно значительно ниже остального содержимого на странице.

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

Как мне найти правильную позицию?

Спасибо!

Wickethewok
источник
2
Начиная с версии 1.9 существует встроенный виджет всплывающей подсказки.
theblang

Ответы:

13

Ознакомьтесь с некоторыми плагинами jQuery для других реализаций диалогового окна. Cluetip выглядит как многофункциональный плагин в стиле всплывающих подсказок / диалогов. Четвертая демонстрация похожа на то, что вы пытаетесь сделать (хотя я вижу, что у нее нет точного варианта позиционирования, который вы ищете).

Бен Келер
источник
Неработающей ссылке. Я полагаю, этот плагин больше не поддерживается. Может быть, стоит выбрать другой ответ?
JohnK,
109

В качестве альтернативы вы можете использовать утилиту jQuery UI,Position например

$(".mytext").mouseover(function() {
    var target = $(this);
    $("#dialog").dialog("widget").position({
       my: 'left',
       at: 'right',
       of: target
    });
}
Брайан М. Хант
источник
29
Это лучший подход. Замечу, однако, что если вы создаете диалог впервые, вам понадобится дополнительный вызов, dialogнапример:$('#dialog').dialog({ width: 300 /* insert your options */ }).dialog('widget').position({ my: 'left', at: 'right', of: $(this) });
wsanville
26
Утилита позиционирования пользовательского интерфейса jQuery не работает со скрытыми элементами, поэтому вы должны открыть диалоговое окно, прежде чем размещать его с помощью этого кода.
Toadmyster
1
jQuery UI - лучший способ сделать это. У Скотта Гонсалеса есть подробное объяснение того, как работает пользовательский интерфейс jQuery и как его использовать
Strangeloops
Меня сбивает с толку то, что, например, это должно быть: at: 'top+50'вместоat: 'top + 50'
Lamy
для всех, кто борется (как я только что был) с тем, как установить более одной позиции, это примерно так: $('dialog').dialog({ position: { my: 'left top', at: 'left+50 top+50'}, });
milpool
81

Благодаря некоторым ответам, приведенным выше, я поэкспериментировал и в конечном итоге обнаружил, что все, что вам нужно сделать, это отредактировать атрибут "position" в определении модального диалога:

position:['middle',20],

У JQuery не было проблем с «средним» текстом для горизонтального значения «X», и мой диалог появлялся посередине, на 20 пикселей вниз от вершины.

Я болею за JQuery.

user1288395
источник
Работает без дополнительных плагинов и интуитивно понятен. Лучшее решение, которое я видел.
PlanetUnknown
Фантастически простое решение без дополнительных плагинов. Это должен быть принятый ответ.
kamui
13
Черт, это хорошо, но это устарело - «Примечание: формы String и Array устарели». api.jqueryui.com/dialog/#option-position Итак, вам нужно будет использовать объект позиции my / at / of thingy. См. Ссылку о «Положение пользовательского интерфейса jQuery». Вы можете получить что-то вроде position: {my: "center top", at: "center top + 20", of: window}, чтобы работать так, как вы хотите. См. Ссылку для получения дополнительных примеров.
mikato
@mikato ... согласно jquery ui 1.10 позиция принимает строку и массив. ... ... но мне все еще нравится объектная нотация (мне нравятся клавиши).
dsdsdsdsd
3
Я не могу поверить, что вам нужно столько кода, чтобы разместить всплывающее диалоговое окно.
Gi1ber7
42

После прочтения всех ответов это, наконец, сработало для меня:

$(".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]);
});
Джаймин Патель
источник
Этот ответ сработал для меня и сэкономил мне, вероятно, много минут / часов поиска в Google, как настроить другие решения. Спасибо!
Натан
1
+1 Мне очень помогло, когда я понял .position () дает относительное положение, а .offset () - абсолютное положение (что мне было нужно)
daniloquio
16

Взяв пример Джаймина еще дальше, я придумал следующее для размещения элемента пользовательского диалога jQuery над элементом, который вы только что щелкнули (подумайте о «речевом пузыре»):

$('#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] );

Обратите внимание, что я «открываю» элемент ui-dialog перед вычислением смещения относительной ширины и высоты. Это связано с тем, что jQuery не может оценивать externalWidth () или outerHeight () без физического отображения элемента ui-dialog на странице.

Просто убедитесь, что для параметра 'modal' установлено значение false в параметрах диалогового окна, и вы должны быть в порядке.

размечена
источник
1
Я думаю, что ваши две переменные должны быть myDialogXиmyDialogY
Кейси
16

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

Пример фиксированного диалога в левом верхнем углу:

$("#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
источник
для меня это было проще всего, просто атрибут, и вы получите решение. Я не знал, что в этом синтаксисе квадратных скобок может быть упомянута «позиция» вместе с высотой / шириной и т.д.
user734028
Понятия
15

Проверьте свои <!DOCTYPE html>

Я заметил, что если вы пропустите <!DOCTYPE html> вашего HTML-файла, диалоговое окно будет отображаться по центру содержимого документа, а не в окне, даже если вы укажете позицию: {my: 'center', at: 'center' , of: window}

Например: http://jsfiddle.net/npbx4561/ - Скопируйте содержимое из окна выполнения и удалите DocType. Сохраните как HTML и запустите, чтобы увидеть проблему.

Дэниел Флиппанс
источник
2
Это была именно та проблема, с которой я столкнулся, и это решило ее.
BobRodes,
1
Моему преобразованию xml не удалось добавить doctype, этот ответ вместе с: stackoverflow.com/questions/3387127/set-html5-doctype-with-xslt заставил меня работать .
Дэниел Бауэр
1
Я желаю более одного голоса за этот отличный ответ. Это устранило мою проблему, с которой я боролся часами.
Dr. DS
10

Чтобы поставить это прямо поверх управления, вы можете использовать этот код:

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

...
    });
живи любя
источник
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]});
}

Помещает диалог прямо под элементом. Я использовал функцию offset () только потому, что она вычисляет позицию относительно верхнего левого угла браузера, но функция position () вычисляет позицию относительно родительского div или iframe этого родительского элемента.

М. Белен
источник
6

вместо того, чтобы делать чистый jquery, я бы сделал:

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

Если я правильно понимаю ваш вопрос, код, который у вас есть, позиционирует диалог, как если бы на странице не было прокрутки, но вы хотите, чтобы он учитывал прокрутку. мой код должен это делать.

Самуил
источник
По какой-то причине document.scrollleft для меня не определен.
Wickethewok,
2
мой плохой, его scrollLeft scrollTop забыл использовать заглавные буквы
Samuel
var x = el.position (). влево + el.outerWidth (); var y = el.position (). top - $ (документ) .scrollTop (); работал у меня. Проблема в том, что я не могу получить высоту и ширину диалогового окна после изменения информации в нем.
rball
4

На этой странице показано, как определить смещение прокрутки. jQuery может иметь аналогичную функциональность, но я не смог ее найти. Используя функцию getScrollXY, показанную на странице, вы сможете вычесть координаты x и y из результатов .position ().

Филип Тинни
источник
4

немного поздно, но вы можете сделать это сейчас, используя $ j (object) .offset (). left и .top соответственно.

user363690
источник
4

Я не думаю, что речевой пузырь совсем правильный. Я немного подправил его, чтобы он работал и элемент открывался прямо под ссылкой.

function PositionDialog(link) {
    $('#myDialog').dialog('open');
    var myDialogX = $(link).position().left;
    var myDialogY = $(link).position().top + $(link).outerHeight();
    $('#myDialog').dialog('option', 'position', [myDialogX, myDialogY]);
}
утес
источник
3

Чтобы зафиксировать центральное положение, я использую:

open : function() {
    var t = $(this).parent(), w = window;
    t.offset({
        top: (w.height() / 2) - (t.height() / 2),
        left: (w.width() / 2) - (t.width() / 2)
    });
}
Эдуардо Куомо
источник
3

Вот код .., как расположить диалоговое окно jQuery UI по центру ......

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');

   });
Ману RS
источник
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});              
         }
    });
Гюнес Эрдеми
источник
2

вы можете использовать $(this).offset(), позиция связана с родителем

Нил Тан
источник
2

Я пробовал все предложенные решения, но они не работают, потому что диалог не является частью основного документа и будет иметь свой собственный слой (но это мое обоснованное предположение).

  1. Инициализируйте диалог с помощью $("#dialog").dialog("option", "position", 'top')
  2. Откройте это с помощью $(dialog).dialog("open");
  3. Затем получите x и y отображаемого диалогового окна (а не любой другой узел документа!)

    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]);

Таким образом, координаты взяты из диалогового окна, а не из документа, и положение изменяется в соответствии со слоем диалогового окна.

Mr.Mountain
источник
1

Я пробовал разными способами расположить мой диалог по центру страницы и увидел, что код:

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

никогда не меняйте позицию диалога, когда он был создан.

Вместо этого я изменяю уровень селектора, чтобы получить весь диалог.

$("#dialog").parent() <- Это родительский объект, который функция dialog () создает в DOM, это потому, что селектор $ ("# dialog") не применяет атрибуты, вверху, слева.

Чтобы центрировать свой диалог, я использую центрировать плагин jQuery-Client-Centering-Plugin

$ ( "# Диалог") родителя () centerInClient ()..;

jmozko
источник
1

приведенные выше решения очень верны ... но диалоговое окно пользовательского интерфейса не сохраняет позицию после изменения размера окна. ниже код делает это

            $(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]
                            });
            })
Каустубх - КАЙ
источник
0

Вы можете установить верхнюю позицию в стиле для отображения по центру, увидев, что код:

.ui-dialog {top: 100px! important;}

Этот стиль должен отображать диалоговое окно на 100 пикселей ниже сверху.

Санджай Джангид
источник