模态框:在打开模态框时,用户只能与模态框交互,无法与页面其他部分交互。
非模态框:在打开非模态框时,用户可以与页面其他部分交互。
html 的 popover 属性创建的弹窗属于非模态框。
html 提供的 <dialog>
可以创建模态框。
给 html 元素添加 popover 属性,这个元素就会变成非模态框。
<div popover id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
默认属性是 display: none,所以在页面上是看不见的。
可以通过 点击按钮
或者 弹窗api
来控制显示/隐藏弹窗,下面依次介绍。
popover 创建的弹窗不受 z-index 影响,层级永远是最高的。
html button 元素有一个属性 popovertarget,用来将按钮变成控制 popover 弹窗的特定按钮。
在 button 元素上添加 popovertarget 属性,属性值是设置了 popover 元素的 id 值。: ) 这样才知道按钮控制的是哪个弹窗!
<button popovertarget="my-popover">点击出现弹窗</button>
<div popover id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
点击按钮,弹窗出现;再次点击按钮,弹窗隐藏。
上面的示例中:点击按钮,如果弹窗没有出现,会显示弹窗,如果弹窗出现了,会隐藏弹窗,会自动切换显隐状态。其实这个行为是由 button 元素的另一个属性 popovertargetaction 控制的。
popovertargetaction 属性有三个值:
如下示例:给 button 元素设置 popovertargetaction=”show”,此时点击按钮,弹窗会出现,再次点击按钮,弹窗没有像之前一样消失。因为弹窗的行为只有显示 (show) 这一个状态。
<button popovertarget="my-popover" popovertargetaction="show">点击出现弹窗</button>
<div popover id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
说明: 在 html 中, button 元素和 input type=”button” 都具有按钮行为。下面两种写法是等价的。
<button popovertarget="my-popover">点击出现弹窗</button>
<input type="button" value="点击出现弹窗" popovertarget="my-popover">
只有 button 元素才有 popovertarget 属性,如果开发中希望点击 div / p 或其它任意元素来控制弹窗显隐,那只能通过调用弹窗 api 的方式来实现。
弹窗 api 总共有三个:
如下示例:点击 div,触发 show(),函数内部调用 togglePopover() 来显示弹窗。
<div onclick="show()">点击弹出弹窗</div>
<div popover id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
<script>
function show() {
document.querySelector('#my-popover').togglePopover();
}
</script>
你会发现:第一次点击 div,弹窗出现,第二次点击 div,弹窗没有像预期那样消失。明明使用了 togglePopover(),这是为什么?
之前介绍 popover 属性时略过了一个知识点,popover 有两个属性值:
如下修改后,第一次点击 div,弹窗出现,第二次点击 div,弹窗如预期那样隐藏。
<div onclick="show()">点击弹出弹窗</div>
<div popover="manual" id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
<script>
function show() {
document.querySelector('#my-popover').togglePopover();
}
</script>
如果想要给弹窗设置个背景灰色蒙版,添加如下 css 样式即可。
#my-popover::backdrop {
background-color: rgba(0, 0, 0, 0.3);
}
popover 弹窗在页面中的位置默认是垂直水平居中。
默认样式中可以知道这个弹窗是 fixed 布局,inset 是 top, right, bottom, left 的简写,inset: 0px 意味着垂直水平居中。
[popover] {
position: fixed;
inset: 0px;
}
如果要修改弹窗的位置,设置 inset: unset; 意思是将 top, right, bottom, left 的值都设置为空,然后再单独设置需要控制的位置属性即可。
示例: 弹窗在右下角显示
<style>
#my-popover {
inset: unset;
bottom: 0px;
right: 0px;
}
</style>
<div popover="manual" id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
示例: 模拟下拉框,弹窗在div下方显示
<div class="select">
<div onclick="show()" id="selector">点击弹出弹窗</div>
<div popover="manual" id="my-popover">
<div>这是一个弹窗标题</div>
<div>床前明月光,疑是地上霜。</div>
</div>
</div>
<script>
function show() {
// 获取div元素
const selectorEl = document.querySelector('#selector')
// 获取弹窗元素
const popoverEl = document.querySelector('#my-popover')
// 获取div元素位置信息
const selectorRect = selectorEl.getBoundingClientRect()
popoverEl.style.inset = 'unset'
popoverEl.style.left = selectorRect.left + 'px'
// 弹窗出现在 div 下方
popoverEl.style.top = selectorRect.top + selectorRect.height + 'px'
// 弹窗出现在 div 上方
// popoverEl.style.bottom = window.innerHeight - selectorRect.top + 'px'
popoverEl.togglePopover()
}
</script>
↶ 返回首页