我最近3个月的前端专业学习记录

以下内容是2023年7月17~10月16日自己每周学习的记录

第29周 7.17-7.23

这周在项目中使用了一种新的布局。

就是下图所示的布局效果。

在过去,这种图片固定比例的,宽度自适应的布局都至少只要2层以上的标签,这一次,使用了容器元素和全新的cqw单位,可以一层标签即实现最终的效果。

相关实现已经整理成文,有兴趣可以访问这里:"CSS高宽不等图片固定比例布局的三重进化"。

第30周 7.24-7.30

本周研究了了一个新的CSS属性text-wrap,目前仅Chrome浏览器支持,兼容性如下图所示:

其中名为balance的属性值很有趣,可以让div元素中的内联元素尽可能宽度一致排列,布局差异如下所示:

这个属性其实很有用,例如类似朋友圈点赞的那种布局效果,目前的实现都是优先第一行显示的。

有了text-wrap:balance属性后,就可以是下图所示的布局效果,体验会更好。

更多内容可以访问这里了解

第31周 7.31-8.6

在做项目的时候,偶然看到有同事的CSS代码中对samp标签样式进行了定义,然后研究了下这个已经没用过的HTML标签,发现还是一个系列,可以用来帮助代码文本的语义化呈现,具体如下:

  • kbd: 键盘输入的文字内容

  • samp: 范例输出

  • code: 计算机代码输出

  • var: 变量与自变量实例

平时只用过 code 标签 ,结果没想到还有其他类似HTML属性,现代浏览器全部都支持。

更详细的内容我已经这里成文章了,有兴趣的可以访问这里了解。

第32周 8.7-8.13

本周学习了两个HTML全局属性,nonce和popover属性。

nonce与安全相关 ,配合meta元素的CSP设置,可以决定哪个内联JS执行,哪个内联<script›元素不执行。

假设页面有如下所示的代码:

xml 复制代码
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-NDhkODkxMzYtNGUxZS00N2NjLTk1YTItNWMyOTM4YzdhZGJj'">
<script nonce="NDhkODkxMzYtNGUxZS00N2NjLTk1YTItNWMyOTM4YzdhZGJj">// ...</script>

则此时,只有nonce值有设置,且值匹配的

popover属性是个比较新的属性。

可以让任意的元素点击后直接出现浏览器层面的popover弹出层效果。

例如下面的代码:

xml 复制代码
<button popovertarget="imgPopover">点击我</button>
<div popover id="imgPopover"><img src="1.jpg" /></div>

此时,点击按钮,就会出现图片显示浮层。

点击空白自动隐藏。

关于这两个HTML属性更多的内容,可以参见我撰写的这篇文章:"我仍未知道的HTML nonce和popover属性"。

第33周 8.14-8.20

本周学习了非常多的东西,因为要专业分享,要讲HTML部分,所以梳理了下HTML相关的内容,发现了很多之前遗漏的知识。

包括:

1. 浏览器的referrerpolicy策略

document.referrer可以返回当前页面的来源页面,而究竟显示哪些信息,是完整地址,还是空,亦或是只有域名,都是可以设置的。

例如:

  • no-referrer不发送任何Referer信息

  • no-referrer-when-downgrade表示协议安全级别下降的时候不发送Referer信息

  • origin是只显示域信息

  • origin-when-cross-origin表示跨域的时候只显示域信息

  • same-origin表示域名相同,否则Referer信息是空

  • strict-origin表示仅当协议安全级别保持不变时发送Referer信息

  • strict-origin-when-cross-origin是默认值(之前默认值不是这个),如果域名和安全协议相同或更高的时候,Referer信息是完整地址,如果跨域,则Referer信息是原始的域信息,如果安全协议降低,Referer信息为空

  • unsafe-url表示就算URL地址不安全,也发送完整的Referer信息

2. 返回顶部

原来<a href="#top">返回顶部</a>也可以返回顶部,以前只知道<a href="#">返回顶部</a>

3. li元素的父元素

<li>元素的父元素除了<ul>``<ol>,还可以是<menu>,这个之前也没注意到。

4. Open Graph协议

也就是开放内容协议,有利于社交分享,以微软官网源码示意:

5. <caption>元素

<caption>元素只能用在<table>表单中,此限制也是最近知道。

6. autocapitalize属性

autocapitalize属性可以控制手机软键盘呼起时候,字母的大小写设置。

7. 其他...

还有很多其他内容,例如exportparts属性,<dfn><abbr>的使用场景,以及上周介绍的几个属性等,篇幅原因,不一一展示了。

第34周 8.21-8.27

这周好好研究了下User Timing API,相比于Date.now()或者performance.now()方法,此API可以在自己希望记录的位置打下标记,然后和浏览器的性能工具配合,可以看到整个的渲染时长、时机等过程,更加方便我们定位调试,以及理解Web渲染的过程。

以及还可以和其他时间线API一起使用,例如PerformanceObserver。

PerformanceObserver可以对各项性能指标进行观察,而浏览器支持的性能指标非常多,尤其是Chrome浏览器。

我们可以使用PerformanceObserver.supportedEntryTypes这个语句获取,例如在Mac OS X系统的Chrome浏览器下。

通过设置需要指定观察的类型,我们就可以看到对应的性能指标了,例如'paint'类型,我们可以看到页面内容初次渲染的时间。代码示意:

ini 复制代码
const observer = new PerformanceObserver(entryList => {
    for (const entry of entryList.getEntries()) {
        console.dir(entry);
    }
});
observer.observe({
  entryTypes: ['paint']
});

浏览器返回:

startTime就可以示意首次渲染时间。

PerformanceObserver的相关知识非常多,这里就不具体展开,有兴趣的可以参考我撰写的"狠狠地研究了下 PerformanceObserver API"一文。

额外的思考

User Timing API非常庞杂,想要全部通透,需要非常多的时间精力,而相关知识的应用价值其实有限,如今的Web页面的性能都非常强悍了,很少遇到需要打开控制台排查性能的机会。

所以,对于大部分而言,花非常多的时间学习相关的内容是不换算的,我觉得了解个大概就足够了,至少那些基本的概念需要知道。

例如时间线是什么,时间线中的mark和measure是什么意思,first-input和largest-contentful-paint的含义是什么等?

对于这类非热门的前端知识,通常业内深入介绍的文章较少,文档呢,也通常会省略很多细节,此时,要想有个全面且大概的了解,一定要亲自实践,而不是自己脑补。

largest-contentful-paint渲染的元素究竟是哪个?如果不是自己预期的元素,会是什么原因造成的呢?

通透了这些原因,你对这些API的理解自然就比别人深刻一些,专业技术也就比别人更加扎实了。

第35周 8.28-9.3

这周研究了下registerProtocolHandler()方法。

第一眼看到registerProtocolHandler()方法的时候,说实话,我还是挺兴奋的。

这可是个有趣的东西啊,居然可以自定义协议地址,并且可以像正常链接一样访问。

然而,亲自体验了之后,发现没有想象的那么美好,限制较多,最大的问题,在Web端并不能简化URL,还需要对协议内容进行分析处理。

通常的自定义协议都是,桌面软件注册,浏览器URL呼起。

而registerProtocolHandler()方法是浏览器注册,浏览器呼起......总之比较鸡肋。

有兴趣可以访问这篇文章"一言难尽的registerProtocolHandler()方法"。

其他学习

之前对外分享的时候,多次提到,要节约时间,要学会坚持,重复做一件事情,后来发现效果一般,听众没什么感触。

这周看到了路长全的分享,讲得比我好------什么是吃苦?吃苦的本质是自律,心不苦,则智不开(有兴趣的可以搜相关视频)。

和日常的辛苦相对比,更有说服力些,可以借鉴下。

第36周 9.4-9.10

  1. reset与chang事件

<form>元素在执行reset()方法的时候,虽然里面的输入框元素的值变了,但是并不会触发change事件,这个现象有时候会对我们的开发带来麻烦。

那有没有什么办法打个补丁呢?

有,正好reset事件执行时机是在输入框value值变化之前触发的,因此,我们可以检测此value前后有没有变化,以此来决定是否触发change事件。

具体代码如下,在页面任意位置引入即可:

在线演示页面戳这里

2. 本地环境跨域

本地开发域名经常是localhost,而请求地址往往是域名,此时会有跨域的问题。

之前的做法都是让运维配置运行跨域的请求头,但这个比较麻烦,后来我发现了一个更简单的解决方法。

那就是安装个Chrome插件Access Control Allow Origin,安装后,只要开启就没有跨域的烦恼了。

第37周 9.11-9.17

本周学习了这些。

1. HTML elementtiming属性

抽空研究了下elementtiming属性,在性能监控的需求中,这个属性很实用。

给任意的有图文内容的DOM元素添加此属性,并自定义标志量作为属性值,则使用PerformanceObserver API进行观察的时候,就可以知道此元素的渲染起始时间,如果是图片等元素,还可以知道图片的加载时间。

这对于排查页面中哪个元素的渲染最耗时非常有用。

详见我整理的这篇文章:"HTML elementtiming属性初体验记录"。

2. 复制图片到剪切板

上周做了个在线PNG/JPG优化的小工具,但是有个问题,如果我想直接粘贴到编辑器中,或者在其他地方进行上传,就必须先将优化的图片下载到本地,然后再进行处理。

但这样的操作显然有些啰嗦,最好可以直接复制优化的图片进入剪切板。

浏览器提供了原生的API可以满足此需求,代码示意:

ini 复制代码
// blob是图片二进制数据 
const data = [newClipboardItem({ ['image/png']: blob })]; 
navigator.clipboard.write(data);

然而,此API只能复制PNG图片,复制其他格式的图片数据会报错。

虽然可以通过canvas将JPG图片转为PNG,但那就是无损图了,而不是压缩图。

后来,曲线救国,直接复制图片的base64信息,然后再在上传页面,或者预览页面进行二次处理。

具体可以参见我整理的文章:"又get到了,JS复制图片到剪切板"。

第38周 9.18-9.24

本周比较忙碌,没有学习,只有思考。

基于JSON数据和JS在Web端模拟视频播放功能上周已经弄好了。

不过周末想了下,需要重新改变下算法实现。

原因:

之前算法是,先提前对每个tts音频和背景音乐进行合并,然后再控制播放,这样实现的好处是解析器编写简单。

但是有一个问题,由于浏览器的限制,这种合成需要用户至少点击一次页面,无法默默地完成。

而根据实际运行的结果,此合成会造成几百毫秒的卡顿,如果在用户点击后执行,会有体验问题。

所以,需要换一种实现,就是时间轴运行到哪个tts,就播放哪个tts音频,之前的xx工具就是这么处理的,虽然麻烦了点,不过因为即点即播,用户体验不受影响。

另外还有个好处,tts和背景音乐分离后,背景音乐的音量设置也可以比较容易地反馈出来。

至于音频的合成,就留在视频导出的时候完成,因为此时会专门做一个loading效果,即使有延时和卡顿,用户也不会觉得有什么问题。

不过,这里还有个技术小缺失,基于canvas图片序列+音频=>MP4视频的技术我这边是没问题的,demo已经跑通,但是合并的时候,需要控制某一个音频的音量我还不知道具体的细节,这个需要花时间研究下,可能需要额外的半天时间。

第39周 9.25-10.1

因为某某工作的原因,重新拾起了对<html><body>元素的关注,然后以前一些模模糊糊的理解现在终于理清楚了。

默认情况下,body元素的高度是0,但是此时设置background背景,会发现满屏显示。

例如:

body { background-color: black; }

但,如果此时html元素也设置个背景色,例如:

html { background-color: skyblue; }

此时,body设置的背景色消失了,明明 body 是子元素。

还有奇怪的,如果body设置的是线性渐变,例如:

body { background: linear-gradient(black, white); }

发现背景是个8px像素平铺的水平条纹。

8px哪里来的,为何是水平条纹?

很多人并不理解这种现象。

这其实是body、html元素的某种特异性。

即:

  1. 如果body设置了背景,但html没设置,则body的背景等同于设置在 html 元素上,否则,body按照普通的标签元素渲染。

  2. html背景的渲染高度至少一屏。

这就可以理解上述所有的现象了。

尤其是最后的水平条纹。

由于body元素默认有8px的margin大小,考虑到margin合并,因此,html元素的默认高度是8px,于是渐变背景高度也是8px。

但是html元素的背景至少要一屏高,于是8px水平平铺了起来。

overflow属性也有类似的现象。

单纯如下body overflow是无法隐藏div元素的,哪怕div元素的高度比body明显高,例如:

css 复制代码
body { height: 30px; overflow: hidden; } 
body > div { height: 300px; background-color: #cd0000; }

此现象出现原因和背景色类似。

  1. 如果html元素没有设置overflow属性,那么body元素的设置等同于设置在html元素上,否则,body元素的overflow属性按照普通元素渲染。

  2. html元素的overflow剪裁高度至少一个屏幕高度。

所以,上面CSS代码,只需要html元素设置任意不是 visible 值的overflow属性,都能触发body元素剪裁div,哪怕html元素的高度很高。

例如:

css 复制代码
html { height: 400px; overflow: scroll; }

此时body overflow生效。

于是,下面的现象也就理解了,即如果div高度很高,例如3000px,可以看到div元素在一屏高度的地方隐藏了:

css 复制代码
body > div { height: 3000px; background-color: #cd0000; }

这是因为html元素的overflow生效高度至少1屏。

第40周 10.2-10.9

学什么学,国庆假期,浪起来!

钓鱼钓了个昏天暗地......

第41周 10.9-10.15

本周学习围绕音频处理展开,两个需求点。

1. 改变原始音频的音量

如果仅仅是调整播放的音量,那很简单。

如果你使用的是<audio>元素,直接改变volume属性就好了。

ini 复制代码
audio.volume = 0.5;

如果没有audio元素,而是使用的Web Audio API,希望在 AudioBuffer 层面设置播放的音量,则可以使用GainNodes实现。

您可以狠狠地点击这里体验效果:使用gainNode改变音频播放音量demo

如果希望从原始文件层面改变音频的音量大小,怎么办呢?

可以解析音频文件,然后遍历采样点数据,然后根据音量设置进行调整。

由于代码较长,这里就不放出来了,有兴趣可以访问这篇文章:"JS改变AudioBuffer音量并下载为新audio音频"。

2. 音频的拼接与合并

拼接:

合并:

操作过程和改变音量大小的实现大同小异。ArrayBuffer转AudioBuffer,然后读取音频信息,对采样信息进行处理。

同样,篇幅原因,这里不展示源码,有兴趣的可以访问:"纯JS实现多个音频的拼接或者合并"

如果你对原生实现不怎么感兴趣,也可以使用开源项目。

比方说这个叫做crunker的项目:github.com/jaggad/crun...

如果你已经有了 AudioBuffer 资源,上面的 fetchAudio() 方法也是可以省略的。

另外,此JS还支持使用静音填充视频。


OK,以上就是最近三个月的学习记录。

然后我专门建了个学习记录的专栏,每个季度更新一下。

欢迎关注哈。

相关推荐
多多*22 分钟前
Spring之Bean的初始化 Bean的生命周期 全站式解析
java·开发语言·前端·数据库·后端·spring·servlet
linweidong26 分钟前
在企业级应用中,你如何构建一个全面的前端测试策略,包括单元测试、集成测试、端到端测试
前端·selenium·单元测试·集成测试·前端面试·mocha·前端面经
满怀10151 小时前
【HTML 全栈进阶】从语义化到现代 Web 开发实战
前端·html
东锋1.31 小时前
前端动画库 Anime.js 的V4 版本,兼容 Vue、React
前端·javascript·vue.js
满怀10151 小时前
【Flask全栈开发指南】从零构建企业级Web应用
前端·python·flask·后端开发·全栈开发
小杨升级打怪中2 小时前
前端面经-webpack篇--定义、配置、构建流程、 Loader、Tree Shaking、懒加载与预加载、代码分割、 Plugin 机制
前端·webpack·node.js
Yvonne爱编码2 小时前
CSS- 4.4 固定定位(fixed)& 咖啡售卖官网实例
前端·css·html·状态模式·hbuilder
SuperherRo2 小时前
Web开发-JavaEE应用&SpringBoot栈&SnakeYaml反序列化链&JAR&WAR&构建打包
前端·java-ee·jar·反序列化·war·snakeyaml
大帅不是我2 小时前
Python多进程编程执行任务
java·前端·python
前端怎么个事2 小时前
框架的源码理解——V3中的ref和reactive
前端·javascript·vue.js