模态对话框被不透明背景遮挡

Posted

技术标签:

【中文标题】模态对话框被不透明背景遮挡【英文标题】:Modal Dialog is obscured by opaque background 【发布时间】:2018-06-01 22:25:18 【问题描述】:

我正在使用 Element 的 Notification 组件,但是当它被激活时,对话框会出现,但似乎是“隐藏在”同样引入的灰色背景的“后面”。单击任意位置会删除灰色背景并允许与对话框交互,但不会出现应该过滤掉正常屏幕噪音的灰色背景。这是一个显示各种状态的简短视频:

video

将组件放入的代码如下:

  <div class="add-address" @click="showAddDialog = true">
    +
  </div>
</div>
<el-dialog
  title="Add New Address"
  :visible.sync="showAddDialog"
  
  :before-close="newAddressDialogClosed">
  <span>Postal Address</span>
  <el-input v-model="newAddress" type="text"></el-input>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">Cancel</el-button>
    <el-button type="primary" @click="dialogVisible = false">Confirm</el-button>
  </span>
</el-dialog>

我已经使用检查器来查看 CSS,但我还没有从 CSS 角度或 Vue/Element 角度理解是什么原因造成的。任何帮助将不胜感激。


我进一步分析了 html/CSS,组件似乎在 DOM 中引入了两个单独的块:

下面的块是灰色背景,您希望它“模糊”页面并将注意力集中在模式上。但是,它位于对话框的前面。同样有趣的是,单击任何地方似乎会针对灰色背景并将其关闭,但这样做也会对对话框上的位置产生微妙的影响,如下所示:

请注意,对话框的 z-index 大于背景,这对我来说直觉上是有意义的,但我认为这会将对话框置于顶部。猜猜这还不是全部。


我现在已经通过将背景更改为display: none 然后直接在 DOM 中的模式对话框之前添加以下 HTML 来解决问题:

<div class="modal-background" v-if="showAddDialog"></div>

这些似乎验证了我的潜在怀疑,即在 DOM 树中的放置很重要,并且组件尝试将模态背景放置在 DOM 的最末端是有问题的。

【问题讨论】:

像this这样的简单例子你有同样的问题吗? @Alessandro 我正在使用 Typescript,但您使用的示例几乎正是我开始使用的,因为它直接来自演示站点。 您在控制台日志中看到任何错误吗? 不,没有错误 你有没有加载器,比如this?您的问题似乎有所不同,但在这段代码中我看不到任何错误。你能创造一个小小提琴吗? 【参考方案1】:

我遇到了同样的问题,还发现更改对话框的 z-index 没有效果。当我嵌套了 Element.Eleme.io 元素时就会发生这种情况,您似乎也是这种情况。

z-index 并不像“更高总是在顶部”那么简单。元素被分组到不同的堆叠上下文中;较低堆叠上下文中的元素不可能出现在较高堆叠上下文中的元素之上。因此,根据不同元素在 DOM 中的渲染位置,它们可以将自己置于不同的堆叠上下文中,并且注定要保持彼此之间的相同关系,无论 z-index 发生了多少变化。 (有关 z-index 的更详细说明,请参阅 https://philipwalton.com/articles/what-no-one-told-you-about-z-index/。

使用 Chrome 开发工具检查,发现遮蔽模态与对话框没有呈现在同一位置;事实上,它被附加到主体,即在应用程序的外部,这似乎是它们不在同一个堆栈上下文中的原因。有一个快速修复;对话框元素有一个属性“modalAppendToBody”。如果为 true,则将模式呈现给主体,如果为 false,则将其呈现给对话框的父元素。通过将此指定为 false,我设法解决了这个问题:

<el-dialog
  title="Add New Address"
  :visible.sync="showAddDialog"
  
  :before-close="newAddressDialogClosed
  :modalAppendToBody="false">
</el-dialog>

【讨论】:

谢谢汉娜。这个来自的项目已经保留了几个月,所以无法在那里测试这个解决方案,但你的逻辑听起来很可靠,所以我会把它标记为正确的。 总而言之,将:modalAppendToBody="false" 添加到&lt;el-dialog&gt; 确实有效 视版本而定,可能是:modal-append-to-body="false"【参考方案2】:

您可以使用名为 z-index 的 CSS 属性

您想要设置为 back 的任何对象?你只需要设置 z-index: -1; // 或者更多 或者你想把任何物体放在另一个物体的前面?你只需要设置 z-index: 1; //或更多

查看片段了解更多信息:

.a 
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: -1;

.b 
    margin-top:150px;
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: 1;
<!DOCTYPE html>
<html>
<head>

</head>
<body>

<h1> I am on Image</h1>

<img class="a" src="http://qnimate.com/wp-content/uploads/2014/03/images2.jpg"  >
<br>
<br>
<br>
<br>
<h1> Image is on me</h1>

<img class="b" src="http://qnimate.com/wp-content/uploads/2014/03/images2.jpg"  >

</body>
</html>

【讨论】:

是的,我正在通过检查器查看 z-index 属性,但令我惊讶的是,我无法通过调整索引来纠正问题。 那么你现在解决了吗..? 我已经用额外的上下文更新了一些问题,但仍然卡住了。 您应该上传正确的代码 sn-p 以便更容易理解并建议您最好的解决方案 列出所有相关代码。对于大型私人存储库,重新创建确切的场景是不切实际的。

以上是关于模态对话框被不透明背景遮挡的主要内容,如果未能解决你的问题,请参考以下文章

Twitter 引导模式背景不会消失

将 Flex Titlewindow 背景设置为透明

cocos2d-x 模态对话框的实现

0188 案例:模态框拖拽

如何在 C++ MFC 中一次打开两个对话框?

QT模态对话框用法(在UI文件中设置Widget背景图,这个图是一个带阴影边框的图片——酷)