前后端认知
- 前端
=> 把后端给的数据展示在页面上(列表页面)
=> 把前端的数据传递给后端, 让后端存储起来(注册) - 后端
=> 当前端需要数据的时候, 后端从数据库里面拿到数据给前端
=> 把前端传递来的数据存储在数据库里面 - 数据库
=> 专门让 后端 进行数据的增删改查
注意: - 前端是不能操作数据库的
- 前端相对数据库进行任何操作, 都要把信息告诉后端
- 由后端进行数据库操作
- 把操作的信息反馈给前端
• php 代码的书写
- php 是一个后端语言(暂时所用的)
=> 运行需要在 apache 服务器上运行
=> 我们要把 php 文件写在 WWW 目录里面
=> 在浏览器以 localhost 的形式运行 - php 代码写在一个 .php 后缀的文件里面
=> .html 后缀的文件不认识 php 代码的 - 每一个 php 文件, 必须要写 php 标签
=> 以 <?php 开头
=> 以 ?> 结尾
=> 所有的 php 代码写在这个标签的中间 - php 文件不允许使用中文命名
=> 如果你用的中文
=> 那么在服务器上打开的时候就会报错
• php 的注释
// 1. 单行注释
/* 2. 多行注释 */
3. 单行注释
• php 的输出语法
- 因为 php 是一个后端语言
=> 前端的输出语法, console.log 或者 alert, 就直接反应再浏览器上了
=> 后端的语法, 是谁找后端要的就给谁
=> 当浏览器赵 php 要的时候, 那么 php 的输出语法就把输出内容给了 浏览器
=> 当 js 这个语言的 php 要的时候, 那么 php 的输出语法就把输出内容给了 js - php 里面的三种输出语法及三种输出语法的详细区别
- echo /ˈekoʊ/反射;重复;回音
=> 只能输出基本数据类型, 复杂数据类型会报错
=> 遇到布尔值的时候, true 会输出 1, false 会输出空白内容 - print_r() /prɪnt/ 打印
=> 可以输出所有数据类型
=> 遇到布尔值的时候, true 会输出 1, false 会输出空白内容 - var_dump() /dʌmp/转储
=> 可以输出所有数据类型
=> 遇到布尔值会正常输出 true 输出 true, false 输出 false
=> 并且会带有数据的类型和数据的信息
php 的变量
- 在 php 里面, 我们定义变量没有关键字
=> 以 $ 开头的就表示一个变量 - 当我定义变量的时候
- $num = 100;
- 变量名叫做 $num
- $ 不是定义变量的关键字, 是变量名的一部分
- 当你要使用变量的时候
- 就直接使用 $num 就可以了
• php 里面的字符串
- 在 php 里面 字符串 定义有两种方式(两种方式是有区别的)
-> 单引号: 就是普通字符串
-> 双引号: 是一个特殊字符串, 可以在字符串里面直接解析变量
php 里面的字符串拼接
- 就是把多个字符串连接在一起
-> 我们在 js 里面的时候, 使用 加号(+) 就能进行字符串拼接
-> 在 php 里面, 加号(+) 只能进行数学运算, 只有 点(.) 才能进行字符串拼接 - 书写的时候
-> 字符串1 . 字符串2
• php 中文乱码的问题
-
问题是怎么来的 ?
=> html 文件之所以能认识中文, 是因为有一个 charset=UTF-8, 告诉了浏览器用什么字符集解析文本内容
=> php 文件只是进行了输出, 没有告诉浏览器你应该用什么字符集来解析文本内容 -
问题怎么解决
=> 只要我在输出之前, 告诉浏览器你用什么字符集格式来解析文本内容
=> 告诉浏览器字符集格式
=> header(字符集格式);
例:header(‘content-type: text/html;charset=utf-8;’);
• php 的分支结构
- 和 js 一样, 有 条件分支语句 和 循环分支语句
=> 条件分支
=> if () {}
=> if () {} else {}
=> switch () {}
=> 循环结构
=> while () {}
=> do {} while ()
=> for () {}
• php 的数组
- js 里面
=> 数组: [1, 2, 3, 4, 5, …]
=> 对象: { name: ‘Jack’, age: 18, … } - php 里面
=> 关联型数组 - 等价于 js 里面的对象
=> 索引型数组 - 等价于 js 里面的数组
- 索引型数组
- 语法: $arr = array(数据1, 数据2, 数据3, …)
- 按照索引下标进行排列
- 如果向单独获取数组里面的某一个数据
=> 写 数组名称[对应的索引] - 关联型数组
- 语法: $arr = array(key1 => value1, key2 => value2);
- 等价于 js 里面的对象
- 注意:
=> 不管是 key 还是 value, 需要用引号包裹, 单引号也行, 双引号也行
=> 不可以不包裹, 如果不用引号包裹, 会被当作变量来使用(报错)
=> 中间用的是 =>, 不是 : 也不是 =
=> 数字和布尔值, 不需要引号包裹, 可以直接使用 - 获取关联型数组里面某一项的值
=> 写 数组名称[‘你要获取的属性名’]
• php 的 json 格式转换
- 为什么要进行 json 格式的转换
=> php 里面的关联型数组时长的和 js 里面一样
=> array( ‘name’ => ‘Jack’, ‘age’ => 18 );
=> 可以正常传递给前端, 但是前端不认识
=> 转换成一个中间商的样子, 转换成一个大家都认识的东西传递过去
=> 都认识的东西就是 json 格式的字符串
=> 因为所有的语言 json 格式时一摸一样的
=> 为了前后端交互更方便 - php 转换 json 格式的两个方法
- 把 php 的数据格式转换成 json 的数据格式
=> json_encode()
=> 语法: json_encode(要转换的 php 数据格式)
=> 返回值: 转换好的 json 数据格式 - 把 json 数据格式转化成 php 的数据格式
=> json_decode()
=> 语法: json_decode(要转换的 json 格式数据)
=> 返回值: 转换好的 php 格式数据
php 的导入语法
- 就是把另一个 php 文件拿到我这里来执行一下
语法: - 在这里导入 base.php 文件
- include “你要导入的文件名称”;
目录: - 直接写文件名, 表示同级目录, 但是不推荐这么写
- ./ 也是表示同级目录, 推荐写法
- …/ 表示上一级目录 例:include “./base.php”;
• php 语言操作数据库 - php 操作数据库有两种语法
- mysql 语法 -> php5 -> 我会同步给你写在注释里面
- mysqli 语法 -> php7 -> 我们学习这个语法
- php 操作数据库有一个固定的步骤
- 和数据库进行连接
- 执行操作
- 解析结果
- 断开连接
- 建立和数据库的连接
- mysqli_connect() 这个方法
- 语法: mysqli_connect(‘IP地址’, ‘数据库用户名’, ‘数据库密码’, ‘你要操作的哪一个小仓库’);
- 操作数据库
- mysqli_query()
=> 所有的操作都是这一个方法, 增删改查都使用这一个方法
-> "SELECT * FROM表名
" -> 查询某一个表里面的所有信息
=> 语法: mysqli_query(‘连接数据库的信息’, ‘你要执行的 sql 语句’);
例: link, 'SELECT * FROMusers
')
=> 返回值: 就是一个查询的结果
-> 依旧时我们看不懂的东西
-> 所以才有第三步解析数据
- 解析结果
- mysqli_fetch_assoc()
=> 不是所有的操作都要解析结果
-> 只有查询操作需要解析,
-> 如果增删改操作, 我们不需要解析结果
=> 语法: mysqli_fetch_assoc(你要解析的数据库查询结果)
=> 返回值: 就是解析好的一个结果, 是一个关联型数组
-> 注意: 这个方法只能解析一条数据
3-2. 解析全部结果 - mysqli_fetch_all()
=> 能把所有的数据都解析出来, 放在一个二维数组里面返回
=> 语法: mysqli_fetch_all(你要解析的结果, 使用哪种方法解析)
-> 那种方法: MYSQL_ASSOC
=> 返回值: 是一个 二维数组, 里面有所有的数据
- 和数据库断开连接
- mysqli_close()
=> 断开和数据库的连接
=> 语法: mysqli_close(连接信息);
常用的 sql 语句
sql 语句的语法规范(你可以不遵守, 建议你遵守)
- sql 语句里面的关键字大写
- 表名和字段名尽可能使用反引号(键盘 tab 键上面那个按钮 ``)包裹
- 注意: 这个不是 es6 的模板字符串, 是 sql 语法规范的一部分
sql 语句的语法规则(你必须遵守, 不然报错)
- 当你写一些文本内容的时候, 需要使用 引号 包裹, 表示是一个 字符串3
插入的 sql 语句
=> 插入就是想用 php 对数据库进行数据插入的操作(注册)
=> 使用 INSERT 关键字
=> 一共有两种语法
- INSERT INTO
表名
VALUES(数据1, 数据2, 数据3, …); /ɪnˈsɜːrt/ 插入 into 到……里面
-> 按照你数据库里面字段的顺序插入的
-> id 我们可以不写, 直接写 null, 会自动增长
-> INSERT INTOusers
VALUES(null, “郭翔”, 18, “男”, “1906”) - INSERT INTO
表名
(字段1, 字段2, …) VALUES(数据1, 数据2, …);
-> 按照你书写的字段添加
-> 值添加某些字段的内容, 剩下的稍后完善的时候在做
=> $res 为 false 的时候
-> 表示的是 sql 语句有错误
-> 第一种方式的时候, 必须要完全按照数据库里面的字段数量添加
-> 第二种方式的时候, 字段和数据库里面不匹配的时候就会报错
删除的 sql 语句
=> 就是想用 php 去删除数据库里面的某些数据
=> 使用 DELETE 关键字
=> sql 语句
-> DELETE FROM表名
WHERE 条件
-> 要从哪一个表删除条件为什么的数据
修改的 sql 语句
=> 想用 php 去操作数据库修改某一条数据的内容
=> 使用 UPDATE 关键字
=> sql 语句
-> UPDATE表
SET 字段=新值 WHERE 条件
-> UPDATE表
SET 字段=新值, 字段2=新值 WHERE 条件
查询的 sql 语句
=> 就是想用 php 去操作数据库查询一些数据
=> 使用 SELECT 关键字
=> 查询的语法 - SELECT * FROM
表
-> 查询这个表里面的所有数据 - SELECT * FROM
表
WHERE 条件
-> 根据我们的条件查询数据库里面的数据 - SELECT * FROM
表
WHERE 条件1 AND 条件2
-> 根据两个条件来查询, 两个条件必须都满足 - SELECT * FROM
表
WHERE 条件1 OR 条件2
-> 根据两个条件来查询, 两个条件满足一个就可以了 - SELECT * FROM
表
WHERE 字段 LIKE ‘%关键字%’
-> 查询数据里面指定字段包含某一个关键字的数据
为啥用单引号或者双引号
-> 再 php 里面 字符串分成两种
-> 单引号, 不能直接解析变量
-> 双引号, 可以直接解析变量
=> 当你需要在字符串里面解析变量的时候, 就是用双引号
=> 当你不需要在字符串里面解析变量的时候, 使用哪一个无所谓
-> 字符串的嵌套, 外面使用双引号, 里面就要用单引号
=> 外面使用单引号, 里面就要使用双引号
常见的请求方式
- 什么是请求方式
=> 前端和后端说话的方式方法
=> 你用不同的方式和后端说话, 他接收到的信息是不一样 - 常见的请求方式有八种(了解)
- GET -> 多用于向服务端获取一些数据
- POST -> 多用于向服务器传递信息
- PUT -> 多用于向服务器传递信息, 并让服务器存储起来
- DELETE -> 多用于让服务器删除一些信息
- HEAD -> 不需要响应体, 主要是为了获取响应头信息
- PACTH -> 和 PUT 类似, 倾向于局部更新
- CONNECT -> 预留方式, 管道连接改成代理连接的方式
- OPTIONS -> 用于允许前端查看服务端性能(服务端同意)
GET 和 POST 请求的区别 ?
GET
- 倾向于向服务器获取数据
- 直接再地址后面进行拼接(请求体是空的)
- 大小限制为 2KB 左右(因为 IE 最多传递 2KB)
- 会被浏览器主动缓存
- 相对于 POST 不是很安全(明文发送)
- 数据格式必须是 url 编码的格式, 如果不是会自动转换成 url 编码
POST
- 倾向于向服务器传递数据
- 再请求体里面传递过去(地址后面没有)
- 理论上是没有限制(但是可以被服务器限制)
- 不会被浏览器主动缓存, 需要手动设置
- 相对于 GET 比较安全的(暗文发送)
- 数据格式理论上我所谓, 但是要和请求头中的 content-type 一致
=> 请求头里面的 content-type 表示请求体的数据格式
注意:
- 当你需要传递和用户相关的隐私信息的时候, 必须要使用 POST 方式发送
- 例如:当我做登录的时候, 一定要用 POST 方式发送请求
cookie - cookie 是一个存放在客户端的存储空间
=> 浏览器是一个软件
=> 当你运行浏览器的时候
-> 一部分位置是来给 页面 运行的
-> 一个小部分位置是专门用来存储数据的 - 这个 cookie 空间里面可以以字符串的形式存储一些数据
=> 数据格式必须是 key=value
=> 多条数据中间用 ; 分隔
=> key1=value1; key2=value2; key3=value3 => 字符串
=> 每一个 cookie 信息还有可能包含过期时间
=> 过期时间就是到达时间的时候, cookie 就消失了
cookie 的特点
- 按照域名存储
- 你在哪一个域名下存储的内容, 就在哪一个域名下使用
- 其他域名都用不了
- 和资源路径地址没有关系
- 存储大小有限制
- 4KB 左右
- 50 条左右
- 或者的关系
- 时效性
- 默认是会话级别的时效性(关闭浏览器就没有了)
- 可以手动设置, 七天后, 两个小时以后
- 请求自动携带
- 当你的 cookie 空间里面有内容的时候
- 只要是当前域名下的任意一个请求, 都会自动携带 cookie 放在请求头里面
=> cookie 里面有多少自动携带多少 - 如果 cookie 空间中没有内容, 就不会携带了
- 前后端操作
- 前端可以通过 js 操作 cookie 空间进行增删改查
- 后端也可以通过任何后端语言进行 cookie 空间的增删改查
发送一个 ajax 的步骤
- 创建一个 ajax 对象
- var xhr = new XMLHttpRequest Request /rɪˈkwest/ 请求;需要
=> 实例化一个构造函数, 得到一个对象
=> 得到的这个对象就能帮我们发送 ajax 请求
- 配置本次请求的信息
- xhr.open(请求方式, 请求地址, 是否异步)
=> 请求方式: GET 或者 POST 或者 PUT 或者 …(大小写无所谓)
=> 请求地址: 你要请求哪一个 php 文件
=> 是否异步: 默认是异步的, 可以改成同步
-> 你如果不传递, 默认是异步的
- 把这个请求发送出去
- xhr.send()
=> 这个方法以执行, 本次 ajax 请求就发送出去了
=> 就发送到 ./ajax.php 文件里面了
- 接受响应
- 为什么要接受响应
=> 因为当 js 和 后端 交互的时候
=> 后端返回的内容不会直接显示再浏览器上
=> 而是给了 js 或者说给了 xhr 对象
=> 我们要拿到这个响应内容(后端给前端的数据) - 怎么接受响应
=> 使用 onload 事件
=> xhr.onload = function () {}
-> 这个事件是 ajax 完成的时候触发
-> 当本次请求完成以后, 就会触发后面的函数了
=> 再事件里面打印一下 xhr(这个 ajax 对象)
=> 再 xhr 这个对象里面
-> responseText 就是响应体
同源策略
跨域的解决方案
- jsonp
- cors
- 代理
jQuery
jQuery属性操作
attr(属性):用于获取属性值
attr(属性,属性值)用于设置属性和属性值,还可以设置自定义属性
removeAttr(属性):用于删除属性,可以删除标准属性和自定义属性
特点:所有的属性都会显示在标签上(原生属性,自定义属性),不管你设置的是什么数据类型,都会变成字符串
prop(属性):用于获取属性值
prop(属性,属性值):用于设置属性和属性值
removeProp(属性):用于删除属性,但是不能删除原生属性,只能删除自定义的属性
特点:这个方法非原生的属性不会在标签上显示,但是可以获取使用,你设置的是什么数据类型,就是什么数据类型
h5标准的自定义属性:data-xxxx
data(属性):获取属性
data(属性,属性值):用于设置属性
removeData(属性):用于删除数据的
注意:里面的属性参数与原生属性没有关系,可以设置为id,但是和元素的id没有关系,不在标签上显示,就是在元素的身上开辟一个地方,存储一些数据,你设置的是什么类型,就是什么数据类型
jQuery的样式操作
css(属性):获取指定属性的属性值,不管是行内还是非行内都能够获取,只获取元素集合中的第一个元素的属性
css(属性,属性值):设置样式(隐式迭代,能获取多少就设置多少)
css({属性:属性值,属性:属性值}) //以对象的形式设置属性和属性值,可以设置多个
jQuery的内容操作
没有参数时,是获取,有的时候是设置
html()只能获取第一个元素的超文本内容
text()能够获取元素集合内所有元素的文本内容
Val()只能够获取第一个元素的value值
设置时,这三个方法能够给元素集合里的所有元素设置
jQuery的筛选器函数
first():筛选出来元素集合中的第一个元素
last():筛选出来元素集合的最后一个元素
eq(n):筛选出来元素集合中索引为n的那个
next():筛选出来元素的下一个兄弟元素
nextAll():筛选出来元素后面的所有兄弟元素
nextUntil(选择器):筛选出来这个元素后面的所有的兄弟元素,直到选择器元素为止,不包括选择器元素
prev():筛选出来该元素的上一个兄弟元素
prevAll():筛选出来该元素前面的所有的兄弟元素
prevUntil(选择器):筛选出该元素前面的所有兄弟元素,到选择器元素为止,不包括选择器元素
parent():筛选出该元素的父元素
parents():筛选出该元素的所有祖先元素,直到html元素为止,包括html元素
parentsUntil(选择器):筛选该元素的所有祖先元素,直到选择器元素为止,不包括选择器元素
children():筛选出元素的子元素
children(选择器):筛选子元素中符合选择器的元素
siblings():筛选出所有的兄弟节点自己不算
siblings(选择器):筛选出符合选择器的兄弟节点
find(选择器):在所有子元素里找,只要有,就能找到
index():获取元素在该父元素下的第几个元素,获取索引
jQuery操作元素类名
addClass(类名):添加类名,可以添加多个类名,如:.addClass(“a b c”)
removeClass(类名):删除类名
toggleClass(类名):切换类名,如果有就删除,如果没有就添加
hasClass(类名):判断有没有这个类名
jQuery绑定事件
用on方法专门绑定事件
on(‘事件类型’,事件处理函数)=》给元素集合内所有的元素绑定一个事件
on(‘事件类型’,’事件委托’,事件处理函数)=》把事件委托位置的元素的事件委托给前面的元素集合
on(‘事件类型’,’复杂数据类型’,事件处理函数)=》给每一个元素绑定一个事件,复杂数据类型的数据是触发事件的时候传递的
on(‘事件类型’,’事件委托’,’任意数据类型’,事件处理函数)
on(对象):给一个元素绑定多个事件的方式
如:.on({
click:function(){},
mouseenter:function(){}
})
one()方法专门用来绑定一个只能执行一次的方法
off():用来解绑一个元素的事件的:
off(‘事件类型’):给该事件类型的所有处理函数解绑,
off(‘事件类型’,事件处理函数):解绑指定事件处理函数
*:one和on绑定的事件都能移除
trigger():专门用来触发事件的方法(不通过点击,而用代码把事件触发)
trigger(‘事件类型’):把该元素的事件给触发了
常用事件:如click(参数,事件处理函数);//该参数是触发事件时传递到事件中,用事件处理函数中的形参e接受,存放在data属性中(e.data)
jQuery的节点操作
创建节点:$(‘
用html格式创建节点
’)插入节点:
内部插入:
页面元素.append(要插入的节点) //插入到页面元素子节点的末尾
还有一个方法要添加的元素.appendTo(页面元素)
页面元素.prepend(要插入的元素) //插入到页面元素子元素的第一个
还有一个方法:要插入的元素.prependTo(页面元素)
外部插入:
页面元素.before(要插入的元素): //插入到页面元素的之前(兄弟节点级别)
还有一个方法:要插入的元素.insertBefore(页面元素)
页面元素.after(要插入的元素): //插入到页面元素的之后(兄弟节点级别)
还有一个方法:要插入的元素.insertAfter(页面元素)
删除节点:
页面元素.empty():删除页面元素里的子元素
页面元素.remove():删除页面元素及其子元素,该方法可以传递一个选择器作为参数,可以用于筛选删除的元素
替换节点:
页面元素.replaceWidth(替换的元素) //用替换元素把页面元素替换掉,有多少替换多少
替换元素.replaceAll(页面元素) //一样是用替换元素把页面元素替换掉,不过操作的元素相反
克隆节点:
clone():不传参数和传参数都是克隆子节点,有两个参数,都是布尔值,第一个参数,默认为false,当第一个参数为false时,第二个参数没有意义,第二个参数跟随第一个参数,第一个参数表示是否克隆元素的事件,第二个参数表示是否克隆子元素的事件
返回值就是,克隆出来的节点
jQuery尺寸
width()和height():用来获取元素的宽高(不包括内外边距和边框)
innerWidth()和innerHeight():用来获取元素的宽高(包括内边距,不包括外边距和边框)
outerWidth()和outerHeight():用来获取元素的宽高(包括内边距和边框,不包括外边距)
outerWidth(true)和outerHeight(true):用来获取元素的宽高(包括内边距和边框,外边距)
注意:当设置为box-sizing:border-box后,width()得到的是css设置的宽度-padding值和border值
jQuery获取元素的位置
offset():当没有参数时是获取,获取的是一个对象{left:xxx,top:xxx},读取的元素相当于页面的位置
当有参数时是设置位置:元素.offset({left:xxx,top:xxx}),绝对写入,不管你本身和页面的尺寸是多少,我写多少就是多少
position()一个只读的方法,元素相对于定位父级的位置关系,得到的是一个对象{left:xxx,top:xxx}.如果你写的是right和bottom会自动转化为left和top
scrollTop():不传参数时是获取卷上去的高度,触发滚动事件是获取,有参数时是设置距离页面顶端的高度,还有一个方法是:scrollLeft()是宽度
jQuery中的方法
ready():jQuery的入口函数,在页面标签加载完之后执行,而js的window.onload入口函数是在页面的资源加载完毕后执行
格式:
(function(){
})
each()方法:相当于原生js中的forEach()方法,(.forEach((item,index)=>{}))用于遍历jQuery中的元素集合,
如:.each((index,item)=>{index是索引,item是每一项}),参数和原生js的forEach方法相反
jQuery的动画
-
隐藏和显示:
隐藏:hide(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
显示:show(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
隐藏和显示切换:toggle(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback) -
淡入淡出:
淡入:fadeIn(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
淡出:fadeOut(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
淡入和淡出切换:fadeToggle(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
fadeTo(时间(必填),透明度(必填),过渡是用那种缓动函数(swing,linear),callback)
//用于渐变为指定的透明度
3.滑动
向上滑动:slideUp(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
向下滑动:slideDown(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
向下滑动和向上滑动切换:slideToggle(时间(fast,slow,或者毫秒),过渡是用那种缓动函数(swing,linear),callback)
4.动画
animate({定义动画的css属性,包括大部分的属性,不包括transform和颜色},时间,过渡的缓动函数,callback)
注意:如果要进行位置操作,要把元素的CSS样式设置为position:relative/absolute/fixed
- 结束动画
//因为你要是一直点击运行动画会出现问题,所以要有停止动画的方法
stop():停止动画
finish():当这个函数触发的时候,就让运动立即停止,不管运动到那个位置,瞬间到达动画结束的位置
jQuery发送ajax请求
$.get()方法专门用来发送get请求
$.get(’./lili.php’,{a:100,b:200},res=>{console.log(res)},‘json’);
$.post()方法专门用来发送post请求
$.post(’./lilili.php’,‘a=200&b=300’,res=>{console.log(res)},‘json’);
$.ajax()方法用来发送各种请求,需要配置信息
let obj={name:'康康',age:23 };
$.ajax({
url:'./lili.php',
type:'GET', //请求的方式,默认为get请求
data:'a=4&b=5',
dataType:'json',
async:true, //是否异步,默认为true
success:function(res){
console.log(res)
console.log(this)
},
error:function(xhr,err,info){
console.log(xhr);
console.log(err);
console.log(info);
},
context:obj, //回调函数中this的指向,指向外面的obj对象
cache:false ,//是否缓存,默认为true,如果是false,则会在data后面自动添加_=时间戳
timeout:1000,//响应时间,单位是毫秒,超过这个时间,是失败,触发失败回调函数
})
jQuery发送一个jsonp请求
jsonp也是用$.ajax()
$.ajax({
url:'./jsonp.php',
dataType:'jsonp', //dataType必须写成jsonp
//这个函数就是相当于原生js中的重写函数,只不过jQuery在内部帮你做了
success:function(res){
console.log(res);
},
error:function(err){
console.log(err);
},
jsonp:'cb' //jsonp属性是带到后端表示函数名的key,不写默认是callback
})
//发送jsonp请求jQuery帮我们准备了一个函数名,并且以参数的方式带到了后端
jQuery的ajax全局钩子函数
钩子函数:一直在ajax身上挂着,ajax的行为改变时,就触发对应的钩子函数
ajaxStart(function(){}):在同一个作用域内,第一个ajax请求开始之前触发,有多个ajax请求时,只会触发一次
ajaxSend(function(){}):每一个ajax在发送请求之前触发,在xhr.send()之前触发
ajaxSuccess(function(){}):每一个ajax在成功的时候触发,只要有一个成功就触发
ajaxError(function(){}):每一个ajax在失败的时候触发,只要有一个失败就触发
ajaxComplete(function(){}):每一个ajax在完成的时候触发,不管成功和失败,都会触发
ajaxStop(function(){}):在最后一个ajax完成的时候触发,只触发一次
//使用:
$(window).ajaxStart(function(){})
jQuery的多库共存
因为jQuery是一个类库,当多个类库在一起时,就会出现冲突
$,和jQuery这两个变量会冲突
不能用了,传参数为true时,
和jQuery使用
let lili=$.noConflict(true);
console.log(lili("div").html());
jQuery的插件扩展机制
$.extend({
要扩展的函数名:function(){},
要扩展的函数名:function(){}
})
//扩展给jQuery自身,调用方法的时候用:$.方法名()
// $.extend({
// lili:function(){alert(1111)}
// })
// $.lili();
$.fn.extend({
要扩展的函数名:function(){},
})
也用来扩展,扩展给元素集合使用的,调用的时候用$(选择器).扩展的函数名()
// $.fn.extend({
//eee:function(){
// alert('eee');
//}
// })
jQuery的深拷贝
$.extend(是否深拷贝,(默认为false)对象1,对象2…)方法传递一个对象时可以做到插件扩展,传递多个参数时,可以将后面几个对象的内容拷贝到第一个对象中,在拷贝的时候,如果有重复的key按照后面的拷贝
闭包
闭包的生成有三个必要的条件:
-
在函数a内部间接或者直接return一个函数b
注:直接return一个函数:return function(){}
间接return一个函数:return{bbb:function(){}}
return一个对象或者数组,这个对象中有函数 -
在函数b中使用函数a的私有变量
-
用一个变量接收函数b,形成一个不会销毁的执行空间,如果不接収,执行a(),会被回收
闭包的特点:
- 延长了变量的生命周期。优点:执行空间不销毁,变量也没有销毁,缺点:变量一直在内存中
- 可以访问函数内部的私有变量。优点:可以利用闭包函数,访问函数内部的私有变量,缺点:变量一直在内存中
- 保护私有变量。优点:保护私有变量不会被外界访问,缺点:如果要访问,就必须要使用闭包函数
闭包的作用:
- 当你想要延长变量的生命周期
- 需要访问一个函数内部的私有数据,可以用闭包函数,如果不是万不得已,不要用闭包
函数的调用:
函数定义的时候在堆中有个函数存储空间,将函数体以字符串形式存入,按照函数名,或者变量名找到对应的存储空间,每一个函数的调用都会开辟一个函数执行空间,进行形参赋值,预解析,里面的内容复制函数存储空间,代码执行完毕,这个执行空间销毁
当函数内部,return一个复杂数据类型时,并且在外面用一个变量接收,这个执行空间就不会销毁,当这个变量指向别的位置时,销毁
继承
继承:继承是发生在两个构造函数之间的关系
构造函数的书写标准:属性在构造函数中写,方法在原型链上写(原因:每次new出来对象,就有一个函数空间被开辟,浪费空间,所以写个原型,多个对象都可以用)
Es5的继承方法:
- 原型继承:通过改变原型链的方式达到继承:子类.prototype=父类实例,继承的属性和方法不在子类身上,但是可以使用,参数要在子类和父类中分别传递
function Person(name){
this.name=name;
}
Person.prototype.getName=function(){
console.log("我的名字是:"+this.name);
}
function Student(age){
this.age=age;
}
Student.prototype=new Person("康康");
let aaa=new Student(23);
console.log(aaa);
- Call继承:call()函数是强行改变this的指向,第一个参数是要改变的this指向,后面的参数是要传递的参数,在子类的构造函数中写:父类.call(this),但是不能继承原型链上的方法,继承的属性在子类身上,参数都在子类上传递
function Person(name){
this.name=name;
}
Person.prototype.getName=function(){
console.log("我的名字是:"+this.name);
}
function Student(age,name){
this.age=age;
//在子类构造函数中写
//构造函数也可以当做普通函数用
Person.call(this,name);
}
let aaa=new Student(23,"康康");
console.log(aaa); //但是不能继承原型链上的方法,只能继承构造函数里面的
- 组合继承:利用原型继承和call继承,组合在一块
function Person(name){
this.name=name;
}
Person.prototype.getName=function(){
console.log("我的名字是:"+this.name);
}
function Student(age,name){
this.age=age;
Person.call(this,name); //call继承继承属性,在子类身上
}
Student.prototype=new Person(); //原型继承,继承原型链上的方法,不用传值
let aaa=new Student(23,"康康");
console.log(aaa);
Es6的继承:
用extends和es6中的super()方法继承,super()必须要写在子类构造函数的第一行
class Person{
constructor(name){
this.name=name;
}
getName(){ //原型方法,省略function关键字
console.log("我的名字是:"+this.name);
}
}
class Student extends Person{
constructor(age,name){
super(name);
this.age=age;
}
}
let aaa=new Student(23,"康康");
console.log(aaa);
设计模式
设计模式:针对特定的问题,给出的简介而优化的处理方案
单例模式:
使用构造函数,生成实例化对象,如果生成的实例化对象的属性,方法都完全相同,那么就生成同一个实例对象。
应用:弹出层,因为alert()太丑,所以要自己写div,只要一个实例对象,改变其文本就行
let Person=(function(){
let contain=null;
function Person(){} //这个是真实的构造函数
return function(){return !contain?contain=new Person():contain;}
})()
let p1=new Person();
let p2=new Person();
console.log(p1===p2);
组合模式:
把几个构造函数的入口函数组合在一起,然后通过一个遥控器进行统一调用
箭头函数不能够当做构造函数new,是不是构造函数的标志是,是否用new
class Play{
constructor(){
}
//构造函数的入口函数
init(){
console.log("睡觉");
}
}
class Eat{
constructor(){
}
//构造函数的入口函数
init(){
console.log("学习");
}
}
//组合模式的代码
class Compose{
constructor(){
this.composeArr=[];
}
//向数组里面添加实例对象
add(obj){
this.composeArr.push(obj);
}
//总开关,这个函数执行了,里面所有的实例的入口函数也都执行
init(){
this.composeArr.forEach(item=>item.init());
}
}
let c=new Compose();
c.add(new Play());
c.add(new Eat());
c.init();
观察者模式:
让观察者看着被观察者只要被观察者的数据发生改变,就让观察者做一些事情
发布/订阅角度:
- 消息盒子:{click:[fn1,fn2,fn3]}
- 添加订阅的方法:向消息盒子里添加内容
- 取消订阅的方法:把已经订阅的方法从消息盒子内部拿走
- 发布事件的方法
当你切换到浏览器别的选项卡,或者最小化,或者切换回来时触发:
document.onvisibilitychange=function(){
//document.visibilityState 状态hidden和visible
}