乐趣区

关于前端:原生popover终于来了

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

提到 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 属性来设置点击行为,有showhidetoggle 3 种形式
  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

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

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

退出移动版