没有遮罩的 JQuery 模态对话框

7

我想展示一个“ajax加载对话框”,它会阻止用户操作(模态),但没有覆盖层。

以下是对话框的初始化代码:

  $("<div></div>").dialog({
         modal: true,
         dialogClass: "noOverlayDialog",
         autoOpen: false, //opened later
         ...
  });

我添加了以下CSS来隐藏叠加层:
.ui-dialog.noOverlayDialog + .ui-widget-overlay { opacity: 0 !important; }

然而,当我调用dialog("open")时,遮罩层会闪烁然后消失,就好像我使用Javascript将其隐藏一样。使用display:none;visibility:hidden也会产生相同的效果。
为了确保是CSS移除了遮罩层而不是其他原因,我删除了CSS代码行,遮罩层总是可见的。
这是为什么?我认为静态CSS不应该有这种行为,遮罩层应该立即被隐藏而没有闪烁。
如果我找不到直观的解决方案,也许一个替代办法是将模态选项设置为false以完全防止遮罩层,然后编写代码来实现模态行为。无论如何,我需要一个可行的解决方案。

我认为你最好的选择可能是覆盖jQueryUI样式表中声明的实际CSS属性,该属性用于叠加背景。当我说覆盖时,我的意思不是改变CSS本身,而是在你的工作HTML中添加属性并重新声明它们。 - Dennis Rongo
这不就是我所做的吗?问题是我不需要它是全局的,而只需要应用于具有类.noOverlayDialog的特定对话框。如果这不改变您的建议,请回答(而不是评论)并给出一个示例,我会尝试一下。谢谢。 - parliament
不行,因为你正在重新定义而不是覆盖实际的类。 - Dennis Rongo
仍然不明白你的意思。举个例子会更有帮助... - parliament
请提供一个 jsFiddle。 - Abhijeet Pawar
顺便说一下,目前dialogClass没有将类添加到覆盖层中,而覆盖层在对话框容器之外。实际上,即使使用了新的appendTo选项,覆盖层仍然附加在document.body上。这应该在即将推出的版本中修复。 - David
5个回答

6

我已经在jsFiddle上使其正常工作。 请点击此链接

<div id="dialog">
    <h3>Here is the dialog content</h3>
    <p id="dialogContent"></p>
</div>
<button onclick="$('#dialog').dialog('open');">open</button>

<script>
    $(document).ready(function(){
        $('#dialog').dialog({
            title: 'My dialog',
            dialogClass: "noOverlayDialog",
            autoOpen:false,
            modal: true,
            open: function(event,ui){
                $('.noOverlayDialog').next('div').css( {'opacity':0.0} );
            }
        });
    });
</script>

如果页面中有多个对话框,则此方法将无法正常工作(特别是 $('.noOverlayDialog').next('div') 不一定会选择正确的遮罩层 - 只有在这种情况下才会)。另外,您在“打开”时将 opacity 设置为 0,但从未将其重置为默认值,因此其他需要可见遮罩层的对话框将无法正常工作。我提供了一个替代方案答案,但您可能需要在自己的代码中解决这些问题。 - mgibsonbr
我不确定那是正确的。我的解决方案只会影响与#dialog div相关联的对话框。任何其他对话框都将根据传递给它们的选项正常工作。这是我应用程序上一个可行的解决方案,该应用程序共有15个不同的对话框。 - ShadeTreeDeveloper
1
起初我也是这么想的,但在使用你的小提琴时,我遇到了这个问题。虽然第一个对话框运行良好,但第二个对话框却隐藏了自己而不是覆盖层...(提示:使用Esc键关闭它,其余部分仍然可以正常工作) - mgibsonbr

4

jQuery使用的遮罩层具有类名ui-widget-overlay。因此,请在您的css中包含以下css规则:

.ui-widget-overlay {
    opacity: 0;
    filter: alpha(opacity=0);  /* IE8 and lower */
}

演示: http://jsfiddle.net/Lhwsq/

注意:

  1. 请确保此规则在jQuery CSS或任何其他插件CSS之后包含。
  2. 此样式将应用于同一页中的任何对话框。

要使其在任何特定对话框上起作用,请参见https://dev59.com/RW3Xa4cB1Zd3GeqPhraV#14586175


3

一个选项是创建一个额外的类overlay-hidden,并在对话框打开时将其添加到覆盖层中,在关闭时再将其移除。这将确保页面中的其他对话框(可能需要可见的覆盖层)继续正常工作:

open: function(event,ui){
    $('.ui-widget-overlay').addClass('overlay-hidden');
},
beforeClose: function(event,ui){
    $('.ui-widget-overlay').removeClass('overlay-hidden');
}

"overlay-hidden类将覆盖opacity0,正如@Vega所建议的那样suggested。"
.overlay-hidden {
    opacity: 0.0;
    filter: alpha(opacity=0);  /* IE8 and lower */
}

在 jsFiddle 上的工作示例(改编自 @ShadeTreeDeveloper 的 答案)。


1

以下答案都没有对我有用,但最终我找到了解决方案。

事实证明,对话框最初是在名为.ui-effects-wrapper的容器内呈现的,覆盖层跟随容器而不是对话框:

<div class="ui-effects-wrapper" ... >
     <div class="ui-dialog" .... >
     </div>
</div>
<div class="ui-widget-overlay" ...> </div>

因此,我的选择器.ui-dialog.noOverlayDialog + .ui-widget-overlay只有在效果容器被删除后才会生效。为了解决这个问题,我需要同时定位这两个选择器:
.ui-dialog.noOverlayDialog + .ui-widget-overlay, 
.ui-effects-wrapper + .ui-widget-overlay {
      background: none !important;
      opacity: 0 !important;
}

请注意,第二个选择器是全局的。

1
我感觉你看到的是覆盖背景图片在透明效果(顺便说一下,并非所有浏览器都支持)生效之前短暂渲染出来的情况。
.ui-widget-overlay { background: none !important; }

上面的代码应该可以运行。但是,如上面的评论所述,如果您在您的服务器或JSFiddle上发布一个示例,将允许进行更具体的诊断。

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