这篇文章发布于 2024年06月11日,星期二,00:00,归类于 Web综合。 阅读 4913 次, 今日 17 次 3 条评论
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的标识,例如:
一旦看到这个标识,就说明页面有顶层元素了。
如何创建顶层元素?
目前来说,创建顶层元素有下面这几种方法:
- 元素全屏显示,可以通过调用Element.requestFullscreen()方法实现;
- 上面提到的使用showModal()方法显示的
<dialog>
元素 - 使用HTMLElement.showPopover()方法显示的弹出层元素。
其中,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
(本篇完)
- CSS ::backdrop伪元素是干嘛用的? (0.387)
- CSS相对定位|绝对定位(五)之z-index篇 (0.245)
- 告别JS浮层,全新的CSS Anchor Positioning锚点定位API (0.221)
- IE6下z-index犯癫不起作用bug的初步研究 (0.181)
- 文本框邮箱地址自动提示jQuery插件 (0.147)
- 小tip: CSS3 animation渐进实现点点点等待提示效果 (0.147)
- 翻译-10件Flash可以做而HTML5做不了的事情 (0.111)
- HTML5全屏API在FireFox/Chrome中的显示差异 (0.111)
- 时代变了,该使用原生popover属性模拟下拉了 (0.089)
- 最近整的MooTools库下Mbox弹框插件 (0.063)
- 了解infinity、pi等CSS calc()计算关键字 (RANDOM - 0.034)
在这个demo中,为什么toast显示在顶层之后,内部无法交互呢,内容无法选择,双击等操作选择的是dialog里的文本。
用dev tool查看也定位不到toast元素,定位的反而是dialog元素。
我觉得dialog最麻烦的地方可能还是在于动画了,要实现展示**和**消失的动画,目前有我想到的有三种方案,一个是手动用js来控制animate,兼容性好,但是消失动画不好做,得劫持esc按键,以及不能使用原生的button target=dialog来关闭dialog了,而且这种用法相当于是把dialog滥用成一个top layer portal了,那和传统方案相比优势并不明显
第二种是使用view-transition,这个兼容性差(只有新版chrome),效果选择有限
第三种理论上是最优解,但兼容性更爆炸,就是使用transition-behavior: allow-discrete来允许none到block的transition,还需要使用@starting-style来设定从none转变过来时的初始样式,唯一的问题就是:只有最新的chrome能用
`撤了` -> `扯了`