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's 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 对盒子做了什么,因为它隐藏了它(除了显示:无)或让它滑入,所以也许我在这里遗漏了一些可能有帮助的东西......

基本上,我需要 JQuery 记住盒子的位置,并在重新打开时将盒子放回该位置。

我花了几天时间才做到这一点,但这是我尚未克服的障碍之一。

也许我可以用不同的方式重新打开盒子?

谢谢!

编辑:

忘记了——这个问题只发生在我使用我的 UpdatePos 函数来设置框的位置时(即在页面加载时)。当我用鼠标拖动一个框,将其关闭并重新打开时,一切正常。所以我猜还有一个我在这里缺少的盒子位置的存储位置......

编辑2:

在更混乱之后,我的调试代码现在看起来像这样:

        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()不变。

也许这会帮助这里的人 - 我在这里仍然没有想法......

...我刚刚发现,当我在自己周围拖动项目,然后关闭并重新打开它时,这是非常不可预测的。有时,它会水平地到达正确的位置,但不是垂直地。有时,它最终会回到屏幕中央......

编辑3:

所以这是一个 jsfiddle 版本:

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

4

1 回答 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:-) 所以我想我不会再弄清楚为什么我的疯狂想法使用此功能并没有做我想要它做的事情(以及它可能从未设计过的事情)并找到另一种方法来获得相同的效果 - 这很有效。

再次感谢您的关注!

于 2013-10-24T19:29:28.670 回答