jQuery模态框定位

6
好的。我正在使用一个弹出窗口来显示动态表格的业务细节。这个表格非常长。弹出窗口的一切都正常,但是如果他们滚动到页面底部,它总是在页面顶部打开弹出窗口。所以他们必须大量地向下滚动。
我目前正在使用这段代码来居中我的弹出窗口。
function centerPopup(x){
    //request data for centering
    var windowWidth = document.documentElement.clientWidth;
    var windowHeight = document.documentElement.clientHeight;
    var popupHeight = $("#popup" + x).height();
    var popupWidth = $("#popup" + x).width();
    //centering
    $("#popup" + x).css({
        "position": "absolute",
        "top": windowHeight/2-popupHeight/2,
        "left": windowWidth/2-popupWidth/4
    });
    //only need force for IE6

    $('#backgroundPopup').css({
        "height": windowHeight
    });

}

我不知道这段代码中是否有任何影响。一个解决办法是让他们滚动到之前的位置,但我找不到太多关于.position的文档。

7个回答

12

7

为什么要重新发明轮子,当已经有许多模态插件的作者已经完成了艰苦的工作。请查看blockuiimpromptujqmodal插件。即使您不使用它们,您也可以查看源脚本并查看如何实现所需功能的示例。


我希望我能使用一个简单的插件,但不幸的是,我正在使用Ruby on Rails从数据库中提取模态框。每个链接都是一个商家名称,打开一个包含商家详细信息的模态框。我还没有找到类似的东西。那些插件是针对硬编码HTML警报之类的,除非我完全错了。 - Mike
您可以轻松地将上述插件与动态内容一起使用。 - redsquare
如果您查看ThickBox,它可以通过Ajax获取内容并在模态弹出窗口中显示。 http://jquery.com/demo/thickbox/ - SolutionYogi
thickbox现在已经有些过时了,上面有更好的替代品。 - redsquare
你知道有哪些好的网站或教程可以让我看到有人将动态内容实现到其中一个模态框中吗?甚至可能是Ruby on Rails? - Mike
也许可以尝试使用http://polyrails.com/2008/11/11/steps-to-unobtrusive-rails-with-jquery/来实现不侵入式的Rails和jQuery。我不会选择livequery插件,但它应该能帮助你入门。 - redsquare

3

好的,以下是翻译内容:

var scrolledX = document.body.scrollLeft || document.documentElement.scrollLeft || self.pageXOffset;
var scrolledY = document.body.scrollTop || document.documentElement.scrollTop || self.pageYOffset;

var screenWidth = document.body.clientWidth || document.documentElement.clientWidth || self.innerWidth;
var screenHeight = document.body.clientHeight || document.documentElement.clientHeight || self.innerHeight;

var left = scrolledX + (screenWidth - $("#popup" + x).width())/2;
var top = scrolledY + (screenHeight - $("#popup" + x).height())/2;

//Use the top and left variables to set position of the DIV.

虽然我同意redsquare的观点,不要重复造轮子,而是使用现有的插件。

编辑:最终代码应该像这样:

function centerPopup(x)
{

    var scrolledX = document.body.scrollLeft || document.documentElement.scrollLeft || self.pageXOffset;
    var scrolledY = document.body.scrollTop || document.documentElement.scrollTop || self.pageYOffset;

    var screenWidth = document.body.clientWidth || document.documentElement.clientWidth || self.innerWidth;
    var screenHeight = document.body.clientHeight || document.documentElement.clientHeight || self.innerHeight;

    var left = scrolledX + (screenWidth - $("#popup" + x).width())/2;
    var top = scrolledY + (screenHeight - $("#popup" + x).height())/2;

    //centering
    $("#popup" + x).css({
        "position": "absolute",
        "top": top,
        "left": left
    });
    //only need force for IE6

    $('#backgroundPopup').css({
        "height": screenHeight
    });

}

我应该只需将以下代码 var windowWidth = document.documentElement.clientWidth; var windowHeight = document.documentElement.clientHeight; var popupHeight = $("#popup" + x).height(); 替换成您的代码吗?我尝试过,但链接根本没有反应。您能否告诉我如何确切地将您的代码实现到我的代码中? var popupWidth = $("#popup" + x).width(); - Mike
不幸的是,唯一发生的事情就是背景会变暗,就像应该发生的那样,但当我尝试输入那个代码时没有弹出框。而且当屏幕变暗时,它也会回到页面顶部。 - Mike
我点击了第一个链接,我的顶部是7295.5,左侧是427.5。所以我发现我的页面高度超过了14,000像素。您的代码将模态框放在页面的正中间,但仍然会被强制滚动到页面顶部。因此屏幕变暗并且您被发送到页面顶部。所以我们仍然有一个问题,即我们被发送到页面顶部,但是现在框已经位于页面的中央。 - Mike
我很蠢,因为我只需要在代码中添加一个“return false”就可以阻止它向页面顶部滚动。现在我只需要让窗口出现在当前屏幕的中央,而不是页面的中央。 - Mike
你能否在jsbin.com上提供一个可工作的示例?我会查看一下。 - SolutionYogi
显示剩余3条评论

2

对我来说,一个简单的解决方案是将模态窗口所在容器元素的CSS设置为:

position:fixed;

这在IE7及以上版本中可行,对于IE6,您可能需要使用上述高级方法。

1
这是一种不错的方法,可以扩展jQuery UI对话框插件,以添加一个新的“sticky”选项...
// This code block extends the ui dialog widget by adding a new boolean option 'sticky' which,
// by default, is set to false. When set to true on a dialog instance, it will keep the dialog's
// position 'anchored' regardless of window scrolling - neato.

// Start of ui dialog widget extension...
(function(){
    if($.ui !== undefined && $.ui.dialog !== undefined)
    {
        var UIDialogInit = $.ui.dialog.prototype._init;
        $.ui.dialog.prototype._init = function()
        {
            var self = this;
            UIDialogInit.apply(this, arguments);

            //save position on drag stop for sticky scrolling
            this.uiDialog.bind('dragstop', function(event, ui)
            {
                if (self.options.sticky === true)
                {
                    self.options.position = [(Math.floor(ui.position.left) - $(window).scrollLeft()),
                                             (Math.floor(ui.position.top) - $(window).scrollTop())];
                }
            });

            //we only want to do this once
            if ($.ui.dialog.dialogWindowScrollHandled === undefined)
            {
                $.ui.dialog.dialogWindowScrollHandled = true;
                $(window).scroll(function(e)
                {
                    $('.ui-dialog-content').each(function()
                    {   //check if it's in use and that it is sticky
                        if ($(this).dialog('isOpen') && $(this).dialog('option', 'sticky'))
                        {
                            $(this).dialog('option', 'position', $(this).dialog('option','position'));
                        }
                    });
                });
            }
        };

        $.ui.dialog.defaults.sticky = false;
    }
})();
// End of ui dialog widget extension... 

0

这里有一个非常好的关于设置ModelPopup位置的答案。希望能对大家有所帮助。

  1. 获取您想要模态窗口显示的位置。您可以使用ASP.NET Ajax库中的Sys.UI.DomElement.getLocation方法来实现,如下所示:

    var location = Sys.UI.DomElement.getLocation($get("div1"));

在这种情况下,我使用了一些div控件来设置模态窗口的位置。

  1. 通过使用面板或div元素获取模态窗口引用。

  2. 设置模态窗口的位置:

    Sys.UI.DomElement.setLocation($get('panel1'), location.x,location.y);


请注意,仅链接答案是不被鼓励的,SO答案应该是寻找解决方案的终点(而不是另一个参考站点,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的摘要,将链接作为参考。 - kleopatra

-2

我不知道为什么每个人都说要使用插件...为什么要重新发明轮子。为什么要费心学习...只需让别人来做。我从1.3.x开始使用jquery,许多插件都很臃肿,不是全部,但很多。我已经用1/4的代码行数编写了许多我研究过的插件的相同解决方案,而且它们也能满足我的需求。

还有,在我忘记之前...一个简单的解决方法是在你的模态或定位代码运行后添加... return false; 就可以解决回到顶部的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接