首页前端开发其他前端知识HTML5的details、summary是什么,怎么实现交互效果

HTML5的details、summary是什么,怎么实现交互效果

时间2024-03-27 10:22:03发布访客分类其他前端知识浏览1097
导读:相信很多人对“HTML5的details、summary是什么,怎么实现交互效果”都不太了解,下面小编为你详细解释一下这个问题,希望对你有一定的帮助 本篇文章给大家带来的内容是关于利用HTML5的details, summa...
相信很多人对“HTML5的details、summary是什么,怎么实现交互效果”都不太了解,下面小编为你详细解释一下这个问题,希望对你有一定的帮助

本篇文章给大家带来的内容是关于利用HTML5的details, summary实现各种交互效果,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

本文利用的是HTML5 details, summary

首先

一、了解HTML5 details, summary默认交互行为

details> 标签在Chrome,Firefox等浏览器下默认是有展开收起行为的,例如下面HTML:

details>
    

    summary>
    这是摘要1/summary>
    

    p>
    这里具体描述,标签相对随意,例如这里使用的&
    lt;
    p&
    gt;
    标签。/p>
    

/details>
    

结果UI表现为:

具体描述为:

1、只显示了summary> 标签内容,而p> 默认隐藏了;

2、summary> 标签前面出现了一个小三角;

小三角图形的隐喻是:我是可点击的,点击我可能会出现宝箱。

OK,我们不妨就点击一下,结果如下图:

具体描述为:

  1. 原本隐藏的p> 标签显示出来了;

  2. summary> 标签前面的小三角方向朝下了;

此时我们再一次点击,p> 标签内容又会隐藏收起,箭头方向还原,如下图:


活脱脱一个天然的展开收起效果。

展开与收起是通过open属性控制的

通过在details> 标签上添加布尔类型的open属性,可以让我们的详情信息默认就是展开状态,如下HTML示意:

details open>
    
    summary>
    这是摘要2/summary>
    
    content>
    这里&
    lt;
    details&
    gt;
    标签设置了HTML布尔属性open,因此,默认是展开状态。/content>
    
/details>
    

结果如下截图:

如果我们使用JS脚本手动移除这个open属性,即使没有点击行为的发生,我们内容也会收起。

summary> 如果缺省

summary> 标签如果缺省,则details> 元素会在内部自动创建一个summary> 内容,默认的文案是“详细信息”。如下HTML代码:

details open>
    
    p>
    如果&
    lt;
    summary&
    gt;
    缺省,则会自动补上,文案是“详细信息”。/p>
    
/details>
    

结果如下截图所示:

二、details浏览器内置UI可以自定义

details> 标签默认的小三角样式有些简陋,在实际应用的时候,往往不是我们希望的样子,不要担心,我们是可以对其进行自定义的。在Chrome等浏览器下使用::-webkit-details-marker,在Firefox浏览器下使用::-moz-list-bullet可以对小三角进行UI控制,例如改变颜色,改变大小,使用自定义的图形代替,或者直接隐藏等,我们来看几个简单的案例。

案例1:小三角右侧显示同时颜色变淡

HTML代码如下:

details class="details-1" open>
    
    summary>
    这是示例1/summary>
    
    content>
    本案例展示对小三角UI重定义:包括显示在右侧,颜色减淡等。/content>
    
/details>

CSS如下:

.details-1 summary {
    
    width: -moz-fit-content;
    
    width: fit-content;
    
    direction: rtl;

}

.details-1 ::-webkit-details-marker {
    
    direction: ltr;
    
    color: gray;
    
    margin-left: .5ch;

}

.details-1 ::-moz-list-bullet {
    
    direction: ltr;
    
    color: gray;
    
    margin-left: .5ch;

}
    

结果如下图所示:

当我们点击摘要标题升起的时候,表现为下图(截自Firefox):

而实际上实际开发的时候,对小三角UI更便捷的定制方法是:隐藏浏览器原生的小三角,然后借助::before或::after伪元素重新生成我们想要的UI效果,下面这个案例就将展示相关的处理。

案例2:隐藏浏览器原生的小三角并使用自定义三角替换

HTML结构还是类似的:

details class="details-2" open>
    
    summary>
    这是示例2/summary>
    
    content>
    本案例隐藏原生小三角,使用自定义小三角。/content>
    
/details>
    

CSS主要分为2部分,一部分是隐藏浏览器原生的小三角,另外一部分是使用伪元素生成自定义的三角效果。

首先看一下隐藏details> 标签默认的小三角的CSS:

/* 隐藏默认三角 */
.details-2 ::-webkit-details-marker {
    
    display: none;

}

.details-2 ::-moz-list-bullet {
    
    font-size: 0;

}
    

可以看到Chrome浏览器和Firefox浏览器的小三角隐藏采用的是不同的策略。在Chrome浏览器下,我们可以直接设置display:none进行隐藏,但是这一招在Firefox浏览器下确实没有效果的,即使设置display:none!important也是如此,根据我的测试,只有font-size:0能够比较完美的隐藏。类似position:absolute; visibility:hidden这种常见的隐藏也是不行的,因为position:absolute无法生效。

然后是自定义小三角显示的CSS,这里采用的是::after伪元素模拟的:

/* 自定义的三角 */
.details-2 summary::after {
    
    content: '';
    
    position: absolute;
    
    width: 1em;
     height: 1em;
    
    margin: .2em 0 0 .5ch;
    
    background: url(./arrow-on.svg) no-repeat;
    
    background-size: 100% 100%;
    
    transition: transform .2s;

}

.details-2:not([open]) summary::after {
    
    margin-top: .25em;
    
    transform: rotate(90deg);
    
}
    

最终效果如下图所示:

收起时候:

最后有一点需要注意一下,就是如果details> 标签内并没有summary> 元素,则我们的对三角的自定义代码都是无效的,可以使用一个空的summary> 元素占位,类似这样:

details>
    
    summary>
    /summary>
    
    content>
    内容。/content>
    
/details>
    

三、Chrome浏览器下点击时候outline轮廓等体验处理

UI可以定制了,但是还有个不容忽视的体验问题,那就是在Chrome浏览器下点击时候会出现outline轮廓,如下图所示:

在实际项目开发的时候,产品和设计一定会让你把这个效果去掉的。以及,当我们summary> 元素点击较快的时候,文本会被选中,也不是我们想看到的。

阻止文本选中,我们可以:

summary {
    
  -webkit-user-select: none;
    
  -moz-user-select: none;
    
  -ms-user-select: none;
    
  user-select: none;

}

对于outline轮廓,比较直接的做法是:

summary {
    
  outline: 0;

}
    

但是这样处理对无障碍访问而是非常不友好的,那有没有什么办法兼顾视觉体验和无障碍访问体验呢?

我的做法是这样子的:

  1. 利用a> 标签的outline交互体验

浏览器对a> 标签元素的outline轮廓进行了专门的体验优化处理,鼠标点击的时候不显示轮廓,键盘访问时候显示轮廓。于是我们可采用李代桃僵策略,让summary> 元素的outline交给a> 元素,方法就是在summary> 中再内嵌一个a> ,同时通过tabindex属性remove掉summary> 原本的可访问性。HTML代码示意如下:

details open>
    
    summary tabindex="-1">
    a href="javascript:">
    这是示例/a>
    /summary>
    
    content>
    点击无外框,键盘focus有。/content>
    
/details>

CSS如下:

summary {
    
    user-select: none;
    
    outline: 0;

}

summary a {
    
    color: inherit;

}
    

此时,在Chrome浏览器下,我们点击摘要信息,没有任何outline轮廓出现;但是当我们使用Tab键索引时候,可以看到下图所示的轮廓效果:

轮廓区域比原生的summary> 要小,但这无伤大雅,而且实际项目开发的时候,我们会去掉小箭头,此时只要设置a> 标签display:block,则轮廓就可以和summary> 保持一致了。

接下来,我们按下Space空格键,就会发现details> 元素内的内容信息不断的展开与收起:

然后上面实现并不完美,相比原生的summary> 元素,Enter回车键展开收起效果丢失了。这是因为HTML元素中如果多个focusable同时带click浏览器行为元素嵌套的时候,点击里面的元素,外部元素的浏览器行为是不会触发的。类似的有label> 内嵌a> 标签。

对于a> 标签,其浏览器行为只能通过回车键触发,空格键是无效的;但是对于summary> ,回车键和空格键都能触发展开收起行为,这就是为什么上面代码空格键有效,回车键无效的原因。

如果想要同时支持回车键展开与收起,可以对HTML如下处理:

details open>
    
    summary tabindex="-1">
    a href="javascript:" onClick="this.parentNode.click();
    ">
    这是示例/a>
    /summary>
    
    content>
    点击无外框,键盘focus有。/content>
    
/details>
    

需要注意的是上面处理在summary> 自己额外绑定click事件时候可能会有double触发的问题,此时,阻止a> 元素的冒泡即可。

  1. JS捕获键盘行为手动设置outline

这个方法不需要对HTML进行任何的改动,是通过CSS和JS配合对全局的summary> 元素进行outline优化。

CSS如下:

summary {
    
    user-select: none;
    
    outline: 0;

}

summary[focus] {
    
    outline: 1px dotted;
    
    outline: 5px auto -webkit-focus-ring-color;

}

JS如下:

window.addEventListener('keydown', function () {
        
    window.isKeyEvent = true;

    setTimeout(function () {
    
        window.isKeyEvent = false;

    }
    , 100);
    
}
    );


document.addEventListener('focusin', function (event) {
    
    var target = event.target;
    
    if (target &
    &
     target.tagName.toLowerCase() == 'summary' &
    &
 window.isKeyEvent == true) {
    
        target.setAttribute('focus', '');

    }

}
    );

document.addEventListener('focusout', function (event) {
    
    var eleFocusAll = document.querySelectorAll('summary[focus]');

    [].slice.call(eleFocusAll).forEach(function (summary) {
    
        summary.removeAttribute('focus');

    }
    );

}
    );
    

只要把上面的CSS和JS复制到页面中,视觉体验和交互体验完美支持的summary> 元素outline效果就有了。

表现为,点击summary> 没有任何outline,键盘focus时候出现,且和浏览器原生outline效果一模一样,Space键和Enter键展开与收起访问完全保留。

例如下图就是键盘Tab键focus后回车后的效果:

每每看到如此极致的用户体验处理,心情都大好。

原理:
关键是全局监听keydown事件,如果有发生,则认为此100毫秒内的页面focus行为均是键盘产生,从而有效区分是点击触发的focus行为还是键盘触发的focus行为,如果是键盘触发,给summary> 元素手动增加outline效果。

四、基于details元素行为的各种交互效果案例

了解了details> 元素的点击交互行为;解决了UI定制难题;解决了outline的体验问题,下面我们就可以付诸实践,不借助任何JS来实现各种我们平常见到的交互效果。

案例1:“更多”展开与收起效果

实现最终效果如下gif:

因为“更多”元素是在底部,因此效果实现的要点的所有的内容信息都放在summary> 元素内部,然后通过details> 元素的open属性控制UI的变化。

HTML和CSS代码如下,其中,最核心部分已经红色高亮:

details>
    
    summary>
    
        p>
    据台媒报道,大...青睐。/p>
    
        p class="more">
    
            p>
    其他几首歌曲.../p>
    
        /p>
    
        a>
    更多/a>
    
    /summary>
     
/details>

::-webkit-details-marker {
    
    display: none;

}

::-moz-list-bullet {
    
    font-size: 0;
    
    float: left;

}

.more {
    
    display: none;

}

[open] .more {
    
    display: block;

}

[open] summary a {
    
    font-size: 0;

}

[open] summary a::before {
    
    content: '收起';
    
    font-size: 14px;

}
    

把“更多”对应的信息放在.more元素内,然后通过[open]属性选择器控制器显示,效果即达成。

案例2:无JS实现点击显示悬浮菜单,自定义下拉框等效果

效果如下gif:

没有任何JS参与。HTML结构如下:

details>
    
    summary>
    我的消息/summary>
     
    div class="box">
    
        a href>
    我的回答sup>
    12/sup>
    /a>
    
        a href>
    我的私信/a>
    
        a href>
    未评价订单sup>
    2/sup>
    /a>
    
        a href>
    我的关注/a>
    
    /div>
    
/details>
    

然后CSS让.box元素绝对定位即可,显示和隐藏details> 元素内置行为就搞定了。

案例3:accordion多项折叠效果

此效果常见于条目比较多的垂直导航栏,新闻条目等。

例如下面实现的效果:

这个更加简单了,就是一堆details> 元素并排放置就可以了,如下HTML:

details open>
    
    summary>
    dt>
    订单中心/dt>
    /summary>
     
    dd>
    a href>
    我的订单/a>
    /dd>
    
    dd>
    a href>
    我的活动/a>
    /dd>
    
    dd>
    a href>
    评价晒单/a>
    /dd>
    
    dd>
    a href>
    购物助手/a>
    /dd>
    
/details>
    
details open>
    
    summary>
    dt>
    关注中心/dt>
    /summary>
     
    dd>
    a href>
    关注的商品/a>
    /dd>
    
    ...
/details>
    
details open>
    
    ...
/details>
    

计算CSS没有任何设置,效果也天然达成。

案例3中的展开项显示的时候是非常生硬的突然显示,实际上我们可以借助一些选择器技巧以及CSS3 transition属性让菜单展开收起的时候是有动画效果的,效果如下gif截图:

此效果实现原理核心是[open]属性选择器,和加号+相邻兄弟选择器。

首先看下HTML,展开列表结构发生了变化,不是作为details> 的子元素,而是作为其相邻兄弟元素存在,HTML示意:

details open>
    summary>
    订单中心/summary>
    /details>
    
dl>
    
    dd>
    a href>
    我的订单/a>
    /dd>
    
    dd>
    a href>
    我的活动/a>
    /dd>
    
    dd>
    a href>
    评价晒单/a>
    /dd>
    
    dd>
    a href>
    购物助手/a>
    /dd>
    
/dl>
    
...

上面dl> 定义列表就是展开收起的内容,其作为兄弟元素和details> 元素平起平坐,于是,我们就可以利用点击summary> 元素details> 元素的open属性会变化的特性实现我们想要的动画效果,CSS如下:

details + dl {
    
    max-height: 0;
    
    transition: max-height .25s;
    
    overflow: hidden;

}

[open] + dl {
    
    max-height: 100px;

}
    

借助相邻兄弟选择器以及max-height任意元素slideUp/slideDown技术就可以效果达成。

案例5:多级嵌套的树形菜单交互效果

这里的树形菜单效果实现也很简单,多个details> 元素相互嵌套就可以,效果Gif如下:

HTML结构大致如下:

details>
    
    summary>
    我的视频/summary>
    
    details>
    
        summary>
    爆肝工程师的异世界狂想曲/summary>
    
        div>
    tv1-720p.mp4/div>
    
        div>
    tv2-720p.mp4/div>
    
        ...
        div>
    tv10-720p.mp4/div>
    
    /details>
    
    details>
    
        summary>
    七大罪/summary>
    
        div>
    七大罪B站00合集.mp4/div>
    
    /details>
    
    div>
    珍藏动漫网盘地址.txt/div>
    
    div>
    我们的小美好.mp4/div>
    
/details>

CSS的主要工作就是绘制菜单前面的加号和减号图形,例如我们可以借助background线性渐变,相关CSS如下:

details {
    
    padding-left: 20px;

}

summary::before {
    
    content: '';
    
    display: inline-block;
    
    width: 12px;
     height: 12px;
    
    border: 1px solid #999;
    
    background: linear-gradient(to right, #999, #999) no-repeat center, linear-gradient(to top, #999, #999) no-repeat center;
    
    background-size: 2px 10px, 10px 2px;
    
    vertical-align: -2px;
    
    margin-right: 6px;
    
    margin-left: -20px;

}
    
[open] >
 summary::before {
    
    background: linear-gradient(to right, #999, #999) no-repeat center;
    
    background-size: 10px 2px;

}
    

效果即达成!

五、如果只想要details/summary的语义不要行为

如果只想要details> 元素,summary> 元素的语义,但是并不需要点击展开收起的行为,该怎么处理呢?

例如,某评论,或者某帖子有标题和正文,非常符合详情-概要-内容的语义,但是希望是纯展示的,点击时候不收起,可以这么处理:

1.summary> 标签设置tabindex="-1"让键盘无法访问;
2.设置CSS:

summary {
    
  outline: 0;
    
  pointer-events: none;

}
    

这样就不能点,也不会有outline轮廓。

六、兼容性以及Polyfill

兼容性如下图:

除了IE和Edge浏览器,大好河山一片绿,至少移动端可以用得比较开心。

如果想要在桌面web网页使用details> 元素的棒棒哒特性,我们可以对其进行Polyfill

对键盘访问,事件toggle都做了兼容。

如果开发策略是对不支持的IE进行特异处理,则下面的JS判断是否支持details> 元素的脚本可能对你有用:

var isSupportDetails = 'open' in document.createElement('details');

最后,无JS实现的好处有:

省了代码,加载快了;
实现更简单了,开发快了;
JS还没加载交互也能进行,体验好了;
键盘无障碍和aria阅读设备无障碍天然支持,体验档次高了。



通过以上内容的阐述,相信大家对“HTML5的details、summary是什么,怎么实现交互效果”已经有了进一步的了解,更多相关的问题,欢迎关注网络或到官网咨询客服。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

javascripthtml5

若转载请注明出处: HTML5的details、summary是什么,怎么实现交互效果
本文地址: https://pptw.com/jishu/654156.html
JAVA中对象和字节数组互转的过程方法是什么 java中super关键字使用的几种方法分别是什么?

游客 回复需填写必要信息