Повторное открытие закрытого диалога переводит его в исходное положение после перемещения

0

Я использую несколько экземпляров диалогового окна JQuery-UI, а также перетаскиваемый и изменяемый размер. Всякий раз, когда я перетаскиваю или изменяю размер одного из диалоговых окон, позиция и размеры текущего окна сохраняются в базе данных, а затем загружаются при следующем открытии страницы.

Это хорошо работает.

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

Я нашел два способа обновить свое положение, когда слайд в анимации сделан, однако он все еще скользит в центр экрана, и мне еще предстоит найти способ заставить его скользить в направлении местоположения, которое, как предполагается, должно быть,

Вот часть кода, который играет определенную роль в этом:

    $('.box').dialog({
        closeOnEscape: false,
        hide: { effect: "drop", direction: 'left' },
        beforeClose: function (evt, ui){
            var $this = $(this);

            SavePos($this);  // saves the dimensions to db
        },
        dragStop: function()
        {
            var $this = $(this);

            SavePos($this);
        },
        resizeStop: function()
        {
            var $this = $(this);

            SavePos($this);
        },
        open: function()
        {
            var $this = $(this);
            $this.dialog('option', { show: { effect: "drop", direction: 'left'} } );
            if (init)  // meaning only load this code when the page has finished initializing
            {
                // tried it both ways - set the position before and after the effect - no success
                UpdatePos($this.attr('id')); 
                // I tried this section with promise() and effect / complete - I found no difference
                $this.parent().promise().done(function() {
                    UpdatePos($this.attr('id')); 
                });
            }
        }
    });

function UpdatePos(key)
{
    // boxpos is an object holding the position for each box by the box id
    var $this = $('#' + key);
    //console.log('updating pos for box ' + boxid);
    if ($this && $this.hasClass('ui-dialog-content'))
    {
        //console.log($this.dialog('widget').css('left'));
        $this.dialog('option', { width: boxpos[key].width, height: boxpos[key].height });
        $this.dialog('widget').css({ left: boxpos[key].left + 'px', top: boxpos[key].top + 'px' });
        //console.log('finished updating pos');
        //console.log($this.dialog('widget').css('left'));
    }
}

Кнопка, которая снова открывает окно, имеет этот код, чтобы это произошло:

var $box = $('#boxid');
if ($box)
{
    if ($box.dialog('isOpen'))
    {
        $box.dialog('moveToTop');
    }
    else
    {
        $box.dialog("open")
    }
}

Я не знаю, что делает jQuery-UI, когда он скрывает его (кроме отображения: none), или чтобы он скользил, поэтому, возможно, там что-то мне не хватает, что может помочь...

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

Мне потребовались дни, чтобы сделать это так далеко, но это одно препятствие, которое мне еще предстоит преодолеть.

Может быть, есть другой способ, которым я могу снова открыть коробку?

Благодарю!

РЕДАКТИРОВАТЬ:

Забыт - эта проблема ТОЛЬКО случается, когда я использую свою функцию UpdatePos для установки местоположения поля (то есть на загрузку страницы). Когда я перетаскиваю ящик с помощью мыши, закрываю его и снова открываю, все работает. Так что я догадываюсь, что есть еще одно место для хранения позиции в ящике, которую я здесь отсутствует...

EDIT2:

После более беспорядочного использования мой код для отладки теперь выглядит следующим образом:

        open: function()
        {
            var $this = $(this);
    console.log('box open');
    console.log($this.dialog('widget').position());  // { top=0, left=-78.5}
    console.log($this.dialog('widget').css('left'));
            $this.dialog('option', { show: { effect: "drop", direction: 'left'} } );
            if (init)
            {
                UpdatePos($this.attr('id')); 
                $this.parent().promise().done(function() {
    console.log($this.dialog('widget').position());  // { top=313, left=641.5}
    console.log($this.dialog('widget').css('left'));
                    UpdatePos($this.attr('id')); 
    console.log($this.dialog('widget').position());  // { top=121, left=107}
    console.log($this.dialog('widget').css('left'));
                });
            }

Результаты, которые я получаю:

box open
Object { top=0, left=-78.5}
-78.5px
Object { top=313, left=641.5}
641.5px
Object { top=121, left=107}
107px

Поэтому мне кажется, что виджет перемещается с экрана (слева = -78.5), а затем перемещается для анимации, а затем мой код перемещает его в место, в котором он должен находиться (121/107).

Результат position() для $box.position() или $box.dialog().position() не изменяется во время этой секции отладки.

Может быть, это поможет кому-то здесь - у меня все еще нет идей...

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

EDIT3:

Итак, здесь версия jsfiddle:

http://jsfiddle.net/semmelbroesel/KFqvt/

  • 0
    Можете ли вы создать скрипку, демонстрирующую эту проблему?
  • 0
    Большая часть кода создается на основе данных базы данных в PHP, поэтому потребуется некоторая работа и упрощение, и я заканчиваю свой рабочий день, но утром я что-то создам.
Показать ещё 8 комментариев
Теги:

1 ответ

0
Лучший ответ

Спасибо всем, кто посмотрел, но я нашел обходное решение.

Вместо использования встроенного drop я решил попробовать это вручную, используя animate где у меня больше контроля. Поэтому соответствующий код теперь таков:

    $('.box').dialog({
        // REMOVED: hide: { effect: "drop", direction: 'left' },
        beforeClose: function (evt, ui){
            var $this = $(this);

            SavePos($this);

            $this.dialog('option', 'position', [ parseInt(boxpos[$this.attr('id')].left), parseInt(boxpos[$this.attr('id')].top) ]);

            $this.dialog('widget').animate({
                left: -$this.dialog('option', 'width') + 'px',
                opacity: 0
            }, 200, function(){
                // animation complete
            });
        },
        open: function()
        {
            var $this = $(this);
            // REMOVED: $this.dialog('option', { show: { effect: "drop", direction: 'left'} } );
            if (init)
            {
                UpdatePos($this.attr('id')); 
                $this.parent().promise().done(function() {
                    UpdatePos($this.attr('id')); 
                });
            }

            var thisLeft = $this.dialog('widget').css('left');
            $this.dialog('widget').css({
                'left': -$this.dialog('option', 'width') + 'px',
                'opacity': 0
            });
            $this.dialog('widget').animate({
                left: thisLeft,
                opacity: 1
            }, 200, function(){
                // animation complete
            });
        }
    });

Используя это, я теперь настраиваю начальное и конечное положение для слайда и эффекта слайда, и теперь он работает хорошо.

Я все еще не уверен, что такое исходная проблема, но она, похоже, связана с $box.dialog('option', 'position'). Я просто напишу свои выводы здесь, если кто-то найдет их интересными.

По умолчанию позиция {}. Если это так, jquery принимает значение по умолчанию { my: "center", at: "center", of: window }.

Хотя в документации утверждается, что установка позиции на координаты x/y с использованием массива устарела, я заметил, что когда я перетаскиваю поле, position внезапно появляется как нечто вроде [107, 250].

Когда я попытался установить position вручную перед открытием, мои записи в console.log показали, что position сначала вернулась к {} (которая переводится в "центр экрана"), затем анимирует, а затем возвращает ее обратно в координаты...

Я не знаю, что здесь происходит на заднем плане, и я очень хорошо знаю, как "оскорбительный" мой код относится к оригинальным мыслям за dialog :-) Поэтому я решил, что перестану понимать, почему моя сумасшедшая идея использования этой функции не делает то, что я хочу, чтобы она делала (и то, что она, вероятно, никогда не предназначалась) и находила другой способ получить тот же эффект - который сработал.

Еще раз спасибо за то, что посмотрели!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню