by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11213
本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。
HTML5 <dialog>
元素使用showModal()显示的时候,自动层级最高,自动居中,自动有黑色蒙层,明显就比使用show()方法或者设置open属性显示弹框要好。
于是,就在前段时间,对于LuLu UI Edge主题的弹框组件,我就进行了大刀阔斧的修改,让弹框的显示均采用showModal()方法(通过劫持open属性实现)。
修改完了自我感觉良好,但是真的实践之后,痛苦的事情来了,由于dialog元素顶层了,因此,自定义的验证提示,浮动定位,toast提示等,全都无法显示,因为这些组件的元素创建都是在body元素下的,由于弹框层级顶级,因此,这些组件样式被覆盖地死死的,用户根本就看不到。
唯一的方法就是让toast元素,浮层元素全都append到<dialog>
元素中,这实在是太麻烦了。
于是,没办法,妥协,仅alert和confirm类型的弹框使用showModal()显示,其他类型的弹框还是传统的show()方法显示,使用JavaScript进行层级控制。
可见,看起来很棒的特性真正使用,可能并没有想的那么好。
就像找对象一样,看起来长得漂亮身材又好,真正相处并不一定自在。
撤了这么久的“顶层特性”究竟是什么呢?
MDN上对这个术语有专门的文档,参见:https://developer.mozilla.org/en-US/docs/Glossary/Top_layer
简而言之,就是浏览器会在文档外创建一个独立的层,这个层正好覆盖整个浏览器视口的宽度和高度,位于页面所有内容之上。
打开控制台,查看元素,会看到#top-layer的标识,例如:
一旦看到这个标识,就说明页面有顶层元素了。
目前来说,创建顶层元素有下面这几种方法:
<dialog>
元素其中,requestFullscreen()
可以让任意元素进入全屏显示状态,showPopover()则可以让任意的HTML元素以弹出层的形式显示,我之前写过一篇文章专门介绍,详见“时代变了,该使用原生popover属性模拟下拉了”。
至于CSS锚点定位(CSS Anchor Positioning API)虽然也是浏览器原生的定位效果,但是,并不会让元素顶层显示,因此,目前,让元素顶层的方法就上面3种。
要想让自定义的提示效果能在具有顶层特性的Dialog对话框上显示,唯一的办法就是以毒攻毒,也就是自定义提示元素我也弄成顶层元素,顶层元素遵循后显示层级更高的元素,因此,这种方法一定可以让提示元素在对话框之上。
所以,归根结底,最好的解决方法,那就是把Tips提示或Toast提示效果使用showPopover()方法显示。
因此,传统组件中的HTMLElement.style.display=”block”这种显示方法就不能使用了,改为给对应的提示元素设置popover属性,然后再调用showPopover()方法。
这里有个演示案例,交互过程是这样的,点击按钮,显示一个模态对话框,模态对话框中还有个显示toast提示的按钮,点击之后,再显示提示框,注意,这里的提示框是使用showPopover()方法实现的。
直接HTML就可以完整运行:
<button onclick="dialog.showModal();">点击我显示模态对话框</button> <dialog id="dialog"> <blockquote> <button onclick="toast.showPopover();">显示toast提示</button> <button onclick="dialog.close();">关闭</button> </blockquote> </dialog> <div id="toast" class="toast" popover>我是提示内容</div>
按照预定的路径连续点击后,就可以看到toast出现在对话框上面啦!
眼见为实,您可以狠狠地点击这里:popover实现toast提示覆盖顶层对话框demo
此时,页面中其实存在两个顶层元素,截图示意如下:
改造成本极低,技术上完全可行。
不过,考虑到兼容性,Safari 23年9月26日才从版本17开始支持,仍有大量用户尚未升级到此版本之上,因此,组件的改造工作还需要再等1年左右,到时候LuLu UI所有这种需要顶层显示的元素全部都采用popover方式实现。
就目前而言,如果遇到顶层元素覆盖的情况,只能让提示元素当作顶层元素的子元素处理了。
这个端午节,连续钓了三条鱼,哈哈哈,收获都还凑合,能明显看出比去年这个时候的自己进步了不少。
第一天存古垂钓园,140元6小时,钓了31斤。第二天宝沪休闲垂钓,150元6小时,钓了34斤,大热天钓这么多不容易,第三天,兄弟垂钓,100元4小时,钓了18斤。
具体过程可以参见我的抖音“最会钓鱼的程序员”,欢迎关注哈。
就是CSS世界精讲视频要delay一天,因为今早带小朋友出去玩,早上赶着出门,没什么时间。
不知道大家端午过得怎么样呢?
嘿嘿,就这样吧,一点思考与实践记录。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11213
(本篇完)