7

时代变了,该使用原生popover属性模拟下拉了

 8 months ago
source link: https://www.zhangxinxu.com/wordpress/2024/01/js-html-popover-dropdown/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

时代变了,该使用原生popover属性模拟下拉了

这篇文章发布于 2024年01月11日,星期四,23:01,归类于 JS实例。 阅读 235 次, 今日 235 次 没有评论

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11097 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

封面图

一、事务繁忙,长话短说

目前主流的下拉列表,或者下拉面板的实现方式都是这样的。

点击按钮,让下拉元素显示,绝对定位,同时设置层级,点击空白处,隐藏下拉列表。

其中,每一步都需要JavaScript代码的参与,因此,一个下拉组件的JS代码量还是不容小觑的。

现在,浏览器已经支持原生popover属性,上面这种下拉列表实现方式可以扫进垃圾箱了。我可以这么说,日后使用popover属性实现下拉效果一定是主流实现方案。

因为有两个好处:

  1. 代码极简;
  2. 层级顶级;

例如有如下所示的HTML代码:

<button popovertarget="imgBook">点击显示图片</button>
<img id="imgBook" popover src="/study/202312/book1.jpg" />

无需任何JS代码,点击按钮,就可以让图片显示,点击页面空白处,图片会自动隐藏,实时效果如下:

book1.jpg

这就是上面说到的代码极简。

至于层级顶级。

这是Web中专有的一个概念,称为top-layer,元素全屏,或者<dialog>对话框使用showModal()方法显示的时候,都会表现为top-layer,如下图所示:

#top-layer示意

顾名思意就是层级顶级,页面中任何元素都无法覆盖,哪怕z-index设置为999999。

一个页面可以有多个层级顶级元素,至于哪个在最上面,采用的是后来居上的原则,也就是那个后显示,那个就在上面,这个非常符合真实的交互需求。

基于以上两点,popover属性一定是下拉交互的最佳实现。

二、案例演示,一目了然

例如,在LuLu UI中的<select>模拟下拉框的效果是这样的:

lulu ui select 模拟下拉效果

现在要实现此效果,极其简单,只需要让下拉框在显示的时候计算下定位就可以了(默认是浏览器居中定位的)。

HTML结构示意:

<button id="button" popovertarget="select">请选择</button>
<menu id="select" popover>
    <li><input type="radio" name="type" value="">请选择</li>
    <li><input type="radio" name="type" value="1">选项1</li>
    <li><input type="radio" name="type" value="2">选项2</li>
    <li><input type="radio" name="type" value="3" disabled>选项3</li>
    <li><input type="radio" name="type" value="4">选项4</li>
</menu>

使用radio单选框模拟选中行为,可以保持<select>元素的表单特性。

至于显示、隐藏以及层级设置都是popover属性自动完成的,我们无需关心,因此,所有的JS代码其实就下面这一点。

button.onclick = function () {
    const bounding = this.getBoundingClientRect();

    select.style.top = (bounding.bottom + window.pageYOffset) + 'px';
    select.style.left = (bounding.left + window.pageXOffset) + 'px';
    select.style.width = bounding.width + 'px';
};
select.onclick = function (event) {
    if (event.target.type == 'radio') {
        this.hidePopover();
        // 选择文字内容更新
        button.textContent = event.target.parentElement.textContent;
    }
}

是不是简单到瞠目结舌,匪夷所思?

眼见为实,你可以狠狠地点击这里:使用popover属性模拟select下拉demo

下拉模拟效果截图示意

下拉列表各种状态应有尽有。

三、与时俱进,勇攀高峰

popover属性目前所有现代浏览器都支持了,在不久的将来大规模应用已是大势所趋。

popover兼容性

好了,就说这么多吧。

最近忙碌,就不扯淡了。

感谢阅读,欢迎!

大人,时代变了

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11097


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK