拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

HTML——那些自带交互特征的HTML元素(details标签、dialog标签)

HTML——那些自带交互特征的HTML元素(details标签、dialog标签) 那些自带交互特征的HTML元素1、非常实用的details元素1.1、黄金搭档summary元素1.2、样式的自定义1.3、实际使用案例示意1.3.1、悬浮菜单自定义下拉框等效果1.3.2、多项菜单折叠效果1.3.3、多级嵌套的树形菜单效果1.4、全新的name属性与手风琴效果2、深入了解dialog元素和popover属性2.1、dialog元素的基本特性2.2、dialog元素的不可替代性2.2.1、form元素与对话框自动关闭2.2.2、关闭来源的判断2.2.3、自动聚焦特性2.2.4、showModal()方法与真正的对话框2.2.5、焦点隔离特性2.2.6、顶层特性2.2.7、自动层级特性2.3、原生弹层与popover属性2.3.1、popover属性的基本使用2.3.2、原生弹层相关的属性和方法2.3.3、popover属性模拟移动端下拉框1、非常实用的details元素据我所知在所有的HTML元素中最实用的莫过于details元素其可以实现几乎任意的通过点击行为触发的展开与收起效果。1.1、黄金搭档summary元素details元素通常和summary元素同时使用注意这里的说法—“通常”​这是非常严谨的表述因为summary元素缺省的时候浏览器会自动生成summary元素并不会影响details元素的交互行为。此特性会在后面进一步详述现在我们先将精力放在details元素的常规应用上。先看下面这段HTML代码上面的代码在浏览器中的效果如图所示样式会因浏览器厂商及版本的不同而有所差异此效果仅供参考​。上面的示例代码中出现了3个HTML元素和1个HTML属性其中details元素是整个交互的核心即使没有设置summary元素也可以通过切换open属性决定里面内容的显示与隐藏。summary元素表示摘要是点击行为的触发源也就是在默认情况下我们通过点击summary元素来影响交互行为的发生。p元素在这里没有任何特殊的含义可以换成任意的内容元素甚至可以是纯文本例如下面的HTML结构也是合法的open属性的存在与否决定了details元素是展开状态的还是收起状态的在本例中如果没有设置open属性那么最终的样式效果会如图所示小三角图标朝右只显示summary元素其余内容均隐藏。最后再看一下没有设置summary元素的样式效果测试代码如下所示此时在我的Chrome 117版本下会有如图3-3所示的效果即浏览器自动生成了一个文案是“详情”​以前的文案是“详细信息”​的summary元素。然而浏览器自动创建的summary元素是写在ShadowDOM中的如图所示​外部的CSS无法改变其样式。因此在实际开发中如果你不希望出现summary元素可以这么处理自己写一个空的summary元素然后设置其隐藏就像下面这样。对于上述HTML示例的实际渲染效果大家可以通过在浏览器中输入地址https://www.htmlapi.cn/3/1-1.html访问来体验。1.2、样式的自定义浏览器默认的黑色小三角图形略显粗糙在对视觉要求较高的产品中往往需要对这个小图标做样式自定义。以下所有场景均使用同样的HTML结构1.颜色的改变首先我们可以轻松改变小三角的颜色例如下面的CSS代码可以将小三角图标的颜色变为红色。效果如图所示。2.位置的改变其次我们还可以将小三角图标的位置调整到右侧。效果如图所示。3.三角字符替换再者我们还可以将小三角图标替换为其他字符甚至是emoji字符例如此时详情信息展开和收起的效果如图所示。不过需要注意的是直接使用content替换默认三角字符的做法在Safari 16版本中并不支持以后可能会支持因此如果你有兼容性的要求可以试试使用下面的完全自定义方法。4.小三角图标完全自定义最后我们还可以将小三角图标完全自定义方法是隐藏浏览器原生的标记符再使用::before或::after伪元素模拟例如效果如图所示。以上所有自定义案例均可以通过在浏览器中输入地址https://www.htmlapi.cn/3/1-1.html访问来体验。1.3、实际使用案例示意样式可任意自定义那岂不意味着平日里那些通过点击行为触发的展开与收起效果都可以使用纯HTML代码实现了还真是这样的1.3.1、悬浮菜单自定义下拉框等效果只要是点击行为触发的悬浮菜单或者是自定义的下拉框效果都可以使用details/summary元素实现。参考如下所示的HTML代码此时只需要设置menu元素绝对定位悬浮菜单效果就可以实现了如图所示。1.3.2、多项菜单折叠效果在有些产品中侧边栏菜单数量会很多因此会有展开与收起的效果此时非常适合使用details/summary元素来实现例如下面的HTML代码无须使用任何额外的JavaScript代码各个菜单项天然支持展开和收起下图所示的就是“关注中心”收起其他菜单项展开的效果。另外如果希望每次最多只展开一个菜单项可以给details元素设置相同的name属性值。1.3.3、多级嵌套的树形菜单效果details元素还支持嵌套且没有层级限制因而使用details/summary元素实现树形菜单效果也不在话下。例如下面的HTML代码然后我们只需要给嵌套的details元素设置合适的缩进再自定义summary元素的小三角图标就可以实现最终的效果了如图所示。以上所有演示案例的交互效果以及完整代码均可以通过在浏览器中输入地址https://www.htmlapi.cn/3/1-3.html访问来体验。总而言之一句话details元素非常实用是所有HTML元素中为数不多的和点击交互强相关的元素。1.4、全新的name属性与手风琴效果Chrome和Safari浏览器给details元素新增了name属性这个属性的作用是如果多个details元素设置了相同的name属性值则这些details元素之间会形成互斥关系即同一时间只有一个details元素可以展开其他的details元素会自动收起。这个特性非常适合实现手风琴效果例如下面的HTML代码此时details元素每次最多只有一个是展开的效果如图所示。这是很棒的特性静待现代浏览器全面支持。2、深入了解dialog元素和popover属性本节讲讲原生的对话框元素dialog及可以让元素以弹出框下面简称弹框形式显示的popover属性。可以这么说只要你的项目没有兼容性方面的顾虑那么凡是对话框效果使用dialog元素一定是最佳解决方案任何使用div元素模拟的对话框组件都无法与之匹敌。2.1、dialog元素的基本特性dialog对话框的主体内容可以是任何HTML元素甚至是其他dialog元素。参见如下所示的极简案例dialog元素里面有一张img图片同时设置了open属性此时在Chrome浏览器下就可以看到如图所示的效果不同的浏览器下dialog对话框的默认样式细节会有所差异​。在默认状态下对话框元素会有黑色的边框、一定的padding内间距、绝对定位且左右居中但是并没有垂直居中这是个值得一提的细节知识即如果我们使用open属性或者使用dialog.open()方法打开对话框则对话框默认并不是在屏幕的垂直中心位置而是在dialog元素所在的DOM树位置附近。这么设计很好理解例如点击某个按钮然后显示对话框可以把对话框元素放在按钮的附近这样对话框显示的时候和交互元素距离近用户体验会更好。如果我们想要对话框位于屏幕的中心则需要额外的CSS设置或者用其他方法打开对话框这一点会在后面介绍。以上就是dialog元素的基本特性看起来似乎也没什么就多了些内置的CSS样式有些CSS样式是有用的例如绝对定位有些CSS样式则多余例如黑色的边框因为与目前的主流设计风格严重不符所以一定会被重置。要想在实际项目中使用dialog元素一定要进行样式自定义同时还需要增加标题及关闭按钮等元素。咦使用div元素模拟的弹框不也同样是样式自定义和增加一些固定的元素吗如此看来使用dialog元素模拟对话框和使用div元素岂非并无区别那还有使用dialog元素的必要吗有必要太有必要了因为dialog元素尚有很多其他元素无可替代的实用特性。2.2、dialog元素的不可替代性2.2.1、form元素与对话框自动关闭对话框元素中往往都会有一两个按钮不参与任何业务逻辑处理其作用仅仅是关闭对话框例如Alert类型对话框的确认按钮或者是对话框右上角的图标字样的关闭按钮。在过去这种关闭行为的实现一定是使用JavaScript代码触发的。例如或者等方法。实际上元素内置了一种特性就算不使用JavaScript代码也能触发对话框的关闭比如如下所示的HTML代码此时点击“我知道了”按钮对话框就会立即关闭。就是这么神奇不信你可以在浏览器中输入地址https://www.htmlapi.cn/3/2-1.html访问来体验对应的演示页面。点击如图所示的按钮可以看到对话框关闭了。此效果实现的关键是在form元素上设置了method“dialog”这是个表单新特性当设置了此声明后在提交表单元素的时候不再刷新页面或打开新窗口而是关闭当前的dialog对话框元素。而点击按钮触发表单提交的只能是’submit’性质的按钮因此万万不可将“我知道了”按钮设置为typebutton或者type“reset”。另外还可以在’submit’性质的按钮上设置formmethoddialog实现同样的对话框关闭效果例如2.2.2、关闭来源的判断dialog元素的DOM对象上支持一个名为returnValue的属性可以自动或手动设置对话框关闭行为的来源。例如下面这个例子这段代码模拟Confirm类型的对话框点击“确定”按钮会执行一段业务逻辑然后关闭对话框点击“取消”按钮则直接关闭对话框。无论是哪个按钮最终都有关闭对话框这一行为如果希望区分是哪个按钮触发的关闭就可以使用这个returnValue属性。其中有两种给returnValue属性传值的方法如果点击按钮触发了对话框关闭则可以在按钮上设置value属性例如value“cancel”如果使用JavaScript代码触发了对话框关闭则可以通过给close()方法传参的方式达到我们希望的效果例如此时我们通过访问dialog.returnValue就可以知道哪个按钮触发了对话框关闭。眼见为实你可以通过在浏览器中输入地址https://www.htmlapi.cn/3/2-2.htm访问来体验。例如点击“取消”按钮后页面上就会提示returnValue的值是’cancel’效果如图所示。如果是通过其他方式关闭的例如按下ESC快捷键则returnValue的值会是空字符串。2.2.3、自动聚焦特性使用原生HTML元素作为前端组件的好处之一就是无障碍访问天然支持无需额外的自定义。比如这里的自动聚焦特性。所谓“自动聚焦”​指的是对话框显示后浏览器的焦点会自动聚焦到对话框内。这种特性不仅有助于增强用户体验还保证了键盘的无障碍访问能力。还以上面出现过的那段HTML代码为例此时如果我们使用dialog.show()方法让对话框显示则其中的input输入框会自动获取焦点无须用户再去点击聚焦效果如图所示。类似地如果是一个Alert提示对话框则焦点会自动聚焦在“确定”按钮上此时用户只需要按下回车键对话框就会关闭操作非常便捷无须移动光标到“确定”按钮上然后再点击。需要注意的是这种自动聚焦特性会自动聚焦第一个能够聚焦的元素而不是智能识别是输入框还是按钮例如下面这段内容此时对话框打开的焦点则在a元素上不过不要紧要想聚焦到按钮上按下Tab键往后索引一下就好了。这是很多对话框组件所缺失的能力即忽略键盘的无障碍访问。设想一下如果对话框打开后浏览器的焦点不在对话框之中那么用户想要使用键盘访问对话框里面的内容就会很麻烦不知道按下多少次的Tab键才能转入对话框元素中​。这里还有一个细节需要注意dialog元素的焦点聚焦特性只有在执行show()或showModal()方法的时候才会触发如果是使用其他方法让对话框显示的如以下代码所示均无法自动聚焦到对话框中。最后如果对话框自动聚焦了那么对话框关闭的时候焦点会恢复到对话框显示之前的状态不会影响正常的键盘访问。2.2.4、showModal()方法与真正的对话框前面几节虽然一直在说“对话框”​但是最终所呈现的效果并非真正意义上的对话框而更像弹框层级可控位置可变焦点可定义更重要的是dialog元素背后的元素内容是可以正常交互的。真正的对话框应该是足够聚焦的用户只能专注于当前的任务​而不是像一个普通的绝对定位浮层。这里就不得不提一下dialog元素的“王炸”方法—showModal()让dialog元素成为真正的对话框元素。还是类似的HTML代码然后我们使用showModal()方法让对话框显示此时的效果如图所示可以明显看到多了个黑色半透明的模态层同时除对话框元素以外的元素都无法交互了。同时相比show()方法showModal()显示的对话框的定位方式也变了不再是绝对定位而是固定定位且实现了真正意义上的居中效果。上述几个明显区别参见下表。你也可以通过在浏览器中输入地址https://www.htmlapi.cn/3/2-3.html访问来感受一下showModal()方法的样式表现。模态对话框的半透明背景是可以使用CSS伪元素::backdrop自定义的视频的黑色背景也可以使用此伪元素进行样式自定义​例如下面这段CSS代码可以让默认的10%的黑色背景变成棋盘网格效果如图所示。并且我们可以使用modal伪类区分是普通对话框还是模态对话框。当然我对showModal()方法的评价如此之高并不仅仅因为它多了个模态层其还带来了现有对话框组件无法模拟的稀缺特性且不止一个。2.2.5、焦点隔离特性前面提到show()方法自带聚焦特性这个showModal()方法也有除此之外showModal()方法还有个焦点隔离特性。即一旦模态对话框显示则我们的Web页面的焦点只能出现在当前的对话框元素中对话框之外的元素是不可能获取焦点的哪怕使用JavaScript代码强制聚焦也不行。也就是说整个网页中只有图所示的三个元素可以获得焦点。此特性极为稀缺因为如果想要使用JavaScript模拟仅存在理论上的可能性例如需要使用HTML inert属性让dialog以外的其他元素全部禁用这实在太复杂也不够优雅。2.2.6、顶层特性使用show()方法让对话框显示对话框元素的层级是由CSS样式决定的如果我们希望对话框元素的层级是最高的则往往需要设置一个数值较大的z-index属性值。而使用showModal()方法让对话框显示对话框元素的层级自动最高无需任何CSS样式设置此特性被称为顶层特性有个专门的名词描述此特性叫作top-layer。使用开发者工具查看dialog元素是可以看到此特性的如图所示。top-layer顶层特性实现的原理比较简单直接在窗体之外创建一个绘制图层如图所示​自然可以覆盖页面主体中的所有元素哪怕页面中的元素的z-index值设置到无穷大也如此。但是有时一个页面中可能不止一个dialog元素如果多个模态对话框同时显示那么层级规则又是怎样的呢2.2.7、自动层级特性如果一个页面中有多个对话框通过showModal()方法显示那么后显示的对话框层级一定最高这一点和传统的HTML元素不同。传统的固定定位元素如果不专门设置层级则一定是位于DOM树后面的元素的层级最高而模态对话框的层级高低与DOM位置无关与呈现的时机有关。比如下面这个例子页面中有两个dialog元素先显示第2个dialog元素再显示第1个dialog元素。你会发现如果使用的是showModal()方法则第1个dialog元素的层级在上面如图所示。如果使用的是show()方法则第1个dialog元素会在下面显示如图所示。眼见为实你可以通过在浏览器中输入地址https://www.htmlapi.cn/3/2-4.html访问来体验。综合上述7点介绍dialog元素显然不是普通的div元素可以模拟的无论是从用户体验的角度还是从开发成本的角度看只要想实现对话框效果毫无疑问一定优先使用dialog元素。2.3、原生弹层与popover属性虽然dialog元素强大好用但是对于一些需要敏捷交互的场景它就显得有些笨重例如当要实现点击按钮预览图片的效果时。如果用dialog元素实现那么我们需要给按钮绑定点击事件将图片元素放在dialog元素之中最后还需要专门写一个弹框关闭的方法。在移动端开发中由于屏幕尺寸有限很多交互效果都是通过弹层实现的其中有个重要的行为就是点击空白区域隐藏弹层而dialog元素的模态层点击是没有隐藏行为的因此预览图片的效果并不适合使用dialog元素实现。基于种种现实的需求一个全新的HTML属性出现了这个属性就是popover目前已经被各大现代浏览器支持并且是一个全局HTML属性。所谓全局HTML属性就是所有元素都可以设置的属性例如id、class或性能监控相关的elementtiming属性。有了popover属性我们只需要使用简单的CSS和HTML代码就可以在不使用任何JavaScript代码的情况下实现任意的基于屏幕定位的弹层效果。2.3.1、popover属性的基本使用popover属性的使用极为简单使用一个简单的案例就一目了然给需要弹出的元素设置popover属性给触发显示的按钮元素设置popovertarget属性其值等同于弹出元素的id属性值即可。此时点击该按钮图片就会以弹出框的形式出现其默认样式和dialog元素极为相似都有个粗的黑色边框如图所示。你可以通过在浏览器中输入地址https://www.htmlapi.cn/3/2-5.html访问来体验。虽说相似但仔细一看在具体的细节上还是有差异的包括popover弹层的内间距更小。popover弹层默认窗体居中且popover弹层元素是顶层元素如图所示。popover弹层默认的模态背景是透明且可穿透的如果希望有黑色半透明背景则需要使用::backdrop伪元素自定义例如popover弹层内容之外的区域点击后会自动关闭当前弹层无须额外的DOM事件支持注意此行为是可以自定义的。2.3.2、原生弹层相关的属性和方法除popover属性外还有一些相关的属性和方法。首先介绍一下全局属性popover的语法及几个全局的、和弹层显隐相关的API。popover属性支持两个值分别是’auto’和’manual’表示弹层的隐藏是自动触发的还是手动执行的。如果设置popover“manual”则弹层的隐藏需要手动执行此属性值多用在多个弹层同时出现的场景下。弹层的显示与隐藏除通过特定的元素外加特定的属性触发外还可以使用下面这三个全局方法。HTMLElement.hidePopover()HTMLElement.showPopover()HTMLElement.togglePopover()看API名称就可以知道什么意思了因此不展开介绍。接下来介绍触发弹层显示的几个HTML属性注意下面这两个HTML属性只能用在button元素和input元素上。popovertarget指向目标弹层元素的id属性值。如果希望知道目标弹层元素的DOM对象可以访问当前元素对象的popoverTargetElement属性获取。popovertargetaction支持’hide’、show或’toggle’这三个值表示点击按钮后弹层是显示还是隐藏对应的DOM对象属性是popoverTargetAction。最后我们还可以使用CSSpopover-open伪类匹配显示中的弹层元素不包括强制设置displayblock让弹层显示的情况以及使用beforetoggle和toggle事件感知弹层显隐状态的变化。2.3.3、popover属性模拟移动端下拉框了解了popover的特性和语法接下来就是实践环节了看如何模拟一个在移动端很常见的、如图所示的下拉框效果。在过去这种效果需要耗费大量的JavaScript代码而如今主要的工作则是在CSS样式的设置上包括将默认的居中效果改为居底以及设置黑色半透明背景色。假设HTML结构如下其中上半部分HTML是原生下拉框通过覆盖一个透明度为0的按钮来触发弹层的显示下半部分则是弹层部分使用radio类型的选择框模拟选择行为。接下来只需要下面几行JavaScript代码就足够了和过去的实现相比简单了不知道多少个数量级并且语义良好性能优异是绝对的最佳实践。对了差点忘记了最终的效果你可以通过在浏览器中输入地址https://www.htmlapi.cn/3/2-6.html访问来体验。
返回列表