重新打开关闭对话框后,将其置于开始位置

时间:2013-10-23 21:19:40

标签: jquery jquery-ui

我正在使用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对盒子做了什么,因为它隐藏了它(除了display:none)或者让它滑入,所以也许我在这里找不到可能有帮助的东西... < / p>

基本上,我需要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)。 / p>

$box.position()$box.dialog().position()的position()结果在此调试部分期间不会更改。

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

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

EDIT3:

所以这是一个jsfiddle版本:

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

1 个答案:

答案 0 :(得分: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背后的原始想法:-)所以我认为我是停止搞清楚为什么我疯狂使用这个功能的想法并没有做我想做的事情(以及它可能从未设计过的事情)并找到另一种方法来获得相同的效果 - 这是有效的。

再次感谢您的期待!