by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11097 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
目前主流的下拉列表,或者下拉面板的实现方式都是这样的。
点击按钮,让下拉元素显示,绝对定位,同时设置层级,点击空白处,隐藏下拉列表。
其中,每一步都需要JavaScript代码的参与,因此,一个下拉组件的JS代码量还是不容小觑的。
现在,浏览器已经支持原生popover属性,上面这种下拉列表实现方式可以扫进垃圾箱了。我可以这么说,日后使用popover属性实现下拉效果一定是主流实现方案。
因为有两个好处:
例如有如下所示的HTML代码:
<button popovertarget="imgBook">点击显示图片</button> <img id="imgBook" popover src="/study/202312/book1.jpg" />
无需任何JS代码,点击按钮,就可以让图片显示,点击页面空白处,图片会自动隐藏,实时效果如下:
这就是上面说到的代码极简。
至于层级顶级。
这是Web中专有的一个概念,称为top-layer,元素全屏,或者<dialog>
对话框使用showModal()方法显示的时候,都会表现为top-layer,如下图所示:
顾名思意就是层级顶级,页面中任何元素都无法覆盖,哪怕z-index设置为999999。
一个页面可以有多个层级顶级元素,至于哪个在最上面,采用的是后来居上的原则,也就是那个后显示,那个就在上面,这个非常符合真实的交互需求。
基于以上两点,popover属性一定是下拉交互的最佳实现。
例如,在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属性目前所有现代浏览器都支持了,在不久的将来大规模应用已是大势所趋。
好了,就说这么多吧。
最近忙碌,就不扯淡了。
感谢阅读,欢迎!
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11097
(本篇完)