← 前端作品集

前端学习笔记

从页面结构到交互逻辑,沿着自己的学习轨迹逐步复习。

前端创作桌上的夜乃樱
这是我从 Typora 导出的原始长文档(约 1.1 万行),没有目录,建议用 Ctrl+F 搜索关键词;也可以直接看旁边的章节顺序:入门 HTML → 入门 CSS → 布局 → JavaScript → Ajax → Promise。

前端学习笔记

(原始导出文件的标题是「Python学习——前端版」,但这份文档记的全是前端内容: HTML / CSS / 布局 / JavaScript / Ajax / Promise。课程名带「Python」只是当时的课程命名, 标题在这里按实际内容改了一下,方便以后翻回来时不用猜。)

前端:

用户交互,数据交互

入门html

html不会报错,会强行修改代码,执行的未必就是写的代码

打开文件:

右击文件资源管理器

html:

超文本标记语言,是构成web页面的基本元素

注释
单标签
双标签
层级关系
代码模板

标签性质

块标签
  1. 默认占据一行
  2. 多个块标签在同一层级,按顺序堆积
行内标签
  1. 行内标签,它就是内容
  2. 行内标签的大小,就是内容的大小
  3. 跟内容一起排布的,多放在快标签里
图片标签

在厚渡之网上只能用相对路径和网络路径


绝对不能在属性之间加逗号


超链接标签(链接文件)

.md文件不能展示,只能下载后查看,可以转化为html导出来查看

超链接标签可以放入index文件当做主目录导航使用

不常用标签
排序标签
无序标签
有序标签
特殊符号

表格和表单

在web里只有行的概念,没有列,有单元格对应的标签

合并

分为纵向和横向合并

表单

是一个用来提交数据的工具,表单只有一部分

前端无法和数据库直接进行交互,需要第三方语言进行操作

表单控件



入门CSS

认识css

css是样式

CSS使用方法
CSS选择器

对于所有的标签,没有特定属性

所有的属性都可以设置任何标签,只是有些标签有效果,有些没效果

CSS选择器进阶
伪类选择器

选择器权重
盒子模型

块盒子外边距会合并,且外边距会超出父盒子

对于块盒子实现间距建议使用内间距


布局

布局就是设置上下左右的空间,宏观布局和微观布局

布局原理简单,但套娃容易让人混淆‘

flex布局技术

取色:截图后按C取色号

小技巧:

  1. 布局不要去固定高度

文字样式

具体文本的一些样式,CSS无法直接操作文本,只能通过标签控制文本


盒子样式

标准盒模型中width指的是内容区域content的宽度;height指的是内容区域content的高度。 标准盒模型下盒子的大小 = content + border + padding + margin

怪异盒模型中的width指的是内容、边框、内边距总的宽度(content + border + padding);height指的是内容、边框、内边距总的高度


定位

层级
其他



JavaScript

JavaScript是一种直译式脚本语言,是一种动态类型,弱类型,基于原型的语言

功能:操作html,响应浏览器事件,用户行为交互,数据验证,前后端交互

基本内容

使用方式
输出方式

数据与变量

变量声明
数据类型
引用数据类型
函数
定义函数
调用函数
DOM操作
事件

语句

判断语句
判断语句

类型操作

类型转换
字符串常用方法
数组常用方法
定时
数学库
时间类型
储存技术
cookie

用户访问网站时,将一些字符串信息保存起来,当下次访问时可以直接读取到上次储存的信息

在服务器环境下才能使用cookie

客户端和后端都可以设置cookie

每个网页之间的cookie不共享,每个浏览器之间的cookie不共享

与后端的所有交互都会自动带上cookie

单个域名cookie的大小不能超过4kb

基础写法
封装
Storage本地储存

本地储存分为临时储存和永久储存,相比cookie:

本地储存的数据量更大,每个域名5M

本地储存只在客户端进行操作

本地储存不会每次请求都自动带上数据,减少请求压力

本地储存不兼容低版本浏览器

临时储存,关闭浏览器再打开没有数据

数据不共享,打开同域新页面没有数据

永久储存,关闭浏览器再打开对应页面也有数据

数据共享,打开同域页面也有数据

IOS设备客户端无痕模式存储不了,所以最好提前判断是否存在localStorage对象

aJax

原生的Ajax即“ Asynchronous Javascript And XML"(异步JS和XLM)是指一种创建交互式网页应用的网页开发技术

Ajax可以在不刷新页面的前提下向后端发送/请求数据,在开发中必然会用到

原生的Ajax

没用经过封装的原生Ajax非常复杂,使用起来代码也极为不协调,并且如需多次请求会出现回调的情况,所以一般不使用原生Ajax

jQuery的ajax

使用jQuery的Ajax要先引入jQuery库,但仍然没有解决回调地狱问题

fetch与axios

fetch和axios都使用了ES6的promise方案来解决回调地狱的问题,所以目前我们在使用Ajax的时候比较多的是采用这两种方案,从功能与完善度来讲,axios更好用

fetch

fetch是ES6引入的新API,所以只要浏览器支持ES6,那么对fetch就是支持的,不需要额外的引入

基础使用:

fetch是一个底层的API,功能不完美,400和500的状态码也会当成成功来处理,默认也不带cookie,并且不支持超时控制与阶段监听,所以一般情况下使用axios

axios

axios是一个基于promise的http库,可以用在浏览器和node.js中,原生js并不支持axios,浏览器环境需要引入axios

基础使用
直接执行
发送多个请求
全局拦截器
移除拦截器:
创建实例:

跨域与jsonp

当我们往一个地址发送请求时,需要确保该地址和你运行HTML文件的地址为同源关系(协议、ip、端口都相同),否则是会出现跨域问题的。报错信息类似于:

Access to XMLHttpRequest at 'https://www.baidu.com/' (redirected from 'http://www.baidu.com/') from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

跨域问题最常用的解决方案有两种,一种是在对应地址的后端设置允许你HTML地址的请求,另外一种是使用jsonp的形式请求数据(需要特定格式数据才行)。

Promise

概念

promise是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理

promise简单地说就是一个容器里面保存着某个未来才会结束的事件(通常是异步操作)的结果

特点

promise对象代表一个异步操作,有三种状态:

pending(进行中),fulfiled(已成功)和rejected(已失败)

之后异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态

缺点
  1. 无法取消promise,一旦新建就会立即执行,无法中途取消
  2. 如果不设置回调函数,promise内部抛出的错误不会反应到外部
  3. 当处于pending状态时,无法得知目前进展到哪一个阶段
用法

写js必然不会对异步事件陌生

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

也就是说,状态由实例化时的参数(函数)执行来决定的,根据不同的状态,看看需要走then的第一个参数还是第二个。

resolve()和reject()的参数会传递到对应的回调函数的data或err

then返回的是一个新的Promise实例,也就是说可以继续then

链式操作的用法

所以,从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:

runAsync1、runAsync2、runAsync3长这样↓

在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中也可以接收到数据:

reject的用法

前面的例子都是只有“执行成功”的回调,还没有“失败”的情况,reject的作用就是把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。

resolve和reject永远会在当前环境的最后执行,所以后面的同步代码会先执行。

如果resolve和reject之后还有代码需要执行,最好放在then里。

然后在resolve和reject前面写上return。

#Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

#Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

p的状态由p1、p2、p3决定,分成两种情况。

  1. 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled。 此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  2. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

promises是包含 3 个 Promise 实例的数组,只有这 3 个实例的状态都变成fulfilled,或者其中有一个变为rejected,才会调用Promise.all方法后面的回调函数。

如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法,如果没有参数没有定义自己的catch,就会调用Promise.all()的catch方法。

#Promise.race()

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

#Promise.resolve()

有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。

上面代码将123转为一个 Promise 对象。

Promise.resolve等价于下面的写法。

Promise.resolve方法的参数分成四种情况。

  1. 参数是一个 Promise 实例

    如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

  2. 参数是一个thenable对象

    thenable对象指的是具有then方法的对象,比如下面这个对象。

    Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。

    上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出 42。

  3. 参数不是具有then方法的对象,或根本就不是对象

    如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。

    上面代码生成一个新的 Promise 对象的实例p。由于字符串Hello不属于异步操作(判断方法是字符串对象不具有 then 方法),返回 Promise 实例的状态从一生成就是resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。

  4. 不带有任何参数

    Promise.resolve方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

    所以,如果希望得到一个 Promise 对象,比较方便的方法就是直接调用Promise.resolve方法。

    上面代码的变量p就是一个 Promise 对象。

    需要注意的是,立即resolve的 Promise 对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。

    上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log('one')则是立即执行,因此最先输出。

    #Promise.reject()

    Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

    上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。

    注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

    上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。