html5:
⾸先 html5 为了更好的实践 web 语义化,增加了 header,footer,
nav,aside,section 等语义 化标签,
在表单⽅⾯,为了增强表单,为 input 增加了 color,email,data ,range 等类型,还有一些属性,
在存储⽅⾯,提供了 sessionStorage,localStorage,和离线存储,通过这些存储⽅式
⽅便数 据在客户端的存储和获取,
在多媒体⽅⾯规定了⾳频和视频元素 audio 和 vedio,另外还 有地理定位,canvas 画
布,拖放,多线程编程的 web worker 和 websocket协议
css3新增特性:
HTML5是HTML的新标准,其主要目标是无需任何额外的插件如Flash、Silverlight等,就可以传输所有内容。它囊括了动画、视频、丰富的图形用户界面等。
HTML5是由万维网联盟(W3C)和 Web Hypertext Application Technology Working Group 合作创建的HTML新版本。
区别:
HTML是很长的一段代码,很难记住。如下代码:
HTML5却只有简简单单的声明,方便记忆。如下:
HTML4.0:没有体现结构语义化的标签,通常都是这样来命名的
,这样表示网站的头部。
HTML5:在语义上却有很大的优势。提供了一些新的标签,比如:
。
从网络传给渲染引擎的 HTML 文件字节流是无法直接被渲染引擎理解的,所以要将其转化为渲染引擎能够理解的内部结构,这个结构就是 DOM。DOM 提供了对 HTML 文档结构化的表述。
在渲染引擎中,DOM 有三个层面的作用:
简言之,DOM 是表述 HTML 的内部数据结构,它会将 Web 页面和 JavaScript 脚本连接起来,并过滤一些不安全的内容。
HTML 解析器(HTMLParser): 负责将 HTML 字节流转换为 DOM 结构。
那么网络进程是如何将数据传给HTML解析器的呢?
从图中我们可以知道,网络进程和渲染进程之间有一个共享数据通道,网络进程加载了多少数据, 就将数据传给HTML解析器进行解析。
HTML解析器接收到数据(字节流)之后,字节流将转化成DOM,过程如下:
有三个阶段:
通过分词器将字节流转化为Token。 分词器先将字节流转换为一个个 Token,分为 Tag Token 和文本 Token。
注意,这里的Token并不是我们之前理解的Token,这里就是一个片段。
Token解析为DOM节点。
将 DOM节点添加到DOM树中。
我们知道,JavaScript可以修改DOM,它也会影响DOM的生成。
内嵌 JavaScript 脚本 比如我们嵌入了一段标签的代码,之前的解析过程都一样,但是解析到script标签时, 渲染引擎判断这是一段脚本,此时 HTML 解析器就会暂停 DOM 的解析, 因为接下来的 JavaScript 可能要修改当前已经生成的 DOM 结构。
暂停解析之后,JavaScript 引擎介入,并执行标签中的这段脚本。 脚本执行完成之后,HTML 解析器恢复解析过程,继续解析后续的内容,直至生成最终的 DOM。
引入 JavaScript 文件 基本上跟之前是一致的,不同点在于,暂停解析之后执行JavaScript 代码,需要先下载这段 JavaScript 代码。
一个请求从发出到返回,需要浏览器和服务端的协调配合。浏览器要把自己的请求参数带给服务端,服务端校验参数之后,除了返回数据,也可能会顺便把请求是否缓存,cookie等信息告诉浏览器。当请求是跨域请求的时候,这个过程还要复杂一些。接下来咱们就看看跨域会有什么问题,又需要前后端进行怎样的配合。
我有一个朋友,叫小王。前端小王和后端同事小马准备联调一个登录的api。假设是/login
;小王在把登录账号和密码都准备好之后,愉快的发起了post提交。结果很意外,请求的响应被浏览器拦截了,浏览器还贴心的在console上抛出了一个错误。
小王翻译了一下,原来是被CORS策略拦截掉了。这个策略大概意思是说,服务端如果允许不同origin的请求,那就需要在返回的response header里面带上Access-Control-Allow-Origin
这个header。否则浏览器在拿到响应并发现响应头里没有这个header时,就会把响应给吞掉,而不会交给js进行下一步处理。
小王把这个事情告诉了小马,然后小马在返回的header中加上了
1Access-Control-Allow-Origin: *
现在小王终于可以拿到返回的结果了。
这里要注意,浏览器不是在请求阶段就对请求进行拦截,而是正常发出请求,拿到服务端的响应之后,开始查看响应header里面有没有
Access-Control-Allow-Origin
这个header,如果没有,响应的结果就不会到js那里去。
后来小王觉得在post中发送表单格式的body太麻烦,希望使用JSON格式的请求体提交。小马觉得就是几行代码的事,就同意了。但是小王改成JSON的消息体之后发现又被CORS拦截了,并抛出了下面的错误:
在上面的报错中,我们看到了 preflight 的单词。那这又是怎么回事呢?原来,修改请求体之后,这个跨域请求不再是简单请求了,需要在发起请求之前先进行 preflight 请求。那么什么是简单请求呢?
GET
, HEAD
, POST
text/plain
, multipart/form-data
, application/x-www-form-urlencoded
由于json数据的content-type导致这个post请求不再是简单请求,而对于非简单请求,之前允许所有域名跨域访问是被禁止的。所以还是要修改Access-Control-Allow-Origin
为特定的请求域名。在开发模式下,可能是http://localhost:3000
之类的。
小马在重新修改Access-Control-Allow-Origin
,小王又拿到了登录成功的结果。可以联调下一个api了。
登录是基于session的,也就是说,登录成功后,server会通过set-cookie
,将cookie设置到浏览器中,这样,下次访问同源下的api时,cookie就会被带上。
然而,奇怪的是,小王发现登录成功后,调用别的接口,cookie并没有被带上,导致server无法识别出用户信息,最终返回错误(状态码为401)。
原来,浏览器发起跨域请求的时候,是不会主动带上cookie的,如果一个请求需要cookie,需要开发者设置一个选项,以fetch api为例:
fetch('http://baidu.com:3000', {
// ...
credentials: 'include'
})
如果使用xhr api来请求,则需要这样写:
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true; // 带上cookie
invocation.onreadystatechange = handler;
invocation.send();
}
}
小王在设置请求之后又发起了一次请求。却发现cookie还是没有带上去。小王只好在MDN继续查看资料,发现在set-cookie时需要带一个sameSite的属性。
sameSite是为了防止csrf攻击而产生的属性,如果不知道啥是CSRF攻击,可以自己先去查一下。
由于我们需要在请求中带上cookie,所以需要在set-cookie时将cookie的sameSite设置为none;又由于将sameSite设置为none时,也需要将Secure设置上,所以请求需要基于https;
小王最后一次请求小马对api进行了上诉更改,服务器终于认出请求来自谁,并返回了正确的结果,跨域的踩坑之旅算是告一段落。
很多时候,我们可能只会关注请求体是什么,响应有没有正确返回,而忽略了header部分。殊不知,header在缓存,web安全,浏览器正确解析结果中发挥了重要的作用,比如本文中的一系列Access-Control-Allow-*
的header。
为了让web更安全,CORS还在不断地更新,比如这个提案,规定从公网到私网,或者从私网访问local network时,需要设置跨域头,Access-Control-Allow-Private-Network
。
SSG(Static Site Generation,静态网站生成)是指在构建时预先生成静态页面,并将这些页面部署到 CDN 或者其他存储服务中,以提升 Web 应用的性能和用户体验。
具体来说,SSG 的实现方式通常包括以下几个步骤:
相比于传统的动态网页,SSG 具有如下优势:
需要注意的是,SSG 不适用于频繁更新的内容和动态交互等场景,但对于内容较为稳定和更新较少的网站则是一个性能优化的好选择。
首先,在浏览器地址栏中输入url
浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。
浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。
握手成功后,浏览器向服务器发送http请求,请求数据包。
服务器处理收到的请求,将数据返回至浏览器
浏览器收到HTTP响应
读取页面内容,浏览器渲染,解析html源码
生成Dom树、解析css样式、js交互,渲染显示页面
浏览器下载HTML后,首先解析头部代码,进行样式表下载,然后继续向下解析HTML代码,构建DOM树,同时进行样式下载。当DOM树构建完成后,立即开始构造CSSOM树。理想情况下,样式表下载速度够快,DOM树和CSSOM树进入一个并行的过程,当两棵树构建完毕,构建渲染树,然后进行绘制。
浏览器安全解析策略对解析HTML造成的影响:
当解析HTML时遇到内联JS代码,会阻塞DOM树的构建,会先执行完JS代码;当CSS样式文件没有下载完成时,浏览器解析HTML遇到了内联JS代码,此时,浏览器暂停JS脚本执行,暂停HTML解析。直到CSS文件下载完成,完成CSSOM树构建,重新恢复原来的解析。
JavaScript 会阻塞 DOM 生成,而样式文件又会阻塞 JavaScript 的执行,所以在实际的工程中需要重点关注 JavaScript 文件和样式表文件,使用不当会影响到页面性能的。
白屏时间:即用户点击一个链接或打开浏览器输入URL地址后,从屏幕空白到显示第一个画面的时间。
当用户点开一个链接或者是直接在浏览器中输入URL开始进行访问时,就开始等待页面的展示。页面渲染的时间越短,用户等待的时间就越短,用户感知到页面的速度就越快。这样可以极大的提升用户的体验,减少用户的跳出,提升页面的留存率。
DNS解析优化: 针对DNS Lookup环节,我们可以针对性的进行DNS解析优化。
- DNS缓存优化
- DNS预加载策略
- 稳定可靠的DNS服务器
TCP网络链路优化: 多花点钱吧
服务端处理优化: 服务端的处理优化,是一个非常庞大的话题,会涉及到如Redis缓存、数据库存储优化或是系统内的各种中间件以及Gzip压缩等…
浏览器下载、解析、渲染页面优化: 根据浏览器对页面的下载、解析、渲染过程,可以考虑一下的优化处理
- 尽可能的精简HTML的代码和结构
- 尽可能的优化CSS文件和结构
- 一定要合理的放置JS代码,尽量不要使用内联的JS代码
- 将渲染首屏内容所需的关键CSS内联到HTML中,能使CSS更快速地下载。在HTML下载完成之后就能渲染了,页面渲染的时间提前,从而缩短首屏渲染时间;
- 延迟首屏不需要的图片加载,而优先加载首屏所需图片(offsetTop
document.documentElement.clientHeight//获取屏幕可视区域的高度
element.offsetTop//获取元素相对于文档顶部的高度
因为JavaScript 会阻塞 DOM 生成,而样式文件又会阻塞 JavaScript 的执行,所以在实际的工程中需要重点关注 JavaScript 文件和样式表文件,使用不当会影响到页面性能的。
渐进式 JPEG(Progressive JPEG),即PJPEG,是该标准的三种流行压缩模式之一。
渐进式 JPEG 以特定方式压缩照片和图形,与基线 JPEG 不同,PJPEG 在 Web 浏览器中呈现时,会首先给出模糊图像的外观。然后一点一点地开始图片渲染,直到它显示完全渲染的图像。浏览器实际上是逐行解释图像,但在占位符中提供了完整图像的模糊预览。随着 Web 浏览器的渲染引擎处理数据,图像的对比度开始变得更清晰、更详细。直到最后渲染完毕,用户将看到完整的清晰图像。
PJPEG 能够起到一种很有意义的心理效果,让用户有东西可看,而不必坐着干等大型图像慢慢显示在屏幕上。
PJPEG 适用于大部分常用的浏览器,包括 Chrome、Firefox 和 Internet Explorer 9 及更高版本。旧版本的 Internet Explorer 在显示渐进式 JPEG 时存在一些问题,不过这只是很小一部分用户。而不支持渐进式 JPEG 格式的浏览器会像普通 JPEG 一样加载照片。
常见的跨页面通信方法有以下几种:
Window.postMessage():
该方法允许在不同窗口间进行安全的跨域通信。该方法可以向指定的目标窗口发送消息,并在目标窗口的window
对象上触发一个message
事件。LocalStorage/SessionStorage:
这两个 web 存储 API 可以在当前浏览器窗口的所有页面之间共享数据。如果一个页面设置了一个存储项,其他同源页面可以通过读取该存储项来访问相同的数据。BroadcastChannel API:
该 API 允许在同一源下的多个浏览器标签页之间进行通信。该方法通过创建一个广播通道,将消息发送到该通道上,然后在其他页面上通过监听该通道上的onmessage
事件来接收消息。SharedWorker:
SharedWorker 是 HTML5 提供的一个跨页面共享数据的机制。它和普通的 Web Worker 相似,但与普通 Web Worker 不同的是,SharedWorker 不是为特定的页面或者文档服务的,而是为同一个源下的多个页面提供服务的。
除了上述方法外,还有一些第三方库和框架,如 EventEmitter、Socket.io 等,也可以用于实现跨页面通信,但这些方法可能需要更多的配置和使用成本。
对于同源页面,常见的方式包括:
而对于非同源页面:
src 用于替换当前元素,href 用于在当前文档和引用资源之间确立联系
src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置,在请求 src 资源时会将其指向的资源下载并应用到文档内,例如is 脚本,img 图片和 frame 等元素
当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将is 脚本放在底部而不是头部。
href是 Hypertext Reference 的缩写,指向网络资源所在位置,建立和当前元素(点)或当前文档(链接)之间的链接,如果在文档中添加
那么浏览器会识别该文档为 ss 文件,就会并行下载资源并且不会停止对当前文档的处理。 这也是为什么建议使2用 link 方式来加载 css,而不是使用@import 方式。
SEO(Search Engine Optimization),汉译为搜索引擎优化。
搜索引擎优化是一种利用搜索引擎的搜索规则来提高目前网站在有关搜索引擎内的自然排名的方式。
SEO是指为了从搜索引擎中获得更多的免费流量,从网站结构、内容建设方案、用户互动传播、页面等角度进行合理规划,使网站更适合搜索引擎的索引原则的行为。
响应式页面中经常用到根据屏幕密度设置不同的图片。这时就用到了 img 标签的srcset属性,srcset属性用于设置不同屏幕密度下,img 会动加不同的图片。用法如下:
使用上面的代码,就能实现在屏密度为1x的情况下加载image-128.png,屏幕密度为2x时加载image-256.pnq.
按照上面的实现,不同的屏幕密度都要设置图片地址,目前的屏幕密度有1x2x,3x4X四种,如果每一个图片都设置4张图片,加载就会很慢,所以就有了新的srcset标准。代码如下:
sizes就是指默认显示128px,如果视区宽度大于360px,则显示340px。
meta
标签由name
和content
属性定义,用来描述网页文档的属性,比网页的作者,网页达,关捷等,除了HTTP标准国定了 name 作为大家使用的共识,开发者还可以自定义name;
常用的meta标签:
charset,用来描述HTML文档的编码类型
viewport ,适配移动端,可以控制视口的大小和比例:
其中, content 参数有以下几种:
robots,搜索引擎索引方式:
其中,content 参数有以下几种:
- 行内元素有:
a
b
span
img
input
select
strong
;- 块级元素有:
div
ul
ol
li
dl
dt
dd
h1
h2
h3
h4
h5
h6
p
;- 空元素,即没有内容的HTML元素。空元素是在开始标签中关闭的,也就是空元素没有闭合标签:
常见的有:、
、
、
、
、
;
鲜见的有:、
、
、
、
、
、
、
、
、
、
。
- drastart:事件主体是被拖放元素,在开始拖放被拖放元素时触发。
- darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
- dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
- dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
- dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
- drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
- dragend:事件主体是被拖放元素,在整个拖放操作结束时触发
1.BFC(Block Formatting Context),即块级格式化上下⽂,它是⻚⾯中的⼀块渲染区
域,并且有⼀套属于⾃⼰的渲染规则:
2.触发BFC的条件包含不限于:
3.利⽤BFC的特性,我们将
BFC
应⽤在以下场景:
盒模型其实就是浏览器把⼀个个标签都看成⼀个矩形盒⼦,每个盒⼦都由:内容、内边距、边框、外边距四部分组成.
盒模型分为,标准盒模型和怪异盒模型
区别: 标准盒模型的宽高只包含内容,不包含其他部分 怪异盒模型的宽高包含了内容、内边距和边框部分
通过box-sizing属性设置盒模型
border-box //怪异盒模型content-box //标准盒模型
已知宽高:
1. 定位:
绝对定位 top:50%;left;50%;margin负的自身宽高的一半
2. 定位:
绝对定位 top:50%;left;50%;transform(-50%, -50%)负百分之五十
3. grid⽹格布局
设置父元素为display: grid;使用 grid-auto-columns 和 grid-auto-rows 属性将网格单元格大小设置为 auto ,然后使用 justify-content 和 align-content 属性将格子垂直和水平居中。
未知宽高:
2. 定位:
元素绝对定位 上下左右(0)margin:auto;
3. 弹性盒子:
父元素设置flex弹性盒,然后使用justify-content: center,align-items: center居中
4. table布局
设置⽗元素为 display:table-cell ,⼦元素设置 display: inline-block 。利⽤ vertical和 text-align 可以让所有的⾏内块级元素⽔平垂直居中
通常情况下我们会使⽤图⽚或者 svg 去完成三⻆形效果图,但如果单纯使⽤ css 如何完成⼀个三⻆
形呢?其实实现过程似乎也并不困难,通过边框就可完成
实现过程:
设置一个宽高为零的元素,然后设置它的border边框为50px或更大,最后给个颜色值,把另外三个边框的宽度改为零
em/px/rem/vh/vw区别如下:
px:绝对单位,⻚⾯按精确像素展示
em:相对单位,基准点为⽗节点字体的⼤⼩,如果⾃身定义了 font-size 按⾃身来计算,整个⻚⾯内1em 不是⼀个固定的值
rem:相对单位,可理解为 root em , 相对根节点 html 的字体⼤⼩来计算
vh、vw:主要⽤于⻚⾯视⼝⼤⼩布局,在⻚⾯布局上更加⽅便简单
脱离文档流指的是将元素从正常的 HTML 文档的布局流中取出,使其不占据文档流空间的一种技术。
下面列举了几种常见的脱离文档流的方法:
position 属性为 absolute 或 fixed:使用绝对定位或固定定位可以将元素从正常的文档流中取出,但是需要注意的是,这会导致元素与其他元素的重叠,因此需要使用 z-index 属性进行层级控制。
float 属性:使用浮动可以将元素从正常的文档流中取出,但是需要注意的是,浮动会影响元素后续元素的位置布局,需要通过清除浮动来避免对后续元素的影响。
transform 属性:使用 transform 属性对元素进行旋转、缩放等变换操作,可以将元素从正常的文档流中取出,但是需要注意的是,元素仍然会占据原来的空间位置,只是在视觉上进行了变换,如果需要完全从文档流中取出,还需要结合 absolute 或 fixed 定位。
display 属性为 inline-block 或 table-cell:使用 inline-block 或 table-cell 可以将元素从正常的文档流中取出,但是需要注意的是,这会将元素变成行内块状或表格单元格状,需要注意在布局时的样式调整。
**标签选择器:**通过 HTML 标签名选择元素,如 p、div、ul。
**类选择器:**通过类名选择元素,使用 .class,如 .container、.red-text。
**ID 选择器:**通过元素 ID 选择元素,使用 #id,如 #header、#main。
**后代选择器:**选择指定的后代元素,在两个选择器之间加上空格,如 ul li、.container p。
**子元素选择器:**选择指定的子元素,在父元素后加 >,如 .container > h1。
**相邻兄弟选择器:**选择紧接在另一元素后的元素,在选择器后加 +,如 h1 + p。
**通用选择器:**选择所有元素,使用 *,如 *。
**属性选择器:**通过元素属性选择元素,有以下三种方式:
[attribute]:选择具有指定属性的元素,如 [href]。
[attribute=value]:选择具有指定属性和值的元素,如 [class=container]。
[attribute*=value]:选择具有包含指定值的属性的元素,如 [class*=col]。
:hover:鼠标悬停在元素上时应用的样式。
:active:元素被激活时应用的样式。
:focus:元素在聚焦时应用的样式。
:nth-child(n):指定位置的子元素应用的样式,如 li:nth-child(2) 表示选择第二个 li 元素。
:first-child:选择父元素下的第一个子元素。
:last-child:选择父元素下的最后一个子元素。
这些是常用的 CSS 选择器,不同的选择器可以组合使用,实现更加精确的元素选择。
在使用 Flex 布局时,子元素如果设置了 position: absolute,会脱离 Flex 布局,并且不再占据父容器的空间。因此,Flex 容器会忽略该元素,而其他子元素会根据自身的尺寸和 Flex 属性进行排列。
具体来说,对于一个设置了 position: absolute 的子元素,它的位置和尺寸是相对于最近的非 static 定位的祖先元素(或者根元素)计算的。这意味着它不再受到 Flex 容器的对齐和排列控制,而是完全自由定位的。
下面是一个例子:
<div class="container">
<div class="box box-1">div>
<div class="box box-2">div>
<div class="box box-3">div>
div>
.container {
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 100px;
height: 100px;
}
.box-1 {
background-color: red;
}
.box-2 {
background-color: blue;
position: absolute;
right: 0;
top: 0;
}
.box-3 {
background-color: green;
}
如上所示,我们在 Flex 容器中的第二个子元素(box-2)上设置了 position: absolute,它将不再占据父容器的空间,并且不会被 Flex 容器控制。
因此,box-1 和 box-3 会按照 Flex 容器的对齐和排列方式进行排列,而 box-2 则会被放置在父容器的右上角,其位置和尺寸由 position 和 top、right 属性决定。
calc、support、media 是 CSS3 新增的三种常用语法和功能,分别用于计算样式属性值、检测浏览器对某一特性的支持及针对不同设备或方式媒体类型设置样式。
calc() 函数可以让我们在 CSS 中进行简单的数学计算,以得到更灵活的样式效果。它允许在 CSS 属性中使用数学表达式,以便轻松地进行计算,如下所示:
width: calc(100% - 20px);
height: calc(50vh - 10%);
其中 calc() 函数中可以包含 +、-、*、/ 和括号等运算符,用来完成基本的四则运算,以及百分比、长度、角度和时间等多个单位的计算。
支持检测是指检查浏览器是否支持某些 CSS 属性、函数或特性。@supports 规则可以用来测试浏览器是否支持某项 CSS 特性。示例如下:
@supports (display: grid) {
/* 支持 Grid 布局 */
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
这里,只有浏览器支持 Grid 布局时,@supports 规则中的 CSS 代码才会被应用。
@media 规则用于设置针对不同设备或方式、不同媒体类型的样式。它可以根据屏幕大小、分辨率、设备类型等条件来设置不同的样式,以便为不同的用户提供最佳的用户体验。示例如下:
@media (max-width: 768px) {
/* 当屏幕宽度小于等于 768px 时应用的样式 */
.container {
width: 100%;
margin-left: 0;
}
}
在 @media 规则中,我们可以使用多个 CSS 属性来设置针对特定条件的样式,如 max-width、min-width、orientation、resolution 等属性。
总的来说,calc、@support 和 @media 是 CSS3 中非常实用的新功能,可以让开发者更灵活地设置样式和布局,提高网站的响应性和用户体验。
弹性盒子(Flexbox)布局是 CSS3 中新增的一种布局方式,其可以方便地处理现代 Web 页面中常见的各种布局问题,如横向居中、垂直居中、等高布局、自适应布局等。关于弹性盒子的所有属性,下面逐一进行详解:
弹性盒子项目的属性
在 CSS 中,有些属性是可以继承的,子元素会从其父元素继承这些值,以避免反复书写相同的样式。以下是一些常见的可以被子元素继承的属性:
font-family
)设置在父元素上的字体系列会被子元素继承,除非子元素中有自己定义的字体系列。
font-size
)父元素上定义的字号也可以被子元素继承,但是在继承的同时子元素可能会基于自己的盒模型计算具体字号,从而得到不同的尺寸。
font-weight
)如同字体系列和字号一样,子元素也可以从父级继承 font-weight
的值。
line-height
)行高是文字行内高度的度量标准。因为在默认情况下,line-height
取值为 normal
(通常是当前字体大小的 1.2 到 1.5 倍),所以设置在父元素上的行高通常也会被子元素继承。
color
)父元素设置的文本颜色也可以被子元素继承,不过在许多情况下子元素会通过类名或 ID 选择器的方式来覆盖父级颜色。
list-style
)如果将 list-style
属性定义在某个 ul
或 ol
元素上,那么它的子元素也可以继承该属性值。
direction
)、文本对齐(text-align
)和文本缩进(text-indent
)文本方向、文本对齐和文本缩进这三个属性也可以被子元素继承。但是要注意,在设置对齐时,行内元素的实际位置可能要基于其自身的内部盒模型计算而非从父级继承。
并不是所有的 CSS 属性都可以被继承,有些属性设计为不能继承,例如
width
、height
、background
等。
闭包就是能够读取其他函数内部变量的函数,闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域
闭包的特性:
说说你对闭包的理解:
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念
闭包 的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中
闭包的另一个用处,是封装对象的私有属性和私有方法
好处:能够实现封装和缓存等;
坏处:就是消耗内存、不正当使用会造成内存溢出的问题
使用闭包的注意点:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露
解决方法是,在退出函数之前,将不使用的局部变量全部删除
比如常见的防抖节流
// 防抖
function debounce(fn, delay = 300) {
let timer; //闭包引用的外界变量
return function () {
const args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
使用闭包可以在 JavaScript 中模拟块级作用域
function outputNumbers(count) {
(function () {
for (var i = 0; i < count; i++) {
alert(i);
}
})();
alert(i); //导致一个错误!
}
闭包可以用于在对象中创建私有变量
var aaa = (function () {
var a = 1;
function bbb() {
a++;
console.log(a);
}
function ccc() {
a++;
console.log(a);
}
return {
b: bbb, //json结构
c: ccc,
};
})();
console.log(aaa.a); //undefined
aaa.b(); //2
aaa.c(); //3
- 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
- 简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期
<div onClick={this.handleClick.bind(this)}>点我div>
React并不是将dlick事件绑定到了div的真实DOM上,而是在document外监听了所有的事件,当事件发生并目冒泡到document外的时候,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅仅减少了内存的消耗,还能在组件挂在销毁时统一订阅和移除事件。
除此之外,冒泡到document上的事件也不是原生的浏览器事件,而是由react自己实现的合成事件(SyntheticEvent)。因此如果不想要是事件冒泡的话应该调用event,preventDefault0方法,而不是调用event.stopProppagation0方法
Webpack是一个流行的前端打包工具,用于将多个JavaScript文件和其他资源合并成一个或多个生产环境中使用的bundle.js文件。下面是Webpack的构建流程以及常见的属性:
Webpack主要分为以下几个步骤:
Webpack的一些常见属性如下:
相同点:
都是异步请求的方式来获取服务端的数据;
异同点:
请求方式不同: $ .get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的。
参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。
数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多
安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。
- window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。
- $(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。
微信小程序项目结构主要有四个文件类型,如下:
WXML可以构建出页面的结构
WXSS 是一套样式语言,用于描述 WXML 的组件样式
js逻辑处理,网络请求
json小程序配置文件
app.json作为配置文件入口,整个小程序的全局配置。
app.js必须要有这个文件,没有会报错
app.wxss全局页面样式设置,在app.wxss中设置的样式可以在小程序的所有页面生效
在⻚⾯标签上绑定
data-key
= value, 然后绑定事件通过e.Target.dataset.key
来获取标签上绑定的值(他盖特)
- wxss 背景图⽚只能引⼊外链,不能使⽤本地图⽚.
- ⼩程序可以使⽤ @import 引⼊ 外联样式⽂件,地址为相对路径.
- 尺⼨单位为 rpx , rpx 是响应式像素,可以根据屏幕宽度进⾏⾃适应
⼩程序直接使⽤this.data.key = value 是不能更新到视图当中的
必须使⽤this.setData({ key :value })
来更新值
- onLoad(昂搂德):页面加载时触发
- onShow():页面显示/切入前台时触发
- onHide():页面隐藏/切入后台时触发
- onReady(昂芮滴):页面初次渲染完成时触发
- onUnload(昂 昂楼的):页面卸载时触发
- onPullDownRefresh(昂谱当 芮 fi屎):下拉刷新的钩子函数
- onReachBottom(昂瑞驰波特闷):上翻到底的钩子函数
⽅案 ⼀ :
在 app.json 中 将
enablePullDownRefresh
【嗯a波 蒲当 芮 fi屎】设为true, 开启全局下拉刷新。
或者在 组件 json中 enablePullDownRefresh设为true, 开启单组件下拉刷新。
⽅案⼆:
scroll-view
:使⽤该滚动组件 ⾃定义刷新,通过bindscrolltoupper
(版的死课肉吐破) 属性, 当滚动到顶部左边,会触发scrolltoupper
【死课肉吐破】事件,利⽤这个属性来实现下拉刷新功能。
相同点:
都是小程序中的点击事件。
不同点:
bindtap
【办的泰普】不会阻⽌冒泡,catchtap
可以阻⽌冒泡。(开吃特泰普)。
方案一:使用全局变量
在 app.js 中的
this.globalData
(阁楼博 怼特)中放⼊要存储的数据。在组件.js 头部中引⼊ const app(康搜爱普) = getApp(); 获取全局变量,然后使⽤ app.globalData.key
来进⾏获取和赋值。
方案二:使用路由
wx.navigateTo 和 wx.redirectTo(瑞迪 芮可图) 时,可以通过在 url 后拼接参数变量, 然后在⽬标⻚⾯的onLoad生命周期中,通过参数来获取传递过来的值。
方案三:使用本地存储
wx.navigateTo(奶为 给特吐 ):保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面
wx.redirectTo( 蕊德 瑞可特 吐):关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
wx.switchTab(死维持 泰普):跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.navigateBack()关闭当前页面,返回上一级页面或多级页面。wx.reLaunch():关闭所有页面,打开应用内的某个页面 (芮老吃)
- wx:if 动态创建或销毁对应的UI结构
- wx:if 条件为 false,什么也不做;为true时,才开始局部渲染
- hidden 简单控制组件的显示与隐藏
- wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。频繁切换的情况下,用 hidden 更好,运行时条件不大可能改变则 wx:if较好
pages : ⽤于存放当前⼩程序的所有⻚⾯路径
window : ⼩程序所有⻚⾯的顶部背景颜⾊,⽂字颜⾊配置
tabBar : ⼩程序底部的 Tab ,最多5个,最少2个
封装 wx.request 请求传递需要的参数,封装常⽤⽅法 POST , GET , 最后导出这些⽅法然后新建⼀个 api.js ⽂件,导⼊封装好的⽅法,然后调取相应的⽅法,传递数据。
总结:
在src目录中新建一个utils (噢 套死)目录,在目录中新建一个request.js,在request.js中首先获取整个小程序的实例来保证能调用wx所有方法,定义get和post等请求的方法,然后在get或者post请求的方法中设置wx.showToast(头斯特),然后通过wx.request来实现get或者post请求,在success(森克 赛斯)中,关闭loading (楼顶),然后通过回调的形式来返回获取的数据
最后调用的时候使用require来引入
热启动 :
假如⽤户已经打开了某个⼩程序,在⼀定时间内再次打开⼩程序的话,这个时候我们就不再需要重新启动了,这需要把我们的后台打开的⼩程序切换到前台来使⽤。
冷启动:
⽤户⾸次打开⼩程序或被微信主动销毁再次打开的情况,此时⼩程序需要重新加载启动。
⼩程序在进⼊后台之后,客户端会帮我们在⼀定时间内维持我们的⼀个状态,
超过五分钟
会被微信主动销毁.官⽅没有明确说明什么时候销毁,不同机型表现也不⼀样,
2019年开发时:官⽅⽂档没有说明,但是经过询问⼀般指5分钟内2020年开发时:官⽅⽂档没有说明,测试安卓没有固定时间,内存⾜够的情况下,有时候⼀天了还在,有时候⼏分钟就没了
TCP作为一种可靠的传输协议,需要在建立连接和断开连接的过程中进行一些状态的确认和控制。因此,在TCP连接的建立和断开过程中,需要进行三次握手和四次挥手。
三次握手:
第一次握手:客户端向服务器端发送一个连接请求报文段(SYN)。
第二次握手:服务器收到请求后,向客户端回送一个收到确认报文段(ACK),并发送一个连接请求报文段(SYN)。
第三次握手:客户端接收到收到确认报文段后,向服务器端回送一个收到确认报文段(ACK)。
这样,双方完成了三次握手,
TCP连接建立成功。三次握手的目的是确保双方都能收到对方的消息,并且能够正确建立连接。
四次挥手:
第一次挥手:客户端向服务器端发送一个关闭连接的请求报文段(FIN)。
第二次挥手:服务器收到请求后,向客户端回送一个确认报文段(ACK)。
第三次挥手:服务器向客户端发送一个关闭连接的请求报文段(FIN)。
第四次挥手:客户端收到请求后,向服务器端回送一个确认报文段(ACK)。
完成四次挥手之后,TCP连接断开。
四次挥手的目的是确保双方都知道连接已经断开,并且释放所有的连接资源。
可以看出,TCP连接的建立和断开都需要进行一些状态的确认和控制,因此需要进行三次握手和四次挥手。这样可以保证连接的可靠性和正确性。
GET和POST是HTTP协议中常用的两种请求方法,它们有以下几点区别:
1.参数位置:
GET请求的参数是在URL中拼接,而POST请求的参数则是在请求体(body)中传递。
2.请求方式:
GET请求是通过URL向服务器请求数据,在URL中通过问号“?”传参。而POST请求是把数据放在HTTP请求体内提交给服务器。
3.请求长度:
GET请求没有请求体,因此请求长度有限制,目前大部分浏览器限制在2048个字符以内;而POST请求没有限制,但是实际情况一般由于服务器的限制而做出调整。
4.安全性:
GET请求会把参数暴露在URL上,容易受到劫持和攻击;而POST请求因为请求体的存在,相对于GET来说更加安全。
5.缓存:
GET请求可以被浏览器缓存,当下次请求相同的URL时,浏览器直接从缓存中取出数据;而POST请求不会被缓存,每次请求都需要重新传输数据。