欢送关注我的公众号:前端侦探

提到 popover,置信大家都很相熟,没错,就是组件库里常常见到的悬浮层(或者叫“气泡卡片”),比方 Ant Design

当初,这个好用的个性终于在Chrome 114上正式反对了~上面花几分钟疾速理解一下吧

一、popover 属性

其实这个名称以前叫做popup,起初才更改成了popover

popover是一个全局属性。给任意元素增加popover当前,它就变成了一个悬浮层。

<div popover>我是悬浮层</div>

popover有两个值,别离是

  • auto:主动(默认值)。也就是浏览器默认行为,比方点击悬浮层里面会敞开悬浮层,按键盘Esc键也会敞开悬浮层
  • manual:手动。也就是没有后面的默认行为,所有操作必须由开发者手动管制。
<div popover>我是悬浮层</div><div popover="auto">我是悬浮层</div><div popover="manual">我是悬浮层</div>

悬浮层默认是暗藏的,也不能通过属性设置默认显示。那么,如何关上一个悬浮层呢?

二、管制悬浮层的形式

管制悬浮层有两种形式,别离是 申明式命令式

首先来看申明式,常常写原生HTML的应该会很喜爱这种形式,无需 JS 染指就能够实现悬浮层的关上和敞开,如下

<button popovertarget="pop1">关上 auto 悬浮层</button><div id="pop1" popover>我是 auto 悬浮层</div>

只须要通过popovertarget属性将指标悬浮层的id属性和按钮相关联就行了(留神,只能是ID),成果如下

还能够通过popovertargetaction属性来设置点击行为,有三个值,别离是

  • show:关上。
  • hide:敞开。
  • toggle:切换(默认值)。如果悬浮层是敞开的就关上,反正亦然
<button popovertarget="pop1" popovertargetaction="show">关上 auto 悬浮层</button><button popovertarget="pop1" popovertargetaction="hide">敞开 auto 悬浮层</button><button popovertarget="pop1" popovertargetaction="toggle">切换 auto 悬浮层</button><div id="pop1" popover>我是 auto 悬浮层</div>

成果如下

当初回过头来看看两种popover的区别

<button popovertarget="pop1">切换 auto 悬浮层</button><button popovertarget="pop2">切换 manual 悬浮层</button><div id="pop1" popover>我是 auto 悬浮层</div><div id="pop2" popover="manual">我是 manual 悬浮层</div>

成果如下

能够看到,auto悬浮层点击空白会主动敞开(还能够通过Esc键敞开),而manual悬浮层只能手动去敞开。当然大部分状况下auto能够满足需要。

三、命令式形式

所谓“命令式”,其实就是一套JS API,须要在 JS中被动去调用。

那么,有了申明式为啥还要命令式呢?答案是,更灵便

比方,后面的申明式,只实用于click场景,如果须要hover也能关上悬浮层,这种形式就不行了。像这种状况,就能够采纳命令式形式了。

先看语法,很简略,就是 3 个办法

popoverEl.showPopover(); // 关上popoverEl.hidePopover(); // 敞开popoverEl.togglePopover(force) // 切换,可传参数,强制设置为 true 或者 false

须要留神的是,这 3 个形式仅实用于悬浮层,也就是必须有popover属性,如果是一般元素,会间接报错,如下

还有一种状况,如果一个原本曾经关上的悬浮层,再次调用showPopover(),也会报错,反之亦然

因而,在应用 JS 管制时,举荐应用manual悬浮层,便于精准管制。

上面来看一个hover管制的例子

<button id="button">hover 关上悬浮层</button><div id="pop" popover="manual">我是 hover 悬浮层</div>

而后是相干JS

button.addEventListener('mouseenter', () => {  pop.showPopover()})button.addEventListener('mouseleave', () => {  pop.hidePopover()})

成果如下

四、判断悬浮层的关上状态

首先,从HTML构造上来看,关上和敞开没有任何属性变动,这个和details不一样(details会增加open属性)。为此,CSS 还专门出了一个伪类:open用于标识悬浮层的关上状态

目前还不稳固,后续可能会更变为:popover-open
div[popover]:open{  /* 关上款式 */}

通过这个伪类,咱们能够很轻松的给悬浮层增加过渡动画

[popover]{  display: block; /*默认是display:none,不会有动画*/  visibility: hidden;  opacity: 0;  transform: scale(.6);  transition: .3s;}[popover]:open{  visibility: visible;  transform: scale(1);  opacity: 1;}

成果如下

除了 CSS 形式,JS 也能判断悬浮层的状态,然而并不是本人设想的那样。

起初,我认为有一个属性能够间接获取到悬浮层的状态,发现并不行,如下

popoverEl.open // undefined

那如何获取呢?

其实能够借助后面 CSS 的形式,只有匹配的:open伪类不就能够了吗,须要用到matches办法

https://developer.mozilla.org/en-US/docs/Web/API/Element/matches

这样就能随时获取到悬浮层的关上状态了

popoverEl.matches(':open')

另外,还能够通过事件监听的形式来获取,须要用到新的事件toggle,这是一个专门针对popover新推出的事件,应用形式如下

popoverEl.addEventListener("toggle", (event) => {  if (event.newState === "open") {    console.log("关上状态");  } else {    console.log("敞开状态");  }});

五、popover 的顶层个性

后面说了那么多,如同并没有什么很厉害的中央,轻易一个 div 都能够模仿,而且当初的组件库不是也实现的好好的吗?到底有什么劣势呢?

关上控制台能够看到,popover上有一个很非凡的标识

这个就是顶层 top-layer !也就是层级是最高的,高于页面上的所有。

这也是悬浮层的意义所在,自身就应该是悬浮在最下面。上面是示意图

这样的益处就是无论在 HTML中的任何地位,都无需放心悬浮层被遮挡的状况,也无需将悬浮层挪动的最外层body上。

这个个性和dialog是一样的,有趣味的能够参考之前这篇文章:你可能不晓得的dialog弹窗

以上残缺代码能够查看以下任意链接:

  • popover (codepen.io)
  • popover (runjs.work)

如果浏览器不反对,会有上面提醒

这个是用@supports实现的

@supports selector([popover]:open) {    .no-support{        display: none !important;    }}

六、兼容性和总结

看一下兼容性,目前只有Chrome 114+反对,外部我的项目能够尝鲜一下,如果是Electron利用,那就大胆应用吧

上面来总结一下本文要点:

  1. popover是一个全局属性。给任意元素增加popover当前,它就变成了一个悬浮层。
  2. popover属性有两个值,默认是auto主动模式,反对默认行为,比方点击空白敞开,键盘Esc敞开
  3. popover属性还反对manual手动模式,也就是没有以上默认行为
  4. 管制popover有两种形式,别离是申明式和命令式
  5. 申明式是指通过HTML属性来实现点击交互
  6. 能够通过popovertarget属性将悬浮层的id和按钮相关联,这样就能通过按钮关上悬浮层了
  7. 还能够通过popovertargetaction属性来设置点击行为,有showhidetoggle3种形式
  8. 命令式是指通过 JS API来实现对悬浮层的管制,相比申明式而言更加灵便
  9. 管制悬浮层的办法有showPopoverhidePopovertogglePopover
  10. CSS伪类:open能够辨别悬浮层的关上状态
  11. JS 能够通过matches(':open')来获取悬浮层的关上状态
  12. JS 还能够通过监听toggle事件来获取悬浮层的关上状态,形式是event.newState
  13. 相比传统实现,原生popover最大的劣势是反对顶层个性

最近正在对xy-ui进行降级革新,外面的 popover 组件就应用到了这一个性,不过也对不反对的浏览器做了兼容,有趣味的能够去体验一下。

https://xy-ui.codelabo.cn/components/popover

最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探