前端语言串讲
- HTML(Hyper Text Markup Lanuage) 是一种标记语言,非图灵完备,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。
- 包括head、功能性标签、aria无障碍阅读、H5规范标签及特性、文档布局语义化标签(用总比不用强/不用总比用错好)、H5表单、H5存储(cookies(可用于服务端)/Local Storage/Session Storage/IndexDB)
- 包括head、功能性标签、aria无障碍阅读、H5规范标签及特性、文档布局语义化标签(用总比不用强/不用总比用错好)、H5表单、H5存储(cookies(可用于服务端)/Local Storage/Session Storage/IndexDB)
- CSS(Cascading Style Sheets) 是一种样式规则语言,可将样式应用于 HTML 内容,例如设置背景颜色和字体,在多个列中布局内容。
- JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。(JavaScript是由Web发展初期的网景(Netscape)公司创建,“JavaScript”是Sun Microsystem公司(现在的Oracle)的注册商标,用来特指网景(现在的Mozilla)对这门语言的实现。网景将这门语言作为标准提交给了ECMA——欧洲计算机制造协会—由于商标上的冲突,这门语言的标准版本改了一个丑陋的名字“ECMAScript”。同样由于商标的冲突,微软对这门语言的实现版本取了一个广为人知的名字“Jscript”。实际上,几乎所有人都将这门语言叫做“JavaScript”.本书也仅仅使用“ECMAScript”来指代语言标准。)
- 1995,JavaScript is born as LiveScript(简述JavaScript 的起源与发展 - 知乎 (zhihu.com))
- 1997,ECMAScript standard is established
- 1999,ES3 comes out and IE5 is all the rage
- 2000,XMLHttpRequest a.k.a.AJAX, gains popularity
- 2009,ES5 comes out and standard ]soN
- 2015,ES6/ECMAScript2015 comes out
- 2016,ES7/ECMAScript2016 comes out
- 2017,ES.Next
- Browser:浏览器通过HTTP协议拿到HTML文档后,解析文件构建dom树,继而计算CSS树,生成排版,渲染合成,绘制界面。
- 重绘(重排)与回流:重绘(repaint)和回流(reflow) 详解_wcy4001的博客-CSDN博客
- V8引擎(JS解释器)工作流程:将JS源码通过词法、语法转化为AST树,接下来将Ignition转化为字节码(Turbofan会发现字节码的漏洞从而进行优化,返回优化后的代码给Ignition)。注意:尽量不要改变JS变量类型的原因是,turbofan发现数据类型不对,就会通过Deoptimize流程告诉Ignition重新优化代码。
- 前端语言发展历程:
- JS in HTML:事件捕捉(由外向内监听,对计算机来说找到精准的触发元素)事件冒泡(由内向外监听,对开发者来说实现一些代理机制)。JS单线程,microTask Queue(eg,promise、async、await)先进入event loop执行,然后macroTask Queue(浏览器内置API)进入event loop执行。
- 浏览器存储信息:worker(进程间传输信息的推送,常在JS程序中进行控制)
- 浏览器存储信息:AMP
- H5 audio&video:音视频是有编解码器的。MP3、MP4、WebM 这些术语叫做容器格式。他们定义了构成媒体文件的音频轨道和视频轨道的储存结构,其中还包含描述这个媒体文件的元数据,以及用于编码的编码译码器等等。编解码器(codec)编码媒体,容器中的音频和视频轨道以适合的格式保存。音频轨道和视频轨道使用不同的格式。每个音频轨道都使用音频编解码器 (en-US)进行编码,而视频轨道则使用视频编解码器进行编码。浏览器并不全支持相同的 codecs(Codecs,如 Vorbis 和 H.264,它们用来将已压缩的音频和视频转化成二进制数字),所以得使用几个不同格式的文件来兼容不同的浏览器。(Mp3专利持续到2017年,mp4专利到2027年,所以浏览器无法以高额的费用使用编解码器codecs里来支持不同格式)
- 获得音量处理节点再到主处理节点上,再输出到设备终端上。
- 视频组合:
- 浏览器存储信息:worker(进程间传输信息的推送,常在JS程序中进行控制)
- H5支持二进制:
- H5 API: 地图(第三方)、canvas、拖拽的API(drop)
- 浏览器 API :内建于 web 浏览器中,它们可以将数据从周边计算机环境中筛选出来,还可以做实用的复杂工作。例如:
- 文档对象模型 API 能通过创建、移除和修改 HTML,为页面动态应用新样式等手段来操作 HTML 和 CSS。比如当某个页面出现了一个弹窗,或者显示了一些新内容(像上文小演示中看到那样),这就是 DOM 在运行。
- 地理位置 API 获取地理信息。这就是为什么谷歌地图可以找到你的位置,而且标示在地图上。
- 画布(Canvas) 和 WebGL API 可以创建生动的 2D 和 3D 图像。人们正运用这些 web 技术制作令人惊叹的作品。参见 Chrome Experiments 以及 webglsamples。
- 诸如
HTMLMediaElement和 WebRTC 等影音类 API 让你可以利用多媒体做一些非常有趣的事,比如在网页中直接播放音乐和影片,或用自己的网络摄像头获取录像,然后在其他人的电脑上展示(试用简易版截图演示以理解这个概念)。
- H5 web worker:
对于多线程代码,你永远不知道你的线程什么时候将会被挂起,其他线程将会得到运行的机会。因此,如果两个线程都可以访问相同的变量,那么变量就有可能在任何时候发生意外的变化,这将导致很难发现的 Bug。这种情况,worker的作用就出现了,主线程中操作文档,worker线程中进行具体的耗时工作,从而实现异步工作,使得网站保持响应,不会卡死。worker有三种类型dedicated workers、shared workers、service workers🌏其第一个常用处就是实现线程间的消息通讯,第二个用处,eg,service worker实现本地存储,通过cache返回缓存好的文件。 - H5 web socket:支持全双工通信。
- H5 shadow dom:特殊节点,shadow host里面构建一个更复杂的shadow tree(在这里面可以构建无限延伸的shadow tree,可以保证shadow内部节点不被外部节点访问到,从而实现其作为拥有内聚功能的HTML元素)。
- H5 web component(此处比较陌生,需参考官方文档):自定义标签(js中自定义dom,通过为其设置属性,将其挂到shadow上)。
- H5 svg and canvas:区别如下图。
- openGL(1990s)_openGL ES(2000s)_openCL(2008s)_webGL(2011)_VulKan(2015)_2022(webGPU直接通过gpu性能绘制前端三维立体动画):网格对象有许多顶点组成,通过顶点注册器Vertex shader对应到屏幕的位置(gl_position),通过fragment shader绘制物体的外观(gl_fragcolor,着色器语言:
GLSLWGSL) - H5 webAssembly:
- 前端的风靡(PPT格式可以用来思考为前端布局排版,挺好看的):
- 大前端:安卓按照通过XML方式定义view(毕设,已准备一部分),微信小程序自己实现了一套wxml、wxss、js构建应用
- 交互范式:MVC、MVP、MVVM
前端与HTML
- 前端:解决GUI人机交互问题、跨终端(PC/移动浏览器、客户端/小程序、VR/AR技术、Web技术栈)
- 前端关注点:
功能(basic on JS)、美观(CSS,etc)、无障碍(HTML标签应用需注意及设备适配)、安全(HTTP)、性能(V8引擎或node环境的底层逻辑/重绘回流/js程序原型机制、同步异步机制、worker机制、上下文机制,etc)、兼容(eg,媒体元素,响应式布局)、体验(功能完备、界面好看、不出bug) - 开发环境:(IE/edge、Chrome、Firefox、Safari)(vscode、vim、webstorm、HB)
- 前端边界:node服务端、electron/react Native客户端应用、web RTC实现P2P在线传输/多人会议、webGL/webGPU开发流畅的3D游戏、webAssembly将C++等其他代码编写为可以在浏览器里面直接运行的代码。
- HTML(开发者、浏览器、搜索引擎提取meta及文档内容、屏幕阅读器)要点:元素结构、dom树、语法、标题、链接、输入、内容划分(块级行级)、语义化(文档布局、有序无序列表)等等。(具体参见
mdn文档) - 语义化的好处:代码可读性、可维护性、搜索引擎优化、提升无障碍性。
前端与CSS
- 选择器特异度(优先级、权重值):
行内样式 > ID选择器 > 类、属性、伪类 > 元素、伪元素选择器 - 选择器类型:通用选择器、元素选择器、类、属性、伪类选择器、兄弟选择器、后代选择器、并列选择器
- 继承(显示继承,eg:em/rem;)
- 字体属性值单位pixel、em、rem: (58条消息) CSS单位px、em、rem及它们之间的换算关系_em和px的换算_汪末末的博客-CSDN博客
- 浏览器中CSS求值过程(可用于继承的分析:父级em,子级继承的是计算值):HTML解析为DOM树——依据
选择器有效、属性有效、符合当前媒体原则进行筛选fliter,从而得到一组CSS规则(声明值)——根据cascading机制选择优先级最高的属性值(层叠值)——经defaulting确定属性值过程后得到唯一的指定值——经resolving将em、相对路径等具体转换转换为计算值——经formatting将计算值关键字auto等、百分比转换为具体的绝对值得到使用值——经constraining将小数转换为整数或者(给一个元素设置了宽度100%,max-width:400px;当viewport宽度<400px,仍然是400px,当视口宽度大于400px,计算值可能为大于400的500px,但constraining依然会将其使用值转换为400px),得到使用值——继而得到浏览器中的实际值。- 特殊地,计算值(eg,em:根据父级元素继承字体大小,从而通过resolving过程计算出css属性值),而一些需要通过实际布局的环境计算的值,需通过formatting过程转换。
- 盒子模型:content-box(CSS标准盒子)、border-box(原理同content-box,实际项目中多用此盒子,也称IE替代盒子)
- 宽高取值为长度、百分数(相对于所在的容器的content-box指定的宽高度)、auto(高度由内容计算出来)
- 边框:若将宽高设置为0,得到4对三角形(实际上是边框的交界处),三部分设计为透明,得到三角形
- auto原理(所在容器的content-width减去当前盒子宽得到剩余空间大小平均分配给两端从而实现水平居中,上下不居中的原因是该盒子为块级元素,占据一行,其所在容器的上下没有剩余空间)(59条消息) margin 实现水平居中,垂直居中原理_margin 居中_chelen_jak的博客-CSDN博客
- margin collapse(倒塌、折叠):浏览器默认,
- overflow控制溢出(auto、hidden、visiual)
- 几种布局——综合使用(特殊地,bootstrap框架)
- 常规流布局(in-flow)
- 行级元素:并列、无宽高
- 块级块级元素:不并列、适用盒模型(body、article、div、main、section、h~、p、ul、li,etc)
- display(block、inline、inline-block(eg,image:
本身是行级,可以放在行盒中;可以设置宽高;作为一个整体不会被拆散成多行)、none)
- display(block、inline、inline-block(eg,image:
- 行级排版上下文IFC(inline formatting context):
- 只包含行级盒子的容器会创建一个IFC;盒子在一行内水平摆放,超过换行(overflow-warp:break-word;),text-align,vertical-align,避开float元素
- 块级排版上下文BFC(Block forvmatting context):某些容器会自动创建BFC
- 根元素html
- 浮动、绝对定位、inline-block
- flex子项与grid布局
- overflow值不是visible的块盒
- display:flow-root
- 排版规则: 盒子从上到下摆放,垂直margin合并,BFC内盒子的margin不会与外面的合并(可设置
display:flow-root;避免margin collapse),BFC不会和浮动元素重叠。
- FlexBox布局(一维布局):flex-direction;justify-content;align-items;align-self;order;flexibility;flex-grow;flex-shrink;(主要是用得熟练,具体属性参见w3c school或mdn)
- Grid网格布局(二维布局,似乎bootstrap的栅格系统用的就是该原理):grid-template;grid line;(浏览器开发者工具)grid-template-columns;参见:网格 - 学习 Web 开发 | MDN (mozilla.org)
- 浮动float:图片环绕
float:left; - 定位position(子绝父相):默认值static,relative不脱离文档流,absolute脱离常规流(楼层)——相对非static祖先元素定位,fixed相对于视口定位(bootstrap导航条固定,同时选择性地对body设置padding内补)
- 常规流布局(in-flow)
- 布局总结:本质上嵌套:positon设absolute,实际上是设置了一个新的常规流;flex子项里面的内容相对于flex子项创建了一个新的常规流。
跟着月影学JS
- 写js原则
- 各司其责(深色与浅色背景切换:js操作样式——js操作类——纯css(lable属性for到checkbox元素,该元素隐藏,通过伪类选择器实现浅深色背景切换):HTML/CSS/JS各司其责;应当避免不必要的由JS直接操作样式;可以用class来表示状态;纯展示类交互寻求零JS方案
- 组件封装(组件是指Web页面上抽出来一个个包含模版(HTML)、功能(JS)和样式(CSS)的单元。好的组件具备封装性、正确性、扩展性、复用性)
- 轮播图html结构;
- 使用CSS绝对定位将图片重叠在同一个位置;轮播图切换的状态使用修饰符(modifier);轮播图的切换动画使用CSS transition。
- 开发轮播图API: +getSelectedltem()、+getSelectedltemIndex()、+slide To()、+slideNext()、+slidePrevious()
- 控制流:JS Bin - Collaborative JavaScript Debugging (h5jun.com)图片与状态组件相联系(但不能让组件的状态与图片的状态相耦合在一起),需实现解耦,类构造函数中使用自定义事件(
控制流)进行解耦。 - 插件化:JS Bin - Collaborative JavaScript Debugging (h5jun.com)将控制元素抽取成插件;插件与组件之间通过依赖注入方式建立联系;
- 模板化:
图片列表模板化,插件中模板化控制组件并通过action实现初始化。
- 组件框架:JS Bin - Collaborative JavaScript Debugging (h5jun.com)component的子类:slider、sliderPlugin,组件是由组件及其控制插件组成的,
缺点是没考虑嵌套,子组件可以作为父组件的插件来使用,可以将子组件和父组件绑定到一起,这样的话,就能将子组件当作父级插件进行使用。另外一个缺点是,没有将CSS文件进行模板化。
- 组件设计总结
- 组件设计的原则:封装性、正确性、扩展性、复用性
- 实现组件的步骤:结构设计、展现效果、行为设计
- 三次重构:插件化、模板化、抽象化(组件框架)
- 并不影响HTML、CSS、JS各司其责的原则,各自做自己
应当做的事情。
- 并不影响HTML、CSS、JS各司其责的原则,各自做自己
- 基于原型和头等函数的多范式语言:过程式(C函数)、面向对象(C++)、函数式(Lisp/JS)、响应式,其中多范式(JS)
- 面向过程抽象:dom事件中的功能:
once:true——该功能可用过程抽象高阶函数once()代替;
//只执行一次
function once(fn){
//外部作用域
return function(...args){
//内部作用域
if(fn){
constret=fn.apply(this,args);
//保证事件只执行一次
fn=null;
return ret;
}
}
//节流函数:滑动、点击等操作会带来浏览器性能上的开销,因此可以使用高阶函数实现节流()
function throttle(fn, time = 500){
let timer;
return function(...args){
//点击时,时间未超过500ms,则timer值为空
if(timer == null){
fn.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, time)
}
}
}
//防抖函数:eg,在线编程的保存功能,每次点击键盘就要不断实现保存功能,这样就会使浏览器功能方面抖动,因此得在敲键盘停下来的时候触发保存功能;
//又eg,css动画小鸟移动,当鼠标移动时不能让小鸟动画一直跟着走,得让鼠标停下来的时候,触发动画。
function debounce(fn, dur){
dur = dur || 100;
var timer;
return function(){
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, dur);
}
}
//延时调用
function consumer(fn, time){
let tasks = [],
timer;
return function(...args){
tasks.push(fn.bind(this, ...args));
if(timer == null){
timer = setInterval(() => {
tasks.shift().call(this)
if(tasks.length <= 0){
clearInterval(timer);
timer = null;
}
}, time)
}
}
}
//迭代调用(早期使用jquery实现批量操作,现多用此方式)
const isIterable = obj => obj != null
&& typeof obj[Symbol.iterator] === 'function';
function iterative(fn) {
return function(subject, ...rest) {
if(isIterable(subject)) {
const ret = [];
for(let obj of subject) {
ret.push(fn.apply(this, [obj, ...rest]));
}
return ret;
}
return fn.apply(this, [subject, ...rest]);
}
}
- 面向过程抽象:为了能够让"只执行一次"的需求覆盖不同的事件处理(eg,点击&数据请求),我们可以将这个需求剥离出来。这个过程我们称为过程抽象。
- 高阶函数:以函数为参数、以函数为返回值、以函数作为函数装饰器(函数与参数函数等价,只是用来改变一些变量值)。
- 常用高阶函数:once、节流函数Throttle、防抖函数debounce、延时调用consumer、迭代批量操作iterative
- 纯函数:输入输出确定
- 命令式:强调具体做法
- 声明式:如下,强调可扩展性
//声明式
letlist=[1,2,3,4];
const double=x=x=> x * * 2
list.map(double);
- JS编程范式(编程范式是编程语言背后的思想,要通过编程语言来体现,eg,是否允许副作用;操作的执行顺序;代码组织;状态管理;语法和词法)总结:
过程抽象/HOF/装饰器、命令式/声明式
leftpad事件
- 2d矩阵:2*3(1/0/0 1/0/0 0/0/1),css中transform原理;
- 写代码的风格(循环/直接写)最重要的应根据使用场景来决定
- node包的leftpad事件:解决方式为,不断地转向性能更好的代码(普通循环——移位取余循环O(log(b))——确定循环次数后,再执行程序逻辑)
代码质量优化(对算法要求高,使用数学的思维实现功能)
- 交通灯切换:setTimeout()嵌套陷入回调地狱;优化:状态列表+递归/HOF——过程抽象
难点4的幂(a&(a-1)):循环——按位循环——转字符串正则匹配二进制- 洗牌:数学random库(算法sort换位不均匀导致洗牌分布不均匀)——
difficult数学归纳法验证洗牌的均匀——生成器保证性能 - 分红包(不能完全随机;相对均匀;有高有低有刺激):切西瓜法/与二分法相反(取较大的直拆分)——抽牌法(插值法)
Supplement: 该文章旨在知识总结记录、课程笔记、学习思考,其中有部分内容引用了课程PPT内容和mdn官网内容。