IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    张 鑫旭发表于 2024-01-11 15:01:33
    love 0

    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代码,点击按钮,就可以让图片显示,点击页面空白处,图片会自动隐藏,实时效果如下:


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

    至于层级顶级。

    这是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兼容性

    好了,就说这么多吧。

    最近忙碌,就不扯淡了。

    感谢阅读,欢迎!

    大人,时代变了

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

    (本篇完)



沪ICP备19023445号-2号
友情链接