最近把HTML5测验系列做到了第五期,前四期我基本都在折腾基础标签、CSS协作和整体布局,这一期我特意换了方向。大家后台问得最多的几个话题,一个是不同浏览器对HTML5播放器的支持差异,一个是Canvas特效里那些看起来简单、实际容易翻车的细节,还有一个是HTML5网页设计的日常习惯。我把这些整理成了一份相对完整的测验题,前两天自己先做了一遍,又让团队里两个刚入门的前端小伙伴试了试,发现确实能把不少平时不注意的盲区给测出来。
这套题一共三大块:单选题、判断题,再加一道偏实操的代码补全题。单选题主要覆盖语义化、表单、多媒体和基础API,判断题针对的是兼容性和使用习惯这类容易混淆的细节,代码题则选了Canvas动画里最常见的两个场景来练手。无论你是刚学完HTML5基础,还是已经在写页面但又想查漏补缺,都可以直接往下做。建议你准备一个编辑器,边做边验证,比单纯看答案记得牢。
1. 这次测验我在考什么
1.1 为什么这一期选了这些方向
第五期和前几期最大的不同,是我放弃了那种一条一条背标签的考法。标签记不住翻文档就行,真正让前端头疼的是"我记得这个标签,但实际一跑就出问题",尤其是播放器兼容和Canvas渲染这两块,教科书里一句话带过的坑,实战里能让你调一晚上。所以这一期我刻意把题目往"边界情况"上引:多格式视频源怎么写、localStorage的存储类型限制、canvas画布尺寸和CSS尺寸不一致会发生什么。
另外,热搜词里出现了一堆和"html5网页设计"、"html5 school"相关的搜索,说明很多人在系统补课。我的想法是,测验的意义不在于把题目做对,而是通过题目把知识点串起来。比如考到video标签,你不仅要会写controls,还要知道什么情况下需要三个不同格式的source,连浏览器解码策略都能顺带聊上几句,这才叫把知识学活了。
1.2 题量和难度怎么安排的
整套卷子单选题15道、判断题5道、代码补全2道,满分100分,单选题每道5分,判断题每道3分,代码题一共20分。难度我刻意做了梯度设计:前5道是送分题,保证基础扎实的人能拿住;中间5道开始需要一点实战经验;最后5道基本就是"看起来都会,一做就错"的陷阱题。
后面章节我会按题型逐条过,每道题直接给出答案和解析,解析里我会明确告诉你这个知识点在实际开发中的场景。如果你在做题过程中卡住了,千万不要急着看答案,先自己在浏览器里跑一下。HTML5最大的特点就是"所见即所得",动手验证一次,比你背十遍文档都管用。
2. 单选题:核心知识自测
2.1 语义化与结构标签
第1题:在HTML5页面中,以下哪个标签最适合用来标记页面侧边栏区域?
A. sidebar
B. side
C. aside
D. section
这道题是我设置的开胃菜,但也是面试里高频出现的送分题。正确选项是C。很多人下意识习惯性写div加class,这在功能上没毛病,但对搜索引擎和屏幕阅读器来说,aside就是比div class="sidebar"更明确地告诉它们"这里是辅助内容区域"。
顺带说一个容易被忽略的点:aside不仅能表示侧边栏,它还可以嵌套在主内容的内部,表示一段与正文主题相关但相对独立的补充信息,比如文章里的术语解释框、引用来源、广告位。你如果只用它来做页面级的侧边栏,就有点大材小用了。实际开发里我会优先问一句:这个aside是全局布局的一部分,还是某篇文章内的补充块?两种场景的语义层级完全不同。
第2题:请选出正确的语义化标签组合。
A. header、nav、main、footer
B. head、nav、mian、foot
C. header、navigation、main、bottom
D. heading、navigator、master、ending
答案毫无疑问是A。这里我不打算解释为什么选A,反而想说说另外几个选项的错误点:head是页面元信息容器,跟header完全是两回事,有的老项目里也会出现navigation这种写法,但HTML5自定义标签里只有nav,没有navigation。footer很多人会记成foot,实际上foot是table里的一个分组,和footer不等价。
更重要的是语义化标签的使用层级。比如header在页面上可以使用多次,文章头、区块头都可以用header,footer同样可以出现多次,每个article里都可以有自己的footer。很多初学者的问题在于以为整个页面只能有一个header和一个footer,这是对语义化最常见的误解。
第3题:figure元素与figcaption元素搭配使用,主要目的是什么?
A. 给图片增加动画效果
B. 让图片和标题说明形成语义上的组合
C. 代替img标签显示图片
D. 对图片进行压缩处理
正确选项是B。figure用来包裹一张图片、一段代码、一个图表甚至一段音频,figcaption提供对应的说明文字。这样做的好处是,图片和说明在语义上成为一个整体,浏览器或辅助工具能正确解析两者的从属关系,而不是靠一个div包着碰运气。
做博客或者写技术文档的时候,这个组合非常实用。我处理代码示例截图经常会这样组织:多张图片放进一个figure里,配一段统一的figcaption,在移动端适配和RSS输出时,结构会比散落的div清晰得多。
第4题:关于 标签,下列说法正确的是?
A. 一个页面可以包含多个main标签
B. main标签应该包含页面上所有内容,包括导航和版权信息
C. 一个页面建议只使用一个main标签,且不应嵌套在article、aside、header、footer内部
D. main标签必须放在body的最前面,否则浏览器不识别
答案是C。main标签的特点就是"一页一主",它代表页面的主要内容区域。除开那些重复出现的导航、侧边栏、页脚信息之外,文档的核心内容都放在main里。多数浏览器对main的默认样式几乎没区别,真正的价值还是语义,而且它在排列页面结构的可访问性上能起到"跳过导航直达内容"的作用。
顺便提一个细节:main不能作为article、aside、header、footer、nav的子孙节点,这是规范明确规定的。我见过有的页面把article整个内容塞进main,然后又单独搞一个main在底下,这种写法明显不符合语义。
第5题:以下哪项不是HTML5新增的语义化标签?
A. section
B. article
C. nav
D. frame
这道题答案是D。frame其实是非常老的框架集标签,HTML5早已废弃,它跟iframe完全不同。section、article、nav都是HTML5为了改善文档结构而新增的。这道题的陷阱在于,section看起来"好像以前也有",其实在HTML4里根本没有section这个标签,那时候大家习惯用div或fieldset凑合。
2.2 表单与输入类型
第6题:以下哪个input类型不是HTML5新增的?
A. email
B. number
C. password
D. date
选择C。password从HTML4时代就存在了,而email、number、date都是HTML5新增的类型。这道题不算难,真正有水平的是后面的延伸:当你在移动端使用input type="email"时,iOS键盘会自动切换成带@和.的邮件键盘;type="number"在部分浏览器里会有上下步进按钮,触发行为随着环境不同表现也不同。日期类型更是优先建议用原生的date,而不是自己封装选择器。
我实际写表单时有个习惯:能用语义input类型解决的,绝对不自己写JS弹层。原生的值校验、键盘适配、无障碍交互,都是现成的,自己折腾反而容易出兼容问题。
第7题:HTML5表单中,用于在提交前校验必填项的属性是?
A. validate
B. required
C. must
D. check
答案B。required是HTML5表单验证体系里最简单粗暴的一个属性。你给input加上required后,浏览器会在提交时自动阻止空值提交,并弹出提示气泡。但它不是万能的,一个常见问题是:隐藏域或display:none的元素如果加了required,部分浏览器会跳过校验,这在SPA里很容易踩到。
这里补充一个常被忽略的知识点:表单验证的触发条件是"表单提交",如果是用JS直接读取元素值而不是走submit流程,require只是摆设。此外,自定义校验规则需要用到pattern属性加正则,和required配合使用。
第8题:在PC端网页设计里,想要限制用户只能输入数字且最多两位小数,最佳方案是?
A. type="text" + 一堆正则判断
B. type="number" + step="0.01" + min和max配合
C. type="range"
D. type="tel"
答案是B。number类型配合step可以控制精度,比如step="0.01"表示每次增减0.01,也代表允许的最小精度单位。min和max可以约束取值范围,配合required和浏览器原生校验,能省掉大量重复的JS代码。
但这里有个经验之说:number类型在PC端虽好用,在移动端弹出的数字键盘反而有部分机器不支持小数符号,容易把"0.5"输入成"05"。所以我通常会在移动端页面考虑用inputmode="decimal"配合type="text",这个取舍你要根据目标用户设备的分布来判断。
第9题:关于placeholder属性,下列说法错误的是?
A. placeholder可以作为输入框的默认值提交到服务器
B. placeholder提示文字在用户输入内容后自动隐藏
C. placeholder的颜色可以用CSS的::placeholder伪元素修改
D. placeholder不适用于所有input类型
答案是A。placeholder只是视觉提示,绝对不会跟着表单一起提交。如果想给输入框设置初始值,应该用value属性。这个错误我在项目review里见过很多次,有人把提示信息当成默认值去做编辑功能,结果一提交就是空字符串。
另外提示一个样式细节:不同浏览器的::placeholder默认颜色不太一样,Firefox低版本和Chrome的灰色深浅有区别,设计稿如果对颜色要求严格,一定要显式设置::-webkit-input-placeholder和::-moz-placeholder。
第10题:HTML5新增的datalist元素的作用是?
A. 渲染一个下拉选择框
B. 为输入框提供一组预定义的候选项,但又允许用户自由输入
C. 定义页面列表的数据源
D. 用来替代select
答案B。datalist更像是一个输入联想器,它和input配合,input会有一个下拉建议列表,但用户仍然可以输入任意内容。select则是严格的选择框,不能自由输入。所以我经常把datalist用在"搜索框联想"或"标签输入"的场景,而不会用它来替代真正的业务下拉选择。
需要注意的是,datalist在不同浏览器中的交互表现差异比较大,键盘操作、鼠标点击的触发宽度都不一样,如果你完全依赖它做搜索联想,最好在上线前做一轮跨浏览器实测。
2.3 多媒体与浏览器兼容
第11题:在HTML5中,为了让video标签在不同浏览器上都能正常播放,推荐的写法是?
A. 只使用mp4一种格式,因为所有浏览器都支持
B. 使用多个source标签按顺序提供mp4、webm和ogv,并设置type属性
C. 直接嵌入FLV格式
D. 将视频转换为gif后使用img显示
回答这道题,B是正确的。不同浏览器对HTML5播放器的支持情况一直是老生常谈:Chrome和Firefox对WebM支持好,Safari和iOS对MP4更友好,而老Edge还需要多考虑一层。你只给一种格式,总有一部分用户打不开。最稳妥的办法是至少准备MP4和WebM两种格式,按需加上OGV兼容复古环境。source标签的type属性不是摆设,浏览器会先读type,判断自己能不能解码,没法解码就直接跳过,不会傻乎乎把整个文件下载完再报错。
这里要强调一个实践细节:source的顺序会影响最终选择,浏览器会选择第一个它能播放的源。所以通常把兼容性最广的MP4放最前面,后面再放WebM。如果视频只有一种格式,又希望兼容所有浏览器,也可以通过前端引入polyfill或者依靠第三方player库做降级,不过这不是最优雅的方案,能源头准备多格式才是正道。
第12题:关于video标签的preload属性,下列说法正确的是?
A. preload="auto"表示视频一打开立刻自动播放
B. preload="none"表示不加载任何视频数据,点击播放时才加载
C. preload="metadata"表示只加载第一帧画面
D. preload的值对性能没有任何影响
正确选项是B。preload有三个值:none、metadata、auto。auto表示浏览器会在页面加载后尽量预加载整个视频;metadata表示只加载元数据,比如时长、分辨率等;none就是完全不预加载,用户点了播放按钮才开始请求数据。它和autoplay是两码事,autoplay才是真正的自动播放。
实际项目中,视频不是首屏核心资源的时候,我会一律用preload="none"或者metadata,省流量也省带宽。首屏要展示的视频才考虑auto,但要注意auto只是建议,最终决定权在浏览器手里,移动端通常会被系统策略强制限制。
第13题:在canvas中绘制动画帧时,最推荐使用哪个API来替代setTimeout实现平滑动画?
A. setInterval
B. requestAnimationFrame
C. sleep
D. setImmediate
答案B。requestAnimationFrame是浏览器专门为动画设计的帧回调函数,它会跟随显示器的刷新率(一般是60Hz)来触发回调。相比setTimeout和setInterval,它的优势很明显:页面切换到后台时会自动暂停,不浪费CPU;每次回调的间隔更精准;多个动画还可以被浏览器合并布局。
我在做html5爱心烟花特效这类Canvas动画时,核心循环几乎全是requestAnimationFrame。它的callback参数会传入当前时间戳,便于计算动画进度,配合canvas的clearRect实现每帧重绘,流畅度和资源占用都优于老式写法。如果你之前只用setTimeout做过动画,建议尽快切换过来。
第14题:localStorage和sessionStorage的区别,以下说法正确的是?
A. localStorage存的数据在浏览器关闭后会被清除
B. sessionStorage的数据在关闭标签页后会丢失,localStorage则持久保存
C. 两者的存储数据类型都支持对象直接存入
D. localStorage的容量上限是100MB
正确的是B。sessionStorage的生命周期是"标签页",页面关了数据就没了;localStorage是持久化的,除非主动删除或者用户清除浏览器数据,否则一直存在。关于C选项是个很大的陷阱:localStorage和sessionStorage都只能存字符串。你直接存一个对象进去,浏览器会用toString()把它变成"[object Object]",取出来就废了。正确的做法是JSON.stringify序列化后再存,取值时再JSON.parse解析。
至于D选项,各浏览器的限制不一样,一般在5MB到10MB之间,远远不到100MB。跨浏览器开发时,别指望大数据量往里塞,更不要在它里面存什么敏感信息,因为同源策略下任何同源的脚本都能读取。
第15题:关于HTML5的Web Worker,下面的描述错误的是?
A. Web Worker可以在后台线程执行JavaScript
B. Web Worker内可以使用window对象
C. Web Worker适合处理大量计算密集型的任务
D. 主线程与Worker之间通过postMessage通信
答案B。Web Worker运行在一个独立线程里,没有window对象,也不能直接操作DOM。它能访问的是一组受限的全局对象,比如self、XMLHttpRequest、Fetch、部分定时器。因为不能操作DOM,它才是"计算密集型任务"的好去处,比如图片处理、大量数据运算、生成PDF等,都可以丢到Worker里做,避免卡住主线程导致页面白屏。
我记得之前做html5网页设计时,有一个页面需要实时计算大量坐标数据,直接把计算放主线程,滚动时掉帧明显,后来把算法迁移到Worker里,消息通信传递数据,体感一下子顺畅了。这道题能帮你确认一个认知:Worker不是为了"多线程并发炫技",而是为了不阻塞UI渲染。
3. 判断题:兼容性与设计习惯考核
3.1 播放器兼容判断题
第1题:不同浏览器对HTML5播放器的支持情况完全一致。
答案是"错误"。这句话放到2015年左右还勉强能说"基本一致",但现在的格局早就变了。Safari偏HLS和MP4,Chrome偏好WebM和MP4,Firefox和Edge各有一些细微差别。而且还有格式内部的编码问题,同样是MP4,H.264编码和HEVC编码在不同平台的硬解支持也完全不同。
我自己的排查习惯是:做视频播放器之前,先查一下目标用户用什么浏览器居多,再决定渲染策略。如果只是做官网的演示视频,MP4一份基本能覆盖绝大多数场景;但如果做在线教育这类重度视频依赖的产品,至少准备MP4加WebM,并且要有一个兜底提示,告诉用户"当前浏览器不支持直接播放,请下载或更换浏览器"。另外,iOS上无论如何用video标签内嵌,系统会自动进入全屏播放,这和Android上又不一样,这些都是做播放器时需要提前做的兼容测试案例。
第2题:video标签中,如果设置了autoplay,视频会在页面加载后自动开始播放,且不受浏览器策略限制。
答案是"错误"。autoplay属性存在,但浏览器普遍有自动播放策略:大多数桌面浏览器要求视频静音才允许自动播放,或者需要用户先跟页面有过交互(点击、滚动等)才放行。移动端的限制更严格,基本只有muted的自动播放会被允许。
所以当你实现"打开页面就播放背景视频"这类需求时,常规做法是video标签加muted + autoplay + playsinline三个属性一起上,然后让用户手动点一个按钮开启声音。这个"静音播放、点击开声"的模式,几乎成了所有带声音背景视频网站的标配方案。
3.2 Canvas与特效判断题
第3题:在canvas上绘制爱心烟花等特效时,每次动画帧都应该先清除上一帧的画面,再重新绘制。
答案是"正确"。Canvas的绘制模式是画笔式的,画上去的内容不会自动消失。如果你不清除画布,动画会出现残影,这在爱心烟花、粒子系统等特效里是灾难性的。清除画布最常见的方法是clearRect(0, 0, canvas.width, canvas.height),或者使用width=canvas.width重置画布宽度来间接清屏。
但这里也有一个容易被忽略的问题:clearRect每次清除后,canvas的绘图状态、填充样式、变换矩阵都会被保留,但如果你用canvas.width重置,会把canvas的上下文状态也全部重置,包括fillStyle、strokeStyle、transform这些。所以清屏方式的选择不仅仅是性能问题,还是状态管理细节,做复杂特效时一定要规划好。
第4题:canvas的width和height属性与CSS设置的宽高完全等价。
答案是"错误"。canvas的width和height是画布的实际分辨率,CSS的width和height只是显示尺寸。如果两者不一致,画布会被拉伸缩放,出现图形发虚、文字模糊的情况。比如canvas.width设为300、CSS设为600,等于把一个300像素宽的图像强行拉大到600像素,放大糊掉是必然的。
制作H5里的圣诞贺卡时,我的做法是:先用一个变量记录画布的物理尺寸,做成响应式,在高分屏设备上还可以按devicePixelRatio缩放画布,保证清晰度。很多人觉得Canvas特效糊是电脑配置问题,其实多半是这块画布尺寸逻辑没处理好。
第5题:把本地存储localStorage里的数据删除时,只能通过调用removeItem方法实现。
答案为"错误"。localStorage删除数据有几种途径:removeItem可以删单个键值对;clear可以清空当前源下所有键值对;直接用delete操作符删属性也能生效。另外,用户在浏览器设置里清除站点数据也可以全清。所以如果你只记住了removeItem,碰到批量清理时就会绕远路。
此外还有一个偏门技巧:localStorage的key和value都要求是字符串,但setItem可以把函数toString后存进去,这个一般不会用,知道有这回事就行。
4. 实操题:代码补全与纠错实战
4.1 视频播放器兼容写法补全
这道题我给了学生一段不完整的HTML,要求补全一个能兼容不同浏览器的视频播放结构。原始代码如下:
<video id="introVideo" controls preload="metadata" poster="poster.jpg"> <!-- 在这里补全多格式视频源 --> </video>需要补全的是两个source标签,分别指向intro.mp4和intro.webm,并带上正确的type。参考写法:
<video id="introVideo" controls preload="metadata" poster="poster.jpg"> <source src="intro.mp4" type="video/mp4"> <source src="intro.webm" type="video/webm"> <p>您的浏览器不支持HTML5视频播放,请更换浏览器或下载视频观看。</p> </video>这里的三段结构各有意义:首先,source的src和type必须写对,浏览器靠type快速判断是否能解码,避免不必要的下载;其次,preload="metadata"是为了加载第一帧画面和时长信息,同时又不一次下载全片;最后,video内的文本是兜底提示,当浏览器完全不支持的时候显示。还有一个细节:不要忘了给video设置poster,否则视频第一帧没加载出来时会显示一片黑,影响视觉体验。
4.2 Canvas爱心烟花特效的核心绘制流程
我先给出一段残缺的代码,让大家补全初始化、清屏和动画循环三步:
const canvas = document.getElementById('fireCanvas'); const ctx = canvas.getContext('2d'); canvas.width = 600; canvas.height = 400; function drawParticle(particle) { ctx.beginPath(); ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2); ctx.fillStyle = particle.color; ctx.fill(); } function update() { // TODO: 1. 清空画布 // TODO: 2. 更新所有粒子的位置 // TODO: 3. 遍历粒子并调用drawParticle requestAnimationFrame(update); }补全后的核心逻辑是:
function update() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach((p) => { p.x += p.vx; p.y += p.vy; p.vy += gravity; p.life -= 1; }); // 过滤掉生命周期结束的粒子 particles = particles.filter((p) => p.life > 0); particles.forEach((p) => drawParticle(p)); requestAnimationFrame(update); }为什么顺序这么重要?你看,如果先画再清屏,那一帧的内容就会被擦掉,视觉上会闪烁。而如果没有重力因素对vy的累加,烟花粒子会一直沿直线飞出去,没有那种抛物线的效果。还有,过滤掉life小于0的粒子是防止数组无限膨胀,否则动画跑几分钟后,粒子数量堆积得越来越离谱,浏览器直接卡死。做html5爱心烟花特效,这几点都是核心。
5. 完整答案与踩坑心得
5.1 答案速查对照表
这份表格可以对照自测,省得你翻回去对:
| 题号 | 答案 | 核心考点 |
|---|---|---|
| 第1题 | C | aside的语义表示 |
| 第2题 | A | 语义化标签正确写法 |
| 第3题 | B | figure/figcaption的作用 |
| 第4题 | C | main的唯一性 |
| 第5题 | D | 废弃标签frame |
| 第6题 | C | 新增input类型 |
| 第7题 | B | required必填校验 |
| 第8题 | B | number配合step |
| 第9题 | A | placeholder不提交 |
| 第10题 | B | datalist自由输入 |
| 第11题 | B | 多source兼容方案 |
| 第12题 | B | preload的含义 |
| 第13题 | B | requestAnimationFrame |
| 第14题 | B | 存储生命周期 |
| 第15题 | B | Worker无window |
| 判断第1题 | 错误 | 播放器支持不同 |
| 判断第2题 | 错误 | 自动播放受限 |
| 判断第3题 | 正确 | 动画清屏 |
| 判断第4题 | 错误 | 画布尺寸不等于CSS尺寸 |
| 判断第5题 | 错误 | 多种删除方式 |
对完答案你会发现,真正的扣分重灾区集中在浏览器兼容题和Canvas的状态管理题上。这两个都不是靠背能解决的知识点,非要在真实浏览器里跑一遍才能形成肌肉记忆。
5.2 这一期最容易失分的三个点
第一个失分点是第11题的source顺序。我见过不少新手把webm放在mp4前面,理由是"想优先用更新的格式",但放在前面就意味着浏览器会先去试探这个格式,部分浏览器如果解码器加载慢,会出现短暂的等待。别看这只是顺序问题,实际用户体感会有差别,特别是弱网环境。稳妥起见,mp4永远放第一顺位。
第二个失分点是Canvas清屏时用canvas.width重置还是用clearRect。我用clearRect通常是在动画里,因为不会重置上下文属性;而canvas.width重置更适合一次性彻底重来,比如画布尺寸改变时。如果你混淆了这两个场景,很容易出现"颜色画着画着突然变回黑色"的诡异问题。实际上canvas.width重置后,所有绘制状态都会回到默认值,你要重新设置fillStyle、lineWidth,很多人就是在这里被坑的。
第三个失分点是localStorage存对象时的序列化和反序列化。直接在setItem时传对象看起来"没报错",但是取出来以后你用obj.name或者obj.id去访问,拿到的是undefined。这个排查方向很明确,但还是那个问题,没实际踩过一次坑的人,很少会第一时间想到数据是被转成字符串了。
5.3 做完这套题之后,我的个人建议
如果你这套题拿到了80分以上,说明HTML5基础已经比较扎实了,下一步可以去折腾更加工程化的方向,比如组件化开发时语义化标签怎么拆分,多媒体播放器怎么结合流媒体协议做自适应码率,Canvas动画怎么抽离成通用的粒子系统。这些都是从"会写页面"进阶到"能设计页面架构"的必经之路。
如果在60分到80分之间,也不用焦虑。我建议你把错题涉及的章节重新过一遍,重点做一做浏览器兼容性矩阵的整理:自己建一个页面,把video、audio、canvas、localStorage、datalist这些特性各写一个demo,然后分别在Chrome、Firefox、Safari、Edge里逐个打开,记录差异。这份自己的笔记比任何教程都管用,因为它是针对你关注场景的实测结果。
如果在60分以下,大概率是对HTML5的整体结构还没有形成系统认知。可以先回到语义化标签和表单这块,用一周时间把基础标签一个个过一遍,每个标签都实际写一个能运行的小例子,然后再回头看这套题。HTML5不是纯理论学科,代码写多了,很多"规则"自然就内化成习惯了。
我自己做HTML5测验系列这一路的体会是:每五期设一个复盘节点很有效。前四期积累下来的零散问题,会在第五期这些综合题上集中暴露出来,比如我之前一直没有留意video的playsinline在iOS上的作用,直到这次把播放器兼容题彻底研究透,回去翻自己的老项目才发现确实漏了属性。技术在往前走,浏览器也在更新,每隔一段时间用这种测验的方式把自己的知识结构重新扫一遍,真的是投入产出比很高的学习方式。