JavaScript
介绍
概念
js: 是基于对象和事件驱动的解释性的脚本语言;
特点
\1. 基于对象: 一切皆对象, js可以使用自己创建的对象
\2. 事件驱动: 都是由事件来进行响应的
\3. 解释性: 相对于编译性来说, 浏览器可以直接识别js,并且去执行
\4. 跨平台性: 只要浏览器支持js 那么js就可以运行 与操作系统与环境无关
\5. 相对安全性: 有同源策略限制
组成部分
ECMAScript:语法标准
DOM: Document Object Model 文档对象模型
BOM: Browser Object Model 浏览器对象模型
与ECMAScript的关系?
js是ECMAScript的表现;
ECMAScript是js的语法标准;
引入
行内
行内: 事件 不推荐使用
缺点: 1. 没有实现三分离
\2. 不利于封装复用
\3. 局限性
内嵌 行内: 事件 不推荐使用缺点: 1. 没有实现三分离
\2. 不利于封装复用
\3. 局限性
从上到下依次执行每一个script
外链
外链式: script双标签 工作 推荐使用
script可以放在页面的任何位置 推荐放在body的结束标签之前
注意: 外链的script标签 不允许写内嵌代码
再写一个script放内嵌代码
注意: js文件:
\1. 后缀.js
\2. 不用写script
注释
// 注释后的代码在文件中看到 没有任何作用
// 注释单行 ctrl + /
/*
块注释 ctrl + shift + /
vscode–首选项—键盘快捷方式–搜索: comment —修改块注释
js: 不能出现 -
必须使用英文符号
每行代码结束必须加;
*/
调试
alert: 弹出框 警告框
alert(‘内容’);
一次只能弹出一个 阻断页面
// alert(‘123’);
prompt(‘提示内容’, ‘默认值’); 对话框
有返回值, 可以接收
取消: null
确定: 输入框的内容
alert(prompt(‘请输入数字’, ‘12’));
document.write(’’, ‘’, ‘’)
document.write(…data);
输出到页面, 不会覆盖自身输出的内容
可以识别标签
写在页面加载完成之后的时候 会覆盖页面的内容
document.write(‘12345’);
document.write(‘这是b标签’);
输出在控制台:
console.log(…data);
右键检查/f12—> Console --> 查看
快捷简写: log
console.log(‘1’, ‘2’, ‘3’, ‘adesdf’);
console.log(‘123’);
断点调试
断点: 阻断代码从头到尾执行 手动控制
\1. f12打开控制台–>Source
\2. 打开要调试的文件
\3. 设置断点: 点击对应的行数 切换到要调试的小的部分
\4. 刷新页面
\5. 具体查看
变量
概念
变量: 用来存储数据的容器
在内存中存储数据的名称
声明变量: var 变量名;
命名规范:
\1. 变量名由字母、数字、_、$组成, 其中数字不能开头
\2. 不能使用关键字和保留词 var let import const for break top(额外注意)
\3. 不能重复 如果重复后面的就会覆盖前面的
\4. 具有语义化 user password
\5. 使用驼峰命名法 多个小单词组成 从第二个之后的单词的首字母大写 userName familyName idCard userPassword
声明变量:
先声明 后赋值
var user;
user = ‘迪丽热巴’; // 将等号右边的赋值给等号左边
console.log(user);
声明的同时并赋值 var 变量名 = 值;
var pass = 123456;
console.log(pass);
先多个声明 再赋值
// var 变量名1 , 变量名2 , … , 变量名n;
// 变量名1 = 值1;
var a1, a2, a3;
a1 = 10;
a2 = 20;
a3 = 30;
console.log(a1, a2, a3);
连等声明
// var 变量名1 = 变量名2 = 值;
var b1 = b2 = 500;
console.log(b1, b2); // 500 500
错误提示:
var _a = 10;
var $ = 30;
console.log(_a, $);
// var一个变量名为var的变量
// var var = ‘a’; 报错
特殊声明
只声明 不赋值 得到就是undefined
// 1. 只声明 不赋值 得到就是undefined
var a;
console.log(a); // undefined
不声明 直接赋值
// 2. 不声明 直接赋值
// 不推荐大家使用 不能区分全局和局部变量 不能垃圾回收
b = 30;
console.log(b);
不声明 不赋值 直接使用
// 3. 不声明 不赋值 直接使用
// 报错
console.log©;
// c is not defined: c没有被定义
数据类型
为什么要分类
\1. 不同数据类型 在内存中所占的存储空间大小不同 存储的位置不同
\2. 不同数据类型 业务是不同的 数字进行计算 布尔值判断
分类
数据类型分类: 五大基础数据类型 一大复杂数据类型
基础: number string boolean null undefined
复杂: object(object array function)
验证:
typeof 数据
typeof(数据)
var a = 10;
typeof a; // 没有输出的
console.log(typeof a); // number
console.log(typeof(a)); // number
基础
number
\1. 整数 正整数 负整数 0
var a = 30;
var b = -500;
console.log(typeof b); // number
\2. 浮点数: 有一位小数点并且小数点后不为0
注意: 由于计算机存储精度问题, 不会用小数做计算
var c = 10.01;
console.log©;
console.log(typeof c); // number
// js没有分数 /做除法
console.log(1/20);
console.log(1/3);
// 注意: 由于计算机存储精度问题, 不会用小数做计算
// 一定要用小数计算 可以同时扩大倍数后在计算
console.log(0.1, 0.2);
console.log(0.1 + 0.2); // 0.30000000000000004
\3. NaN: Not a Number 不是一个数字
\1. 自定义
\2. 计算错误/失败 10 - ‘a’
特点:
\1. typeof以后返回number
\2. NaN与任何数值都不相等 包括自身
\3. NaN与任何其他数值计算结果都是NaN
var d = NaN;
console.log(d, typeof d); // number
console.log(10 - ‘a’); // NaN
console.log(NaN == NaN); // false
console.log(NaN + 100); // NaN
\4. 进制数
4.1 八进制数: 以0为开头 并且没有超过8的数字
4.2 十六进制数: 以0x为开头 0-9a-f表示0-15 a: 10 b: 11 c: 12 d: 13 e: 14 f: 15
// 4.1 八进制数: 以0为开头 并且没有超过8的数字
var mn = 070;
// 08的0次 + 78的1次 = 56
console.log(mn);
// 4.2 十六进制数: 以0x为开头 0-9a-f表示0-15 a: 10 b: 11 c: 12 d: 13 e: 14 f: 15
var n = 0xf;
console.log(n);
\5. Infinity: 无穷大 正负 -Infinity
console.log(1/0);
console.log(-1/0);
\6. e: 10的幂
// 10000 1e4
var ab = 1e10;
console.log(ab);
string
string: 字符串 用成对的单双引号包裹的
var a = “1234a”;
console.log(a);
console.log(typeof a); // string
var b = ‘123’;
console.log(b);
console.log(typeof b); // string
''号中不允许出现换行 可以加\
var c = ‘赛场上我们胜了,赛场下我们同样胜了——今天中国人关注的“精彩”,远远不只是争金夺银的瞬间,“后发先至”“永不言弃”“公平竞争”“相互尊重”一样引来阵阵掌声。这是新时代的今天,投射到奥运赛场上的一种中国眼界、中国风范、中国情怀。赛道浓缩了发展史。1932年,刘长春在美国洛杉矶参加的两个项目,小组赛上均是最后一名;2021年,苏炳添在东京奥运会的百米赛道上,昂然刷新亚洲纪录。同样是奥运赛道,表述的却是从落后到腾飞的不一样的历史。’;
字符串长度: 字符串.length
console.log(c.length);
获取指定下标的字符
下标: 从左往右数, 从0开始的数字
字符串.charAt(下标)
字符串[下标] ie8+
// 1. 字符串.charAt(下标)
console.log(c.charAt(51));
// 2. 字符串[下标] ie8+
console.log(c[51]);
字符串拼接
字符串需要拼接的时候 使用 + 进行连接
只要+左右有一边是字符串 就会进行字符串的拼接
步骤: 1. 删除 要替换的内容 2. 加 2个引号(与最外层引号一致的引号)2个加号(2个引号中间) 3. 拼 变量(两个+中间)
console.log(‘hello javascript’);
var user = ‘javascript’;
// 字符串需要拼接的时候 使用 + 进行连接
// 只要+左右有一边是字符串 就会进行字符串的拼接
// 步骤: 1. 删除 要替换的内容 2. 加 2个引号(与最外层引号一致的引号)2个加号(2个引号中间) 3. 拼 变量(两个+中间)
console.log('hello ’ + user + ‘’);
// hello javascript, 今年 26 岁
var age = 27;
console.log('hello ’ + user + ‘, 今年 ’ + age + ’ 岁’);
boolean
boolean: 布尔值 只有2个值 true(真) false(假)
用于判断条件或者判断条件的结果
var a = 1;
var b = 1;
console.log(a == b); // true
console.log(typeof true); // boolean
// 了解
if(true) console.log(123);
if(false) console.log(456);
null
null: 唯一空值
来做占位 只有本身这一个值
var n = null;
console.log(n);
undefined
undefined: 值的空缺 本身该有 但是现在没有
只有本身这一个值
var m;
console.log(m); // undefined
js中规定 null和undefined相等但是不全等的
console.log(null == undefined); // true
// 数据类型不同
console.log(typeof null); // object
console.log(typeof undefined); // undefined
强制转换
为什么要强制转换
字符串加法会拼接,导致得不到正确的计算结果
所有输入框的值都是字符串
所以需要强制转换
\1. 数值: Number() parseInt parseFloat
\2. 字符: String toString
\3. 布尔: Boolean
Number
Number(数据);
不会改变原数据 返回转换以后的数据
只能转 纯数字字符串、空字符串、空格字符串、布尔值、null, 其他转换结果为NaN
var a = Number(‘123’);
console.log(a, typeof a);
console.log(Number(’’)); // 0
console.log(Number(’ ')); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number(‘12px’));// NaN
console.log(Number(‘px’));// NaN
parseInt
parseInt(数据, [进制]);
[进制]: 可写可不写 默认是十进制
转换规则: 从左往右依次转换每一个字符, 遇到不能转换的,结束转换, 如果第一个字符就转换失败 返回NaN
返回结果是整数
console.log(parseInt(‘80’));
console.log(parseInt(‘80px’)); // 80
console.log(parseInt(‘80.25px’)); // 80
console.log(parseInt(‘a80.25px’)); // NaN
// 八进制数: 070 --> 转换到10 --> 56
console.log(parseInt(‘070’)); // 70
console.log(parseInt(‘070’, 8)); // 56 edge–>仿真—>ie8
parseFloat
parseFloat(数据);
转换规则: 从左往右依次转换每一个字符, 遇到不能转换的,结束转换, 如果第一个字符就转换失败 返回NaN
返回结果是整数、浮点数
console.log(parseFloat(‘80.25px’)); // 80.25
String
\1. String(数据) 可以转换一切数据
\2. 数据.toString([进制]);
进制只对数值类型起作用
/*
1. String(数据) 可以转换一切数据
*/
console.log(String(123));
console.log(String(true));
console.log(String(false));
console.log(String(null));
console.log(String(undefined));
/*
2. 数据.toString([进制]);
进制只对数值类型起作用
*/
var a = 56;
console.log(a.toString(8)); // 将a转换成8进制的数字的字符串
console.log(a.toString()); // 默认10进制
console.log(true.toString());
console.log(false.toString());
// Cannot read property ‘toString’ of null 不能在null上读取到属性toString
// js中的 . 相当于语文的 白勺 的
// console.log(null.toString());
// console.log(undefined.toString());
区别:
String: 强制转换 可以转换一切数据 不能被改变
toSting: 属于对象的一个方法 可以被改变 不能转换null和undefined
Boolean
Boolean(数据);
区分js中的数据的真假:
真: 除了假的都是真的
假: false 0 NaN 空字符 null undefined
console.log(false);
console.log(Boolean(0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(’’)); // false
console.log(Boolean(’ ')); // true
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(-1)); // true
隐式转换
isNaN
isNaN: 判断一个数据 是不是 不是 一个数字
如果数据是真正的数字 返回 false
如果数据不是真正的数字 返回 true
隐式调用 Number(), Number能转化成功的数据, isNaN返回false, 如果转换失败, isNaN返回true
console.log(isNaN( ‘123’ )); // false
console.log(isNaN( ‘123a’ )); // true
console.log(isNaN( ‘abc’ )); // true
console.log(isNaN( true )); // Number(true)—1---false
console.log(isNaN( ‘true’ )); // Number(‘true’) – NaN true
console.log(isNaN( String(null) ) ); // ‘null’ Number(‘null’) true
toFixed
toFixed: 将数值转换成字符串 保留指定位数的小数 2位以上
数值.toFixed(数字);
返回字符串
var num = 100.00;
console.log(num);
console.log(num.toFixed(2));
console.log(typeof num.toFixed(2)); // string
var a = 0.1;
var b = 0.2;
var c = a + b;
console.log(c.toFixed(2));
运算符
分类和概念
运算符: 将两个操作数联系起来的符号, 程序执行的符号
例如: + = - / *
表达式: 由2个以上的操作数和运算符组合起来的式子就叫做表达式
例如: var a = 10; c = 10 + 20;
运算符: 算术 赋值 比较 三目 逻辑
表达式: 由运算符来决定的
算术表达式 赋值 比较 三目 逻辑
算术运算符
算术: + - * / %(取余) ++ –
console.log(10 + 20);
var a = ‘a的数据类型是:’ + typeof 20;
console.log(20 - 10);
console.log(20 * 10);
console.log(20 / 10); // 2
console.log(20 % 10); // 0
console.log(20 % 3); // 2
++: 自加 在自身基础上加1, 可以数据的前面也可以写在数据的后面
var b = 10;
b++;
++b;
var c = 10;
c++;
console.log©; // 11
var d = 10;
++d;
console.log(d); // 11
当++和其他代码放在一起的时候, 在前, 先自加,在执行其他代码, 如果在后,先执行其他代码,再自加
var e = 10;
console.log(++e); // ++e; log(e); 11
console.log(e); // 11
var f = 10;
console.log(f++); // log(f);–10 f++;
console.log(f); // 11
–: 自减 在自身基础上-1, 可以写在数据的前面也可以写在数据的后面
当–和其他代码放在一起的时候, --在前, 先自减,在执行其他代码, 如果–在后,先执行其他代码,再自减
var m = 10;
console.log(m–); // 10
console.log(m); // 9
var n = 10;
console.log(–n); // 9
console.log(n); // 9
隐式转换
数值之间正常计算
有字符串的+, 会变成字符串的拼接
除了字符串的+以外的所有运算,都会尽可能的使用Number()转成number后进行计算
如果遇到复杂数据类型,调用自身的toString方法转成字符串后再参考上述规则;
console.log(10 / 20); // 0.5
console.log(10 * 100); // 1000
console.log(‘a’ + 10); // a10
console.log(‘a’ + true); // atrue
console.log(‘a’ + null); // anull
console.log(‘a’ + undefined); // aundefined
console.log(‘a’ - 10); // NaN - 10 NaN
console.log(true - 1); // 1 - 1 0
console.log(null + 10); // 0 + 10 10
console.log(10 / false); // 10 / 0 Infinity
赋值运算符
赋值运算符: = += -= *= /= %=
=: 将右边的数值赋值给左边
10 = 20!!!! 不允许
+=: 累加
var a = 10;
a += 100; // a = a + 100; a = 10 + 100
console.log(a); // 110
a %= 10; // a = a % 10; a = 110 % 10; a = 0;
console.log(a);
比较运算符
比较运算符: > >= < <= ==(相等) =(全等) !=(不等) !(不全等)
比较运算符左右两边数据的一个大小 看这个表达式是否成立 成立返回true 否则返回false
字符串比较: 从左往右依次比较每一个字符的ASCII编码, 遇到可以比较出来大小的就会结束比较
空: 0
‘0’ – 48
‘9’ – 57
‘A’ – 65
‘Z’ – 90
‘a’ – 97
‘z’ – 122
console.log(1 > 2); // false
console.log(1 < 2); // true
console.log(3 < 3); // false
console.log(3 <= 3); // true
console.log(3 >= 3); // true
console.log(‘2’ < ‘10000’); // 50 < 49 false
== 与 === 区别:
== 只需要值相等
=== 值相等 并且 数据类型也要一致
console.log(1 == ‘1’); // true
console.log(1 === ‘1’); // 数据类型不同 false
console.log(1 != ‘1’); // false
console.log(1 !== ‘1’); // true 数值相等 数据类型不等
逻辑运算符
逻辑运算符: &&(与) ||(或) !(取反)
&&: 左右各自都有一个表达式, 如果两个表达式都为真(true), 整个表达式就为true, 有一个为假就是false
全真为真 一假为假
console.log(true && true); // true
console.log(false && true); // false
console.log(1 < 2 && 2 > 3); // false
console.log(true && 2 <= 3); // true
console.log(false && 2 >= 3); // false
||: 左右各自都有一个表达式, 如果两个表达式都为假(false), 整个表达式就为false, 有一个为真就是true
全假为假 一真为真
console.log(true || false); // true
console.log(true || true); // true
console.log(false || false); // false
console.log(false || true); // true
console.log(1 == ‘1’ || 1 !== ‘1’); // true || true
!: 取反 返回布尔值 将true变成false 将false变成true
假: undefined null false 0 NaN 空字符串
console.log(!1); // false
console.log(!0); // true
console.log(!’’); // true
console.log(!‘abc’); // false
**短路运算: **
逻辑与短路: 当第一个表达式为false, 后面表达不在执行,如果第一个表达式为true, 后面表达式执行
在两个数之间做选择, 如果第一个为真 就执行第二个 如果第一个为假 就执行第一个
var a = true && false;
console.log(a);
var b = 1 && 0; // b = 1 && b = 0;
console.log(b); // 0
var c = 0 && 1; // 在0和1之间选1个数 如果第一个为真 就用第二个 如果第一个为假 就用第一个
console.log©; // 0
var d = ‘a’ && ‘b’;
console.log(d); // ‘b’
逻辑或短路: 当第一个表达式为false, 后面表达式继续执行,如果第一个表达式为true, 后面表达式不执行
在两个数之间做选择, 如果第一个为真 就执行第一个 如果第一个为假 就执行第二个
var m = true || false;
console.log(m); // true
var n = false || true;
console.log(n); // true
var mn = 0 || 1;
console.log(mn); // 1
var o = ‘a’ || ‘’;
console.log(o); // ‘a’
三目运算符
语法: 条件 ? 条件为真, 执行的代码 : 条件为假, 执行的代码;
1 > 2 ? alert(‘翻身农奴把歌唱’) : 2 < 3 ? alert(‘外援赢了’) : alert(‘2立于不败之地’);
优先级
运算符优先级
获取元素
\1. 通过id
语法: document.getElementById(‘id名’)
document: 文档
get: 获取、得到
Element: 元素
ById: 通过Id
只能获取到一个元素, 前缀必须是document
console.log(document.getElementById(‘odiv’)); //
获取正确 语法: document/父元素.getElementsByTagName(‘标签名’);
获取到的是一个集合, 前缀可以是document也可以是父元素
集合不能直接操作, 必须通过下标得到具体的元素之后才能操作
// 通过标签
console.log(document.getElementsByTagName(‘li’)); // HTMLCollection(10) [li, li, li, li, li, li, li, li, li, li]
// 通过父元素获取标签 先获取到父元素
var odiv = document.getElementById(‘odiv’);
// 通过父获取子
var lis = odiv.getElementsByTagName(‘li’);
console.log(odiv);
console.log(lis); // HTMLCollection(3) [li, li, li]
// 下标: 从左往右 从0开始的数字
console.log(lis[0]);
\3. 通过className
语法: document/父元素.getElementsByClassName(‘类名’);
获取到的是一个集合, 前缀可以是document也可以是父元素
集合不能直接操作, 必须通过下标得到具体的元素之后才能操作
只支持ie8以上
// 获取className为box的元素
var boxes = document.getElementsByClassName(‘box’);
console.log(boxes);
console.log(boxes[0]);
console.log(boxes[2]);
鼠标事件
事件三部曲
\1. 获取元素
\2. 加事件 鼠标操作谁就给谁加事件
元素.事件 = function(){}
\3. 写 写具体的代码操作
所有点击之后发生的事情 都写在function后面的{}里
// 描述: 点击div 弹出1
// 1. 获取元素 div
var div = document.getElementsByTagName(‘div’)[0];
console.log(div); // 每次获取元素 必须输出看调试 确定元素是否正确得到
// 2. 加事件
// onclick: 单击事件
div.onclick = function () {
// 3. 写具体的代码操作
console.log(‘单击’);
};
鼠标事件
onclick: 单击事件
ondblclick: 双击
onmousedown: 按下
onmouseup: 抬起
onmouseover/onmouseenter 滑入
onmouseout/onmouseleave 滑出
onmousemove: 移动
oncontextmenu: 右键菜单
// onclick: 单击事件
div.onclick = function () {
// 3. 写具体的代码操作
console.log(‘单击’);
};
// ondblclick: 双击
div.ondblclick = function () {
console.log(‘双击’);
};
// onmousedown: 按下
div.onmousedown = function () {
console.log(‘按下’);
};
// onmouseup: 抬起
div.onmouseup = function () {
console.log(‘抬起’);
};
// onmouseover/onmouseenter 滑入
div.onmouseover = function () {
console.log(‘over’);
};
div.onmouseenter = function () {
console.log(‘enter’);
};
// onmouseout/onmouseleave 滑出
div.onmouseout = function () {
console.log(‘out’);
};
div.onmouseleave = function () {
console.log(‘leave’);
};
// onmousemove: 移动
div.onmousemove = function () {
console.log(‘move’);
};
// oncontextmenu: 右键菜单
div.oncontextmenu = function () {
console.log(‘右键’);
};
over与enter的区别
over: 子元素会触发父元素的事件
enter: 子元素不会触发父元素的事件
// 1. 获取元素
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
// 2. 添加事件
div.onmouseover = function () {
console.log(‘over’);
};
div.onmouseenter = function () {
console.log(‘enter’);
};
操作标签
操作表单标签
单标签只有表单标签有内容, 内容放在value
获取值: var 变量 = 元素.value;
// 1. 获取表单标签
var inp = document.getElementsByTagName(‘input’)[0];
console.log(inp);
// 2. 获取值: var 变量 = 元素.value;
var txt = inp.value;
console.log(txt);
设置值: 元素.value = 值;
inp.value = ‘迪丽热巴’;
获取下拉列表的值: select元素.value
var sel = document.getElementsByTagName(‘select’)[0];
console.log(sel);
console.log(sel.value); // bj
设置值: 元素.value = 值;
值必须是value的内容 与value的值一模一样
sel.value = 'cs '; // 设置不上
sel.value = ‘cs’; // 可以设置
操作闭合标签
操作闭合标签内容:
共同: 都是操作闭合标签 后面覆盖前面的
innerHTML: 可以识别标签
innerText: 不可以识别标签
语法:
获取内容: var 变量 = 元素.innerHTML/innerText;
设置内容: 元素.innerHTML/innerText = 值;
// 1. 获取元素
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
// 2. 获取内容
var html = div.innerHTML;
var text = div.innerText;
console.log(html);
console.log(text);
// 3. 设置内容
// div.innerText = ‘这是新内容’;
// div.innerHTML = ‘这是新内容’;
// 4. 如果想要在元素内容的最后添加其他内容 不覆盖原来的内容
// 使用 原内容 + 新内容
div.innerHTML = div.innerHTML + ‘这是新内容’;
// 简写
div.innerHTML += ‘这是第二个新内容’;
操作属性
属性: 写在起始标签上的 除了标签名以外的都是属性
操作属性:
获取属性的值: var 变量 = 元素.属性;
设置属性的值: 元素.属性 = 值;
所有的属性都按照这种方式来进行操作, class特殊, 由于class是关键字, 不能直接使用, 使用className
// 获取title属性
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
// 获取title的值
var t = div.title;
console.log(t);
// 设置title的值
div.title = ‘我是第一’;
// 操作class属性
var cl = div.className;
console.log(cl);
div.className = ‘abc’;
操作样式
设置样式: 元素.style.属性名 = 值;
// 获取div
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
// 改变背景色为天蓝色
div.style.background = ‘skyblue’;
div.style.width = ‘500px’;
div.style.opacity = 0.5;
批量设置:
元素.style.cssText = 值;
cssText所设置的值内容格式与css一样 :;
div.style.cssText = ‘width: 500px; background: skyblue; opacity: 0.5;’;
\1. js中不能使用 - , 有用到连字符- 转成驼峰命名法
\2. cssText: 会覆盖原来行内的所有样式
div.style.fontSize = ‘50px’;
流程控制语句
流程控制语句: 决定当前代码应该如何执行或者按照什么样的顺序执行
顺序语句: 代码按照从上到下的顺序依次执行
分支语句: if if-else switch
循环语句: for while do-while
分支语句
分支语句: 可以决定后续代码走哪一个代码块
if:
if(条件){
条件为真的时候 执行的代码;
}
简写:
if(条件) 条件为真的时候 执行的代码;
注意: 只能控制紧跟在条件后面的第一句代码
// 假如意外得到100 吃火锅
// var money = 100;
var money = 80;
// if(money == 100){
// alert(‘吃火锅’);
// alert(‘五个菜’);
// }
if(money == 100) alert(‘吃火锅’); alert(‘五个菜’);
if-else: 用于二选一
if(条件){
条件为真执行的代码;
} else {
条件为假执行的代码;
}
if(money == 100){
alert(‘吃火锅’);
} else {
alert(‘吃食堂’);
}
多分支: if-else
多分支: 再有2种以上情况的时候 选择使用
if(条件1){
条件1为真 执行的代码
} else if(条件2){
条件2为真 执行的代码
} else if(条件3){
条件3为真 执行的代码
} else {
以上条件都不符合 执行的代码
}
var core = 88;
var core = -10;
if(core >= 90 && core <= 100){
alert(‘优秀’);
} else if(core >= 80 && core < 90){
alert(‘良好’);
} else if(core >= 70 && core < 80){
alert(‘中等’);
} else if(core >= 60 && core < 70){
alert(‘及格’);
} else {
alert(‘再来一次’);
}
分支语句嵌套
var core = 88;
var core = -10;
// 成绩取值 在 0–100
if (core >= 0 && core <= 100) {
// 判断成绩
if (core >= 90 && core <= 100) {
alert(‘优秀’);
} else if (core >= 80 && core < 90) {
alert(‘良好’);
} else if (core >= 70 && core < 80) {
alert(‘中等’);
} else if (core >= 60 && core < 70) {
alert(‘及格’);
} else {
alert(‘再来一次’);
}
}
多分支: switch
switch: 适用于条件和结果比较单一的情况
switch(条件){
case 结果1:
条件符合结果1的时候执行的代码
break;
case 结果2:
条件符合结果2的时候执行的代码
break;
case 结果3:
条件符合结果3的时候执行的代码
break;
case 结果4:
条件符合结果4的时候执行的代码
break;
default:
以上结果都不符合的时候 执行的代码;
break;
}
break: 防止穿透
如果不加break, 当匹配到一个结果之后,后续的结果都不在比较,直接执行其中的所有代码
// 判断按钮 + - * /
var str = ‘+’;
switch(str){
case ‘+’: console.log(10 + 20); break;
case ‘-’: console.log(10 - 20); break;
case ‘*’: console.log(10 * 20); break;
case ‘/’: console.log(10 / 20); break;
default: alert(‘你太为难我了,换一个吧’); break;
}
循环语句
循环: 重复执行的操作
\1. 重复代码
\2. 只有数字 下标 改变
\3. 页面元素的渲染和操作
for
for(表达式一; 表达式二; 表达式三){
循环体;
}
for(初始化变量; 循环结束条件; 变量更新){
重复执行的代码块
}
执行时机: for会在页面开始的一瞬间就执行完成
循环的执行过程, 需要使用断点调试
执行过程:
1. 初始化变量: var i = 1;
2. 循环条件: i <= 5
3. 循环体: log(i);
4. 变量更新: i++
2342342342
循环必须有一个可用的结束条件 否则就会形成死循环
// 从1开始输出 输出1-5每一个数字
for(var i = 1; i <= 5; i++){
console.log(i);
}
渲染页面
很多数据需要频繁更换\banner图、数据 前端不会把数据写死
使用for循环将后台返回的数据渲染到页面中
后台返回的数据的格式多为: 数组、对象
var 变量 = [数据1, 数据2, 数据3, …];
步骤:
\1. 写一个静态页面
\2. 重复子节点注释掉
\3. 实现js渲染页面
3.1 获取父元素 ul
3.2 将每一个数据渲染到ul中
3.3 给父元素添加子节点
// 数据
var data = [‘园区网络规划’, ‘web前端’, ‘python人工智能’, ‘Java’];
console.log(data[0]);
console.log(data[1]);
console.log(data[2]);
console.log(data[3]);
// 1. 获取父元素 ul
var ul = document.getElementsByTagName(‘ul’)[0];
console.log(ul);
// 2. 将每一个数据渲染到ul中
for(var i = 0; i < data.length; i++){
console.log(data[i]); // 获取到数据中的每一个
// 3. 给父元素添加子节点
ul.innerHTML += ‘
强调: 两个分号不能省
初始化变量;
for(;循环条件;){
循环体;
变量更新;
}
// 输出1-5
var i = 1;
for (; i <= 5;) {
console.log(i);
i++;
}
while
初始化变量;
while(循环条件){
循环体;
变量更新;
}
// 输出1-5
var j = 1;
while (j <= 5) {
console.log(j, ‘j’);
j++;
}
for和while的区别
for和while没有区别, 在使用时,根据场景的不同选择
明确循环次数, 用for 求1-100 给30给li加点击
没有明确循环次数, 用while 1000, 每天花当天钱数的一半 问什么时候到1元以下
do-while
初始化变量;
do{
循环体;
变量更新;
}whlie(循环条件);
// 1–5
var k = 1;
do {
console.log(k, ‘k’);
k++;
} while (k <= 5);
while和do-while的区别
whlie: 先判断后执行循环体
do-while: 先执行循环体后判断
break与continue
break: 防止穿透; 跳出循环, 结束整个循环;
continue: 跳出本轮循环, 下次循环继续;
// 酸汤水饺
// for(var i = 1; i <= 30; i++){
// console.log(‘当前吃了’+ i + ‘个’);
// }
// 吃到第五个水饺 发现了蟑螂
// for(var i = 1; i <= 30; i++){
// if(i == 5){
// break;
// }
// console.log(‘当前吃了’+ i + ‘个’);
// }
// 吃到第五个水饺 饺子掉了
for(var i = 1; i <= 30; i++){
if(i == 5){
continue;
}
console.log(‘当前吃了’+ i + ‘个’);
}
循环嵌套
for(外层循环初始化变量; 外层循环条件; 外层循环变量更新){
for(内层循环初始化变量; 内层循环条件; 内层循环变量更新){
循环体;
}
}
/*
外层循环控制行 内层循环控制列
* i = 1 j = 1
* * i = 2 j = 1 2
* * * i = 3 j = 1 2 3
* * * * i = 4 j = 1 2 3 4
* * * * * i = 5 j = 1 2 3 4 5
j与i的关系: j <= i
/
for(var i = 1; i <= 5; i++){
// 列
for(var j = 1; j <= i; j++){
document.write(’ ‘);
}
// 行
document.write(’
’);
}
for-in
json格式的数据: 对象 Object
以键值对的方式存在
var 变量 = {
属性名: 属性值,
属性名1: 属性值1
};
属性名可以加引号 也可以不加 建议使用字符串’’’
.后面不能加’’ .后面不能加变量
var obj = {
name: ‘迪丽热巴’,
‘age’: 18,
‘height’: 178
};
console.log(obj); // {name: “迪丽热巴”, age: 18, height: 178}
获取
获取对象的属性值:
变量.属性名
对象[变量]
console.log(obj.name);
console.log(obj.age);
// console.log(obj.‘age’); // .后面不能加’’ .后面不能加变量
var a = ‘age’;
console.log(obj.a); // 得不到正确结果
// 语法: 对象[变量]
console.log(obj[a]);
设置
对象.属性名 = 值;
obj.age = 28;
遍历
for(var 变量名 in 对象){
变量名—> 对象中的每一个属性名
对象[变量名] —> 对象中属性名对应的属性值
}
for-in 即可以遍历对象 也可以遍历 数组和集合
for(var k in obj){
console.log(k, obj[k]);
}
// for-in 即可以遍历对象 也可以遍历 数组和集合
var arr = [‘秦时明月’, ‘海贼王’, ‘死神来了’];
for(var i in arr){
console.log(i, arr[i]);
}
函数
函数: 将具有独立作用的代码块放到一起 在有需要的时候调用
作用: 提高代码的复用率 减少代码量
场景:
\1. 事件处理函数: 元素.事件 = function(){}
\2. 对象的方法: var obj = {
‘方法名’: function(){}
}
\3. 代码的封装复用
函数声明
函数: 由事件驱动的或者在有需要的时候被重复调用的代码块
\1. 函数声明:
1.1 声明函数: function 函数名() { // 代码块 }
1.2 调用函数: 函数名();
// 1.1 声明函数: function 函数名() { // 代码块 }
function map() {
for(var i = 0; i <= 100; i++){
console.log(i);
}
};
// 1.2 调用函数: 函数名();
map();
\2. 字面量声明/表达式声明:
2.1 声明函数: var 变量名 = function(){ // 代码块 }
2.2 调用函数: 变量名();
// 2.1 声明函数: var 变量名 = function(){ // 代码块 }
var map1 = function(){
for(var i = 0; i <= 100; i++){
console.log(i);
}
}
// 2.2 调用函数: 变量名();
map1();
注意:
\1. 函数只声明 不调用 不起作用
\2. 函数命名规范和变量的命名规范一致
\3. 函数声明调用可以在声明之前或者之后, 字面量声明方式只能在声明之后
// 1.1 声明函数: function 函数名() { // 代码块 }
// map();
function map() {
for(var i = 0; i <= 100; i++){
console.log(i);
}
};
// 2.1 声明函数: var 变量名 = function(){ // 代码块 }
// map1(); // map1 is not a function map1不是一个函数
var map1 = function(){
for(var i = 0; i <= 100; i++){
console.log(i);
}
}
参数
介绍
可变的数据都抽取参数
形参: 形式参数 用来接收实参传递过来的数据 function后面的()里
类似于变量 命名规范和变量一致
实参: 实际数据 传递给函数的形参的具体的数 函数调用的()里
arguments: 实参的集合 在每一个函数中都有
注意:
\1. 形参实参一一对应
\2. 多个参数: 用 , 隔开
function sum(start) {
var s = 0;
for (var i = start; i <= 100; i++) {
s += i;
}
console.log(s);
}
sum(1);
sum(50);
sum(70);
// 30 - 1000
// 50 - 800
// 600 - 900
/*
多个参数: 用 , 隔开
*/
function sum1(start, end) {
var s = 0;
for (var i = start; i <= end; i++) {
s += i;
}
console.log(s);
}
sum1(1, 100);
sum1(30, 1000);
sum1(50, 800);
/*
3 5 6 7 8
21 34
100 30 40 56 90
666 8888 9999 10001 111 121
当参数个数不确定的时候 干脆一个都不写 用arguments
arguments也是一个集合 有长度和下标
是实参的集合
*/
function sum2() {
console.log(arguments);
var s = 0;
// 获取arguments中每一个数据
for(var i = 0; i < arguments.length; i++){
console.log(arguments[i]);
s += arguments[i];
}
console.log(s);
};
sum2(3, 5, 6, 7, 8);
sum2(21, 34);
sum2(100, 30, 40, 56, 90);
arguments和形参关系:
是同一个, 都是用来存储实参的
两者互相影响
/*
arguments和形参关系:
是同一个, 都是用来存储实参的
两者互相影响
*/
function fn(a, b) {
console.log(a, b); // a = 10 b = 20
console.log(arguments); // [10, 20]
a = 10000;
console.log(arguments); // [10000, 20]
arguments[1] = 666;
console.log(a, b); // 10000 666
};
fn(10, 20);
参数问题
当形参和实参个数不相等的时候:
当形参个数大于实参个数 多余的形参是undefined
当实参个数大于形参个数 多余的实参不能通过形参获取 通过arguments获取
function fn(a, b, c) {
console.log(a, b, c);
};
fn(1, 2, 3);
fn(20, 30); // a=20 b=30 c=undefined
fn(20, 30, 40, 50, 60); // a=20 b=30 c=40
函数名重复: 后面的覆盖前面的
function fn1() {
console.log(2);
}
function fn1() {
console.log(20 + 30);
}
fn1(); // 50
参数的数据类型
number string null undefined boolean
object array function
都可以作为实参进行传递 一般不使用null undefined
function fnT(a) {
console.log(a);
};
fnT(30);
fnT(‘abcd’);
fnT(true);
fnT(null);
fnT(undefined);
var obj = {
name: ‘张三丰’,
age: 88
};
fnT(obj);
var arr = [2, 3, 4, 5];
fnT(arr);
function sum() {
console.log(10 + 20);
}
fnT(sum);
作用域
域: 区域 范围 空间
作用: 读、写
读—获取
写—设置
作用域: 变量和函数可以起作用的范围
es5中作用域通过function进行划分的
全局作用域: script标签下(function的{}外面)
在全局作用域下用var\function 声明的变量和函数 叫做全局变量\全局函数
作用于整个js 在整个js中都可以进行读写
局部作用域: function的{}中
在局部作用域下用var/function声明的变量和函数 叫做局部变量\局部函数
作用于当前的局部作用域 但凡出了{} 就会被销毁
// 外面—>全局作用域
var a = 10;
function fn() {
// 函数里面—>局部作用域
console.log(a);
var b = 30;
console.log(b);
}
fn();
作用域链
作用域链: 是js的一中查找机制, 先找自身作用域是否有值, 如果有就直接使用, 如果没有, 向上一级作用域去查找, 找到全局作用域, 如果还没有, 就报错: is not defined
决定了变量和函数向上一级作用域查找的过程
// s: 全局变量
var s = 10;
function sum() {
// 局部作用域
var s = 30;
// sum的局部函数
function fun() {
console.log(s); // 30
}
fun();
}
sum();
预解析\变量提升
js代码在执行的时候 至少分成2步:
预解析: 找var、function, 将var声明的变量, 声明提到最前, 找function声明的函数, 将整个函数存储在内存中
逐行解析: 从上到下执行
console.log(a); // undefined
var a = 20;
/*
解析过程:
var a;
cobsole.log(a); // undefined
a = 20;
*/
fn();
function fn() {
console.log(10+20);
};
/*
解析过程:
function fn() {
console.log(10+20);
};
fn();
*/
局部作用域解析:
当函数被调用的时候, 就会行程一个新的局部作用域, 解析过程遵循预解析
function a() {
console.log(a);
var a = 20;
console.log(a);
}
a();
/*
局部作用域解析过程:
64: var a;
63: log(a); undefined
64: a = 20;
65: log(a); 20
*/
带有参数的函数: 被调用的时候, 形参会在第一时间被赋值
function fn(a) {
console.log(a);
a = 30;
console.log(a);
}
fn(15);
/*
预解析: 形参的声明: var a;
逐行解析:
形参的赋值: a = 15
81: log(a); 15
82: a = 30;
83: log(a); 30
*/
函数返回值
函数就像一个小黑屋 将局部变量和函数囚禁在其中 在屋子外面得不到这个数据
每个函数被调用以后都有返回值, 默认返回值是undefined
接收返回值: var 变量 = 函数();
用 return 设置返回值
语法: return 要返回的值;
可以将函数的局部变量或者局部函数返回到函数外面
return:
\1. 设置返回值, 一次只能返回一个值;
如果返回多个数据 可以使用数组或者对象(推荐)
\2. 结束代码
function sum() {
var a = 20 + 30;
console.log(a);
}
var f = sum();
console.log(f); // undefined
function sum1() {
var b = 30 + 40;
return b;
}
var f1 = sum1();
console.log(f1);
// 1. 设置返回值, 一次只能返回一个值;
// 如果返回多个数据 可以使用数组或者对象(推荐)
function sum2() {
var a = 30;
var b = 40;
// return a,b;
return {
‘a’: a,
‘b’: b
};
}
var f2 = sum2();
console.log(f2);
// 2. 结束代码
function sum3() {
var a = 20;
return a;
var b = 30;
console.log(b);
}
sum3();
函数封装
\1. 实现单个效果 6!
\2. 新建一个空函数
\3. 重复代码放进去
\4. 调用函数 确定可以执行
\5. 抽参: 将不确定的数据变成形参
\6. 传参: 抽出来谁就把谁传进去
\7. 设置返回值并接收返回值
function getMax(data) {
var max = data[0];
// console.log(max);
// 每一个
for (var i = 0; i < data.length; i++) {
// 每一项和最大值进行比较
// console.log(data[i]);
if (data[i] > max) {
max = data[i];
}
}
// console.log(max);
return max;
}
var m = getMax(arr);
console.log(m);
var m1 = getMax(arr1);
console.log(m1);
var m2 = getMax(arr2);
console.log(m2);
函数的返回值
函数的返回值的数据类型可以是一切数据类型
function gr() {
function inner() {
console.log(123456);
}
return inner;
return [40, 30];
return {
a: 30,
b: 40
};
return undefined;
return null;
return true;
return 'abc';
return 30;
}
var a = gr();
console.log(a); // a=function inner(){}
// a();
页面重复效果实现
\1. 获取到父元素(结构一致的父元素) 可以复制粘贴的部分最大的层级 li
\2. 实现一个父元素中的效果
\3. 封装效果
\4. 循环实现每一个父元素的效果
注意: 一般不单独抽取下标作为参数 将整个元素作为形参抽取出来
获取元素样式
基础语法
标准(ie9及以上): getComputedStyle(元素).属性名
ie(ie8及以下): 元素.currentStyle.属性名
// 获取元素
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
var w = getComputedStyle(div).width;
console.log(w);
var c = getComputedStyle(div).color;
console.log©;
/*
getComputedStyle在ie下会报错
*/
console.log(div.currentStyle); // undefined
// console.log(div.currentStyle.width);
// getComputedStyle是一个函数 在ie下不存在的
// 所有的全局的函数和变量都属于 window
console.log(window);
console.log(window.getComputedStyle); // 标准: 函数 ie: undefined
console.log(div.currentStyle); // 标准: undefined ie: 对象
兼容:
当一个是undefined一个不是的时候 用方法/属性是否存在来做判断
if(window.getComputedStyle){
// 标准
var w = getComputedStyle(div).width;
console.log(w);
} else {
// ie
var w = div.currentStyle.width;
console.log(w);
}
封装
js中.相当于白勺的 后面全都是字符串 如果要使用变量 用[变量]
如果封装的函数里面有数据要在函数外面使用的时候 要设置返回值
// 获取元素样式
function getStyle(ele, attr) {
// ele: 元素
// attr: 属性
if (window.getComputedStyle) {
var w = getComputedStyle(ele)[attr];
} else {
var w = ele.currentStyle[attr];
}
// console.log(w);
return w;
}
var c = getStyle(div, ‘background’);
console.log©;
var w = getStyle(div, ‘width’);
console.log(w);
使用
js库: 将封装好的函数 放到一个js文件中 在后续有需要的时候 直接引入js库 调用函数
每个函数 必须要: 函数的作用 参数说明
qwert
this 概念 this: 指代词 存在于页面的任何位置不同的位置this具有不同的含义
指向:
\1. 全局: window
\2. 事件处理函数: 触发源 点谁就是谁
\3. 普通函数: window
\4. 对象的方法: 对象
console.log(window);
var div = document.getElementsByTagName(‘div’)[0];
div.onclick = function () {
console.log(this);
};
function sum() {
console.log(this);
}
sum();
var obj = {
name: ‘王一博’,
‘tip’: function () {
console.log(this);
}
}
obj.tip();
this使用场景
for循环嵌套的事件中, 获取到当前元素, 通过this来获取
/ 获取元素
var lis = document.getElementsByTagName(‘li’);
console.log(lis);
// 每个
for(var i = 0; i < lis.length; i++){
console.log(lis[i]);
// 添加事件
lis[i].onclick = function () {
// 当前li的内容
// 获取到当前li
console.log(i); //
console.log(lis[i]); // undefined
console.log(this);
console.log(this.innerHTML);
};
}
排他思想:
除了自己 其他都默认值的情况
先将所有的都回归默认值
再给当前这一个单独设置
// 1. 获取元素
var lis = document.getElementsByTagName(‘li’);
console.log(lis);
// 2. 每一个
for(var i = 0; i < lis.length; i++){
// 3. 添加事件
lis[i].onclick = function () {
// 4. 让所有li的内容隐藏
for(var j = 0; j < lis.length; j++){
lis[j].style.color = ‘#fff’;
}
// 5. 让当前li的内容显示
// 获取当前li
console.log(this);
this.style.color = '#000';
};
}
自定义属性
概念
属性: 写在起始标签上的 除了标签名以外的都是属性
固有属性: 规定好作用的属性 id class title
自定义属性: 由开发人员自己规定的属性名和属性值的属性 ttt=“abc”
获取属性: 元素.属性
设置属性: 元素.属性 = 值;
直接写在标签上的自定义属性 获取不到 得到的是undefined
通过js设置的自定义属性 在标签上看不到的 但是可以正常的获取和设置
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
// 获取属性
// 直接写在标签上的自定义属性 获取不到 得到的是undefined
var t = div.ttt;
console.log(t);
// 设置
// 通过js设置的自定义属性 在标签上看不到的 但是可以正常的获取和设置
div.abc = 123;
console.log(div.abc); // 123
使用
使用场景: 当多个元素 每个都需要有2个及以上状态的时候 每个元素都需要自己的开关的时候 使用自定义属性来标识
// 1. 获取元素
var divs = document.getElementsByTagName(‘div’);
console.log(divs);
// 每个div都要有一个假设的状态
// 使用自定义属性存储
// divs[0].tag = 1; // 1–40 2–100
// divs[1].tag = 1; // 1–40 2–100
// divs[2].tag = 1; // 1–40 2–100
// divs[3].tag = 1; // 1–40 2–100
// divs[4].tag = 1; // 1–40 2–100
// for(var i = 0; i < divs.length; i++){
// divs[i].tag = 1;
// }
// 每个div做判断的时候 用自己的tag判断
for(var i = 0; i < divs.length; i++){
// 设置自定义属性
divs[i].tag = 1;
// 点击
divs[i].onclick = function () {
// 用自己的tag判断 先获取自己
console.log(this, this.tag);
if(this.tag == 1){
this.style.height = ‘100px’;
this.tag = 2;
} else {
this.style.height = ‘40px’;
this.tag = 1;
}
}
}
自定义索引
自定义索引: 自定义属性, 存储的值变成了下标
快速获取body: document.body
var arr = [‘pink’, ‘red’, ‘skyblue’, ‘green’];
// [button, button, button, button]
var btns = document.getElementsByTagName(‘button’);
console.log(btns);
// 数据和按钮的关系: 一一对应 下标一致
// 点击每一个按钮 切换背景色 换的是 按钮对应的数组中的颜色
// 要想切换背景色 必须先得到按钮的下标
// 自定义索引: 自定义属性, 存储的值变成了下标
// btns[0].tag = 0;
// btns[1].tag = 1;
// btns[2].tag = 2;
// btns[3].tag = 3;
// 每一个
for(var i = 0; i < btns.length; i++){
// 存储自定义属性
btns[i].tag = i;
// 添加事件
btns[i].onclick = function () {
// 切换背景色
// 先得到按钮的下标
console.log(i); // 得不到正确的下标
// 得到自定义索引 获取自定义属性tag
console.log(this.tag);
// 通过下标 得到数组arr中的值 数组[下标]
console.log(arr[this.tag]);
// 设置给body
// 快速获取body: document.body
document.body.style.background = arr[this.tag];
};
}
定时器
概念
定时器: 让代码每隔一段时间或等待一段时间后再执行的代码就叫做定时器
延迟定时器
延迟定时器: 让代码等待一会之后 在执行
只执行一次
语法: setTimeout(函数, 时间);
时间单位: 毫秒 1s = 1000ms
场景: 一次性广告 关不掉广告
setTimeout(function () {
console.log(‘等待’);
}, 3000);
间隔定时器
间隔定时器: 让代码每隔一段时间 就执行一次
不间断的执行
语法: setInterval(函数, 时间)
时间单位: 毫秒 1s = 1000ms
场景: 计时器 倒计时 轮播图 时钟 动态效果
setInterval(function () {
console.log(1);
}, 1000);
function a() {
console.log(‘输出’);
}
// 每隔1s 执行a
setInterval(a, 1000);
清除定时器
定时器一旦开启 不会自动清除, 当不在需要定时器, 需要进行手动清除
定时器开启的时候, 会返回一个数字, 这个数字就是唯一标识
定时器一旦清除 再也找不到
var 变量 = setTimeout/setInterval(函数, 时间);
延迟定时器: 只执行一次
清除: clearTimeout(唯一标识timerId);
间隔定时器: 一直执行
清除: clearInterval(timerId);
var n = 5;
var timerId = setInterval(function () {
n–;
console.log(n);
// 当n变成0之后 清除定时器
if(n == 0){
clearInterval(timerId);
}
}, 1000);
console.log(timerId, ‘id’);
注意
唯一标识声明在全局
定时器的封装:
当定时器的函数执行的代码一样的时候 而是将定时器的第一个参数的函数 直接抽取封装
// 每隔
var t = null;
t = setInterval(auto, 1000);
console.log(t, ‘t’);
function auto() {
// 切换到下一张 1–>2–>3–>4—>5–>1
n++;
console.log(n);
// 判断是否到最后
if (n == 6) n = 1;
// 改变图片地址
img.src = './image/' + n + '.jpg';
}
对象
概念和分类
对象: 一切皆对象 js中所有的内容都可以看做一个对象
本地/原生对象: Number String Boolean Object Array Function Date RegExp Error
(三基础三复杂三其他)
内置对象: Global Math
宿主对象: DOM BOM
全局对象: window
Math
console.log(Math);
console.log(Math.PI); // π
console.log(Math.ceil(4.000001)); // 当小数点后有任意一个数 向上进一
console.log(Math.floor(3.999999)); // 向下取整 舍掉小数
console.log(Math.round(4.49999)); // 四舍五入
console.log(Math.round(4.5000001)); // 四舍五入
console.log(Math.pow(2, 3)); // 2的3次方 pow 幂次方
console.log(Math.sqrt(9)); // 开根号
console.log(Math.abs(-10)); // 10
/*
Math.random() : 求0-1之间的随机数
Math.random() * 数 : 求 0-数 之间的随机数
Math.random() * (y-x) + x: 求 x-y 之间的随机数 y > x
*/
console.log(Math.random());
console.log(Math.random() * 10);
// 30-40随机数
console.log(Math.random() * (40 - 30) + 30);
console.log(Math.max(32,43,5765,7723,54,12)); // 求最大值
console.log(Math.min(32,43,5765,7723,54,12)); // 求最小值
时间
创建时间
创建当前时间: var 变量名 = new Date();
当前这一行执行到的时候的一瞬间的时间
var date = new Date();
console.log(date);
/*
Tue Aug 17 2021 10:39:21 GMT+0800 (中国标准时间)
星期 八月 日 年 时:分:秒 时区
*/
特殊格式的时间
console.log(date.toLocaleDateString()); // 2021/8/17
console.log(date.toLocaleTimeString()); // 上午10:43:17
创建其他时间(过去、未来)
var 变量 = new Date(数值, 数值, 数值, 数值, 数值, 数值);
**月: 0-11表示1-12月 **
var d1 = new Date(1997, 0, 1, 21, 21, 21);
console.log(d1);
var 变量 = new Date(‘字符串’); 不允许使用中文字符
var d2 = new Date(‘2021/8/20 21:21:21’);
var d2 = new Date(‘2021 8 20 20:21:21’);
var d2 = new Date(‘2021&8&20 19:21:21’);
var d2 = new Date(‘2021-8-20 18:21:21’);
// var d2 = new Date(‘2021_8_20 17:21:21’); // 中文字符不能用
console.log(d2);
获取单个时间
// 创建时间
var d = new Date();
console.log(d);
// 年
console.log(d.getFullYear()); // 2021
// 月
console.log(d.getMonth()); // 0-11表示1-12月 7
// 日
console.log(d.getDate()); // 17
// 星期: 0-6表示周日-周六
console.log(d.getDay()); // 2
// 常见的星期处理
var week = [‘周日’, ‘周一’, ‘周二’, ‘周三’, ‘周四’, ‘周五’, ‘周六’];
var w = d.getDay(); // 下标
console.log(week[w]);
// 时
console.log(d.getHours()); // 24小时制 10
// 分
console.log(d.getMinutes()); // 分钟 56
// 秒
console.log(d.getSeconds()); // 11
// 毫秒/时间戳
console.log(d.getTime()); // 从1970-1-1到现在的毫秒数 1629169075807
moment
百度: momentjs
http://momentjs.cn/
保存js文件:
moment.js: 未压缩 学习
moment.min.js: 压缩 工作
使用
String
创建方式
\1. 字面量创建: 是一个包装对象, 不是一个真正的字符串对象
// 1. 字面量创建: 是一个包装对象, 不是一个真正的字符串对象
var str = ‘abc123’;
console.log(str, typeof str);
\2. 关键字创建
// 2. 关键字创建
var str1 = new String(‘abcsdsew1234’);
console.log(str1, typeof str1); // object
\3. 字符串有长度有下标
// 3. 字符串有长度有下标
// 长度: 字符串.length
console.log(str1.length);
// 下标
console.log(str1[3]);
\4. 字符串的比较规则: 从左往右比较每一个字符的ASCII码
// 4. 字符串的比较规则: 从左往右比较每一个字符的ASCII码
// 0–48 9–57 A–65 Z–90 a–97 z–122
console.log(‘2’ > ‘10000’); // true 50 > 49
查找
charAt
/*
1. 找到指定下标字符: 字符串.charAt(下标)
/
var str = ‘123456789’;
console.log(str.charAt(5)); // 6
charCodeAt
/
2. 找到指定下标的字符的ASCII值: 字符串.charCodeAt(下标);
/
console.log(str.charCodeAt(5)); // 54
indexOf
/
3. 字符在字符串中出现的位置:
字符串.indexOf(字符a, [起始下标]);
起始下标: 可选, 默认从0开始
找字符串中字符a出现的位置,如果找到就返回下标,如果找不到就返回-1
/
var str = ‘ehdgfewyetryuiodfghjsdrty’;
// g
console.log(str.indexOf(‘g’)); // 3
console.log(str.indexOf(‘g’, 4)); // 17
console.log(str.indexOf(‘g’, 18)); // -1
lastIndexOf
/
4. 字符在字符串中出现的位置:
字符串.lastIndexOf(字符a, [起始下标]);
起始下标: 可选, 默认从最后一位开始
找字符串中字符a出现的位置,如果找到就返回下标,如果找不到就返回-1
*/
console.log(str.lastIndexOf(‘g’)); // 17
console.log(str.lastIndexOf(‘g’, 16)); // 3
console.log(str.lastIndexOf(‘g’, 2)); // -1
截取
substring
语法: 字符串.substring(起始下标, 结束下标);
起始下标/结束下标: 可选 可写可不写
返回: 截取出来的字符
不传参: 返回整个字符串
传一个参数: 表示从当前下标位置开始截取到整个字符串的末尾
传两个参数:
\1. 起始下标 < 结束下标: 表示从起始下标位置开始 截取到结束下标位置为止 包含起始下标的字符 不包含结束下标的字符
\2. 起始下标 > 结束下标: 互换位置 参考上述规则
\3. 为负数: 将负数转成0 参考上述规则
var str = ‘abcdefg’;
console.log(str.substring());
console.log(str.substring(2)); // cdefg
console.log(str.substring(2, 4)); // cd
console.log(str.substring(4, 2)); // cd
console.log(str.substring(4, -2)); // 4, 0 0–4 abcd
slice
语法: 字符串.slice(起始下标, 结束下标);
起始下标/结束下标: 可选 可写可不写
返回: 截取出来的字符
不传参: 返回整个字符串
传一个参数: 表示从当前下标位置开始截取到整个字符串的末尾
传两个参数:
\1. 起始下标 < 结束下标: 表示从起始下标位置开始 截取到结束下标位置为止 包含起始下标的字符 不包含结束下标的字符
\2. 起始下标 > 结束下标: 返回空字符
\3. 结束下标为负数: 表示从右往左有几位不要
var str = ‘abcdefg’;
console.log(str.slice()); // abcdefg
console.log(str.slice(2)); // cdefg
console.log(str.slice(2, 4)); // cd
console.log(str.slice(4, 2)); // 空字符
console.log(str.slice(0, -2)); // abcde
substr
语法: 字符串.substr(起始下标, 长度);
起始下标/长度: 可选 可写可不写
返回: 截取出来的字符
不传参: 返回整个字符串
传一个参数: 表示从当前下标位置开始截取到整个字符串的末尾
传2个参数: 从起始下标开始截取长度为第二个数的字符
var str = ‘abcdefg’;
console.log(str.substr()); // abcdefg
console.log(str.substr(2)); // cdefg
console.log(str.substr(2, 4)); // cdef
其他
split
Split: 分割字符串 返回数组
语法: 字符串.split(‘分割符’);
分割符可以是一切字符 标签 字符 可传可不传
不传: 默认整个字符串为数组的一项
var str = ‘abcabcabcabc’;
console.log(str.split());
console.log(str.split(’’)); // 把字符串的每一个字符都变成数组的一项
console.log(str.split(‘ab’)); // ["", “c”, “c”, “c”, “c”]
replace
replace: 替换字符串
语法: 字符串.replace(‘被替换的字符’/正则, ‘新字符’/函数);
一次只能替换一个
var str = ‘abcabcabc’;
console.log(str.replace(‘abc’, ‘***’));
toUpperCase/toLowerCase
转大写: 字符串.toUpperCase();
转小写: 字符串.toLowerCase();
var str = ‘DFyhuhiuGUYG’;
console.log(str.toUpperCase());
console.log(str.toLowerCase());
// 忽略大小写 等号左右两边都转成大写 或者 都转成小写
var s1 = ‘abcdEfG’;
var s2 = ‘AbcdEFG’;
console.log(s1.toUpperCase() == s2.toUpperCase());
trim
trim: 去除左右空格
字符串.trim();
var str = ’ you are a happy child ';
console.log(’(’ + str + ‘)’);
console.log(’(’ + str.trim() + ‘)’);
数组
概念
数组: 用来存储不定数量不定类型的数据的容器
有长度有下标
创建数组
\1. 字面量创建:var 变量 = [值, 值, …];
\2. new关键字创建:
var 变量 = new Array(…data);
参数只有一个并且是数字: 表示当前数组的长度
var arr = [1, 2, 3, 4, 5];
console.log(arr);
/*
2. new关键字创建:
var 变量 = new Array(…data);
参数只有一个并且是数字: 表示当前数组的长度
*/
var arr1 = new Array(1,2,3,4);
console.log(arr1);
var arr2 = new Array(‘abc’);
console.log(arr2);
var arr3 = new Array(4);
console.log(arr3); // [empty × 4]
length
长度: 可以获取可以设置
获取: 数组.length
设置: 数组.length = 值;
var arr = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’];
console.log(arr.length);
arr.length = 10;
console.log(arr.length, arr);
arr.length = 3;
console.log(arr);
下标
下标: 索引, 标志每个数据的位置
通过下标取值: 数组[下标]
设置值: 数组[下标] = 值;
var arr = [1,2,3,4,5,6,7,8];
console.log(arr[5]);
arr[10] = 11;
console.log(arr);
数据存储
栈: 基础数据类型的声明和数据 复杂数据类型的声明和地址
堆: 复杂数据类型的数据
基础数据类型: 数据相对单一 数据量相对较小 声明和数据同时存储在栈中
复杂数据类型: 数据多样化 数据量相对较大 声明存储在栈 数据存储在堆
var arr = [1,2,3,4];
console.log(arr);
arr[5] = 1000;
console.log(arr);
深浅拷贝
浅拷贝
浅拷贝: 地址的赋值 出现一改全改的问题
var arr = [1, 2, 3, 4];
var brr = arr;
console.log(arr, brr);
arr[4] = 1000;
console.log(arr);
console.log(brr);
深拷贝
深拷贝: 重新划分一块内存 将原来的数据在单独存储到新的内存中
var crr = [5, 6, 7, 8];
var drr = [];
// 将crr的每一个数据对应的存储到drr中
// crr的每个数据的下标和drr的下标一致
// 每一个
for(var i = 0; i < crr.length; i++){
drr[i] = crr[i]
}
console.log(crr, drr);
crr[4] = 1000;
console.log(crr, drr);
栈方法
push: 在数组的末尾添加一项或者多项, 返回添加后的数组的长度
数组.push(…data);
pop: 在数组的末尾删除一项, 返回被删除的项
数组.pop();
unshift: 在数组的开头添加一项活着的多项, 返回添加后数组的长度
数组.unshift(…data);
shift: 在数组的开头删除一项, 返回被删除的项
数组.shift();
var a = arr.push(3,4,5);
console.log(arr, a);
var b = arr.pop();
console.log(arr, b);
var c = arr.unshift(‘a’, ‘b’);
console.log(arr, c);
var d = arr.shift();
console.log(arr, d);
splice
splice: 万能的splice 增删改
语法: 数组.splice(起始下标, 删除的个数, …data)
…data: 多个添加进来的数据 可写可不写
返回值: 被删除的项组成的新数组
删除: 数组.splice(起始下标, 删除的个数)
添加: 数组.splice(起始下标, 0, …data)
替换: 删几个加几个 数组.splice(起始下标, 删除个数, …data)
var arr = [‘貂蝉’, ‘吕布’, ‘小乔’, ‘周瑜’, ‘大乔’, ‘孙策’];
var brr = arr.splice(3, 1);
console.log(arr, brr);
// 添加
arr.splice(3, 0, ‘鲁班’, ‘王昭君’, ‘恺’, ‘程咬金’, ‘蔡文姬’);
console.log(arr);
// 替换
var crr = arr.splice(2, 1, ‘后羿’);
console.log(arr, crr);
查找
indexOf: 数组.indexOf(项, 起始下标)
lastIndexOf: 数组.lastIndexOf(项, 起始下标)
找到了就返回下标 找不到就返回-1
查找的项和数组中的项必须全等才能找到
var arr = [1, 2, 3, ‘2’, ‘3’];
console.log(arr.indexOf(‘1’));
concat
concat: 多个值拼接到数组中, 返回拼接后的 新数组 数组.concat(…data);
var arr = [1, 2, 3];
var brr = [5, 6, 7];
var ab = arr.concat(4, brr);
console.log(arr, brr);
console.log(ab);
slice
slice: 截取指定下标的数组中的项 返回组成的 新数组 数组.slice(起始下标, 结束下标); 不传参: 整个数组 传1个参数: 从起始下标开始截取到数组的结尾 传2个参数: 起始 < 结束: 从起始下标开始截取到结束下标位置的项 包含起始下标 不包含结束下标 结束 < 起始: 返回空数组 结束下标为负数: 后面有几个不要
var arr = [1, 2, 3, 4, 5];
console.log(arr.slice()); // [1, 2, 3, 4, 5]
console.log(arr.slice(3)); // [4, 5]
console.log(arr.slice(2, 5)); // [3, 4, 5]
console.log(arr.slice(5, 2)); // []
console.log(arr.slice(1, -2)); // [2, 3]
reverse
翻转: reverse 数组.reverse();
var arr = [4, 5, 6, 7, 8];
arr.reverse();
console.log(arr);
join
join: 将数组的每一个项用连接符连接起来 返回 字符串 数组.join(‘连接符’); 连接符可以是一切字符 可传可不传 默认以,链接
var arr = [1, 2, 3, 4];
console.log(arr.join()); // 1,2,3,4
console.log(arr.join(’’)); // 1234
var a = arr.join(‘123’);
console.log(a);
document.body.innerHTML = a;
实现翻转字符串
var str = ‘abcdefg’; // gfedcba
// 5.1 将字符串转数组
// 5.2 使用数组的翻转方法
// 5.3 数组在拼接成字符串
var arr = str.split(’’).reverse().join(’’);
console.log(arr);
排序算法
选择
原理: 那数组的每一项和当前项后面的每一项做对比 如果当前项比后面项大,互换位置
var arr = [33, 58, 66, 77, 88, 22, 12, 6, 8];
// 每一项
for(var i = 0; i < arr.length; i++){
// 当前项后面的每一项
for(var j = i + 1; j < arr.length; j++){
// console.log(arr[i], arr[j]);
// 如果当前项比后面项大
if(arr[i] > arr[j]){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
冒泡
原理: 用相邻的两个数字做比较 如果前面的比后面的大 互换位置
var brr = [99, 1, 46, 37, 33, 22, 11, 5];
// 有多少个项 循环多少次
for(var i = 0; i < brr.length; i++){
for(var j = 0; j < brr.length - i; j++){
// j = 0 1
// j = 1 2
// j = 2 3
// console.log(brr[j], brr[j+1]);
// 如果前面的比后面的大
if(brr[j] > brr[j+1]){
// 互换位置
var temp = brr[j];
brr[j] = brr[j+1];
brr[j+1] = temp;
}
}
}
console.log(brr);
sort
数组.sort(函数);
函数可写可不写
默认按照从小到大的ASCII值排序
var arr = [9, 3, 4, 5, 2, 6, 4, 10, 40];
arr.sort();
console.log(arr);
// 函数: 有2个参数 表示相邻的两个数据
var arr = [9, 3, 4, 5, 2, 6, 4, 10, 40];
arr.sort(function (a, b) { // 形参一直存在 名字自定义
// console.log(a, b);
// 设置返回值
// return a-b; // 从小到大
return b-a; // 从大从小
});
console.log(arr);
中文排序
按照本地语言环境进行对比
中文排序: 字符串.localeCompare(字符串2)
返回值: -1 0 1
var s1 = ‘张三’;
var s2 = ‘李四’;
console.log(s1.localeCompare(s2));
console.log(s2.localeCompare(s1));
console.log(s2.localeCompare(s2));
迭代方法
迭代: 数据筛选过滤和处理
every: 对数组的每个项做一个判断,如果每个数据执行函数后返回结果都为true, 返回结果就是true, 如果有一个是false, 返回结果就是false
数组.every(函数);
用函数的返回值来做判断
有3个形参(项, 下标, 原数组)
some: 对数组的每个项做一个判断,如果每个数据执行函数后返回结果都为false, 返回结果就是false, 如果有一个是true, 返回结果就是true
数组.some(函数);
用函数的返回值来做判断
有3个形参(项, 下标, 原数组)
filter: 挑选 每个数据执行函数后 返回结果为 true的 数据, 组成新的数组 返回 返回一个新数组
数组.filter(函数);
用函数的返回值来做判断
有3个形参(项, 下标, 原数组)
map: 遍历数组 接收每个函数的返回值 组成新数组 返回
forEach: 遍历数组 纯粹遍历 没有任何返回值
var arr = [1, 2, 3, 4, 5, 6];
// 判断arr的每个数据是不是都大于0
var res = arr.every(function (a, b, c) {
console.log(a, b, c);
return a < 3;
return a > 0;
});
console.log(res);
var res1 = arr.some(function (val, ind, array) {
console.log(val, ind, array);
return val > 1;
});
console.log(res1);
var res2 = arr.filter(function (val, ind, array) {
console.log(val, ind, array);
// return val >= 3;
return val % 2 == 0;
});
console.log(res2);
var res3 = arr.map(function (v, i, a) {
console.log(v, i, a);
// return i;
// return a;
return 1;
});
console.log(res3);
var res4 = arr.forEach(function (v, i, a) {
console.log(v, i, a);
// arr[i] = 10;
return 1;
});
console.log(res4); // undefined
console.log(arr);
正则
概念
正则: RegExp, 用提前定义好的特殊字符组成的‘规则字符串’, 用来检索、替换文本
\1. 屏蔽敏感词
\2. 登录注册
创建
\1. new关键字创建
var 变量 = new RegExp(‘规则字符串’, ‘修饰符’);
var reg = new RegExp(‘web’, ‘ig’);
console.log(reg); // /web/gi
console.log(typeof reg); // object
\2. 字面量创建
var 变量 = /规则字符串/修饰符;
var reg1 = /web/ig;
console.log(reg1);
修饰符作用
i: ignore case 忽略大小写
g: global 全局(整个字符串)
检索方法
字符串
replace
replace: 字符串.replace(‘字符’/正则, '新字符/函数); 函数有形参: 匹配到的符合条件的字符 函数的返回值 就是替换的新字符
var str = ‘web123web456web789Web1WEB23’;
console.log(str.replace(‘web’, ‘**’));
var reg = /web/ig;
console.log(str.replace(reg, ‘*’));
// 在替换的字符长度不确定的时候 使用函数来做替换
var a = str.replace(reg, function (s) {
console.log(s);
return ‘abc’;
});
console.log(a);
split
split: 字符串.split(‘分割符’/正则);
var str = ‘web123web456web789Web1WEB23’;
var reg = /\d/; // 匹配数字0-9
var reg = /web/i;
console.log(str.split(reg));
search
search: 字符串.search(正则) 找到返回下标 找不到返回-1
var str = ‘web123web456web789Web1WEB23’;
var reg = /\d/;
var reg = /\s/; // 空格
console.log(str.search(reg));
match
match: 将符合正则的项组成新数组返回 一个: [“WEB”, index: 22, input: “web123web456web789Web1WEB23”, groups: undefined] 匹配的结果 下标 原字符串 多个: [“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “1”, “2”, “3”]
var str = ‘web123web456web789Web1WEB23’;
var reg = /WEB/;
console.log(str.match(reg));
var reg = /\d/g;
console.log(str.match(reg));
正则
惰性查找: 一次只匹配一个 下一次再找下一个
exec
exec: 返回匹配到的项 组成新数组返回
正则.exec(字符串);
不加g: 每次查找都从0开始
加g: 从上一次匹配到的结果的下一个字符开始查找
var str = ‘web123web456web789Web1WEB23’;
// var reg = /web/;
var reg = /web/g;
console.log(reg.lastIndex); // 下一正则开始查找的位置
console.log(reg.exec(str));
console.log(reg.lastIndex); // 下一正则开始查找的位置
console.log(reg.exec(str));
console.log(reg.lastIndex); // 下一正则开始查找的位置
console.log(reg.exec(str));
console.log(reg.lastIndex); // 下一正则开始查找的位置
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 下一正则开始查找的位置
console.log(reg.exec(str)); // 从0开始
test
test: 返回是否有符合正则的字符 有返回true 没有返回false 正则.test(字符串); 不加g: 每次查找都从0开始 加g: 从上一次匹配到的结果的下一个字符开始查找
var str = ‘web123web456web789Web1WEB23’;
// var reg = /web/;
var reg = /web/g;
console.log(reg.lastIndex); // 0
console.log(reg.test(str));
console.log(reg.lastIndex); // 3
console.log(reg.test(str));
元字符
.: 匹配除换行以外的任意字符;
var str =’\n123\n456’;
console.log(str);
var reg = /./;
console.log(reg.exec(str));
字符集: 不需要加任何引号、分隔
/*
2. 字符集: 不需要加任何引号、分隔
[]: 字符集, 表示匹配字符集中的任意一个字符
[^]: 非字符集, 表示匹配除字符集以外的任意一个字符
0-9 0-9之间的每一个数字
a-z a-z之间的每一个字母
A-Z A-Z之间的每一个字母
*/
var str = ‘,today is not bad day’;
var reg = /[today,is]/; // 匹配的字母有: t o d a y i s ,
console.log(reg.exec(str));
var reg = /[^to,day]/;
console.log(reg.exec(str)); // 空格 [" ", index: 6, input: “,today is not bad day”, groups: undefined]
var str = ‘9web123’;
var reg = /[0-9]/;
console.log(reg.exec(str));
数字
/*
3. 数字
\d: 数字0-9
\D: 除数字以外的任意字符
*/
var str = ‘today is 4’;
var reg = /\d/;
console.log(reg.exec(str)); // 4
var reg = /\D/;
console.log(reg.exec(str)); // t
数字、字母、_
/*
4. 数字、字母、_
\w: 表示匹配字母、数字、_任何一个
\W: 表示匹配除字母\数字_以外的任何一个
*/
var str = ‘1you are a beautiful girl’;
var reg = /\w/;
console.log(reg.exec(str));
var reg = /\W/;
console.log(reg.exec(str)); // 空格
空格
/*
5. 空格
\s: 匹配空格
\S: 匹配除空格外的任何一个
*/
var str = ’ How are you’;
var reg = /\s/;
console.log(reg.exec(str)); // 0
var reg = /\S/;
console.log(reg.exec(str)); // H
边界, 一个字母有2个边界
/*
6. 边界, 一个字母有2个边界
\b: 单词边界
\B: 非单词边界
*/
var str = ‘today is a finaly day’;
var reg = /\ba/; // 匹配a的左边是空格的a
console.log(reg.exec(str)); // 9
var reg = /\Ba\B/; // 匹配a的左边不是空格并且a的右边不是空格的a
console.log(reg.exec(str)); // 3
开头、结尾 整个字符串来做判断
/*
7. 开头、结尾 整个字符串来做判断
一个字符串只有一个开头(第一个字符) 一个结尾(最后一个)
^a: 以a为开头
a$: 以a为结尾
有明确长度、有长度范围 先写^$
*/
var str = ’ we are web0713’;
var reg = /^w/;
console.log(reg.exec(str));
var reg = /\d$/;
console.log(reg.exec(str));
量词
量词: 单位
a?
a? : 匹配是0个或者1个a
var str = ‘awebweb123’;
var reg = /b?/;
var reg = /a?/;
console.log(reg.exec(str));
a*
a* : 匹配是0个或者 连续 的多个a 尽可能多的去匹配
var str = ‘1234567a1234567’;
var str = ‘a1234567a1234567’;
var reg = /\d*/;
console.log(reg.exec(str));
a+
a+: 匹配 连续 的多个a 尽可能多的去匹配 至少匹配1位
var str = ‘aaa1234567a1234567’;
var reg = /\d+/;
console.log(reg.exec(str));
a{m,n}
{m,n} : 匹配至少m次,最多n次 尽可能多的去匹配 m,n中间不能加空格
{m,} : 匹配至少m次 逗号不能省略
{m} : 匹配 m 次
var str = ‘12345aa678901234’;
var reg = /\d{5,10}/;
console.log(reg.exec(str)); // 12345
var str = ‘12345678901234’;
var reg = /\d{3,}/;
console.log(reg.exec(str)); // 12345678901234
var reg = /\d{6}/;
console.log(reg.exec(str));
或和
|或
a|b : 或 匹配a或者b
var str = ‘web23webabc’;
var reg = /web1|web2/;
console.log(reg.exec(str));
()和
() : 分组
每个分组的匹配结果都会在结果中展示, 数组第2项以后的就是分组的匹配结果
分组结果: $1 $2
var reg = /web(1|2)(2|3)/;
console.log(reg.exec(str));
console.log(RegExp.$1);
console.log(RegExp.$2);
var str = ‘13322221111’;
// 将中间4位加密 1331111
var reg = /^(1[3-9]\d)(\d{4})(\d{4})$/;
console.log(reg.exec(str));
console.log(str.replace(reg, '$1$3’));
var str = ‘hello RegExp’; // RegExp hello
var reg = /(hello) (RegExp)/;
console.log(str.replace(reg, ‘$2 $1’));
// 验证某几种情况选一个
// https://www.baidu.com/
// com cn net edu
var reg = /^(http|https)/www.\w+.(com|cn|net|edu)$/;
// 转义: 将vscode规定好的特殊的符号转成常规字符 用
// .: 正则规定好的特殊的符号转成常规字符 用
var str = ‘https://www.baidu.com’;
console.log(reg.exec(str));
前瞻后顾
(?
(?:a) : 非获取匹配
不获取分组中的小结果
var str = ‘hello world’;
var reg = /(hello) (world)/;
console.log(reg.exec(str));
var str = ‘web1web2webawebb’;
// var reg = /web(1|2)/;
var reg = /web(?:1|2)/;
console.log(reg.exec(str));
(?=)
(?=a) : 正向肯定预判
var str = ‘123@345’;
var reg = /\d(?=@)/; // 匹配后面跟着@的数字
console.log(reg.exec(str));
(?!)
(?!a): 正向否定预判
var str = ‘123@345’;
var reg = /\d(?!@)/; // 匹配后面不跟着@的数字
console.log(reg.exec(str));
DOM
DOM: Document Object Model 文档对象模型
DOM: 在页面生成的时候会形成一个树状结构 这个树状结构就叫做DOM树 当做节点
DOM树由节点组成
获取元素
获取元素: 静态获取 获取元素这一行代码执行的时候 页面中有多少就获取到多少 后续添加的得不到的 ie8+
document/父元素.querySelector(‘css选择器’); 获取到符合选择器的第一个元素
document/父元素.querySelectorAll(‘css选择器’); 获取到复合选择器的所有元素 集合
var li = document.querySelector(‘li’);
console.log(li);
var lis = document.querySelectorAll(‘li’);
console.log(lis); // NodeList(5) [li, li, li, li, li]
var lis1 = document.getElementsByTagName(‘li’);
console.log(lis1); // HTMLCollection(5) [li, li, li, li, li]
var boxes = document.querySelectorAll(’.box’);
console.log(boxes);
var boxa = document.querySelectorAll(’.box.a’);
console.log(boxa);
var c2 = document.querySelectorAll(‘li:nth-child(2)’);
console.log(c2);
获取子节点
标准浏览器: 节点.children
ie: 节点.childNodes 在标准浏览器中会获取到换行节点
console.log(ul.childNodes);
console.log(ul.childNodes[0]);
节点属性
\1. 节点名称: 节点.nodeName text comment LI UL P
\2. 节点类型: 节点.nodeType 0-12 1–标签 2–属性 3–文本 8–注释 9–document
\3. 节点内容: 节点.nodeValue 只有文本节点才有
// 节点属性:
// 1. 节点名称: 节点.nodeName text comment LI UL P
console.log(ul.childNodes[0].nodeName);
console.log(ul.childNodes[1].nodeName);
console.log(ul.childNodes[2].nodeName);
// 2. 节点类型: 节点.nodeType 0-12 1–标签 2–属性 3–文本 8–注释 9–document
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);
console.log(ul.childNodes[2].nodeType);
// 3. 节点内容: 节点.nodeValue 只有文本节点才有
console.log(ul.childNodes[0].nodeValue);
console.log(ul.childNodes[1].nodeValue); // null
// 先获取标签节点的子节点(文本)再获取内容
// console.log(ul.childNodes[1].childNodes[0].nodeValue);
获取父节点
直接父节点: 当前子节点的上一级 节点.parentNode
定位父节点: 具有定位属性的父节点 没有定位属性的父元素 获取的就是body 节点.offsetParent
/*
获取父元素
先获取子元素
*/
var box = document.querySelector(’.box’);
console.log(box);
// 获取父节点:
// 直接父节点: 当前子节点的上一级 节点.parentNode
// 定位父节点: 具有定位属性的父节点 没有定位属性的父元素 获取的就是body 节点.offsetParent
console.log(box.parentNode);
console.log(box.offsetParent);
获取其他节点
获取首节点
首节点: 节点.firstElementChild 节点.firstChild
标准: 标签 换行
ie: undefined 标签
var ul = document.querySelector(‘ul’);
console.log(ul);
console.log(ul.firstElementChild, ul.firstChild);
兼容:
当一个是undefined 一个是有值 用||来连接 逻辑或短路 将有可能是undefined写在前面
console.log(ul.firstElementChild || ul.firstChild);
获取尾节点
获取尾节点:
节点.lastElementChild 节点.lastChild
标准: 标签 换行
ie: undefined 标签
兼容: 节点.lastElementChild || 节点.lastChild
console.log(ul.lastElementChild || ul.lastChild);
获取上一个兄弟
获取上一个兄弟节点:
节点.previouElementSibling 节点.previousSibling
标准: 标签 换行
ie: undefined 标签
兼容: 节点.previousElementSibling || 节点.previousSibling
var box = document.querySelector(’.box’);
console.log(box);
console.log(box.previousElementSibling || box.previousSibling);
获取下一个兄弟
获取下一个兄弟节点:
节点.nextElementSibling 节点.nextSibling
标准: 标签 换行
ie: undefined 标签
兼容: 节点.nextElementSibling || 节点.nextSibling
console.log(box.nextElementSibling || box.nextSibling);
删除节点
删除自身: 节点.remove(); ie8+
删除子节点: 节点.removeChild(子节点);
var ul = document.querySelector(‘ul’);
var box = document.querySelector(’.box’);
console.log(box, ul);
// ul.removeChild(box);
box.remove();
创建节点
创建标签节点
创建文本节点
将文本节点追加到标签节点中
将li追加到ul中
// 1. 创建标签节点
// var 变量 = document.createElement(‘标签名’);
var li = document.createElement(‘li’);
console.log(li);
// 2. 创建文本节点
// var 变量 = document.createTextNode(‘内容’);
var txt = document.createTextNode(‘12345’);
console.log(txt);
// 3. 将文本节点追加到标签节点中
// 父节点.appendChild(子节点)
li.appendChild(txt);
console.log(li);
// 2-3步简化: 标签.innerHTML = 值;
// 4. 将li追加到ul中
ul.appendChild(li);
追加节点
追加到父元素末尾: 父元素.appendChild(子);
// 先创建li标签
var li = document.createElement(‘li’);
// 设置内容
li.innerHTML = ‘123456’;
// 1. 追加到父元素末尾: 父元素.appendChild(子);
var ul = document.querySelector(‘ul’);
ul.appendChild(li);
插入到某个节点之前: 父元素.insertBefore(new, ref)
var li1 = document.createElement(‘li’);
li1.innerHTML = ‘新的003’;
// 获取box
var box = document.querySelector(’.box’);
ul.insertBefore(li1, box);
// 插入到第一个
var li2 = document.createElement(‘li’);
li2.innerHTML = ‘新的001’;
ul.insertBefore(li2, ul.children[0]);
替换节点
父元素.replaceChild(new, ref);
var li = document.createElement(‘li’);
li.innerHTML = ‘新的li’;
var ul = document.querySelector(‘ul’);
ul.replaceChild(li, box);
克隆节点
节点.cloneNode(boolean);
boolean : true–克隆节点的内容 false–不克隆节点内容(默认)
var cli = box.cloneNode();
var cli = box.cloneNode(false);
var cli = box.cloneNode(true);
console.log(cli);
ul.appendChild(cli);
操作属性
操作属性:
获取: var 变量 = 元素.属性名; var 变量 = 元素[属性名];
设置: 元素.属性名 = 值; 元素[属性名] = 值;
.相当于 的 后面只能跟 字符串
局限: 上面两种 只能操作固有属性 写在标签上了的自定义属性获取不到
通过上面两种设置的属性 在页面上 看不到 但是可以正常获取和设置
var box = document.querySelector(’.box’);
console.log(box);
console.log(box.id, box.tag); // abc undefined
box.a = 1;
console.log(box.a);
获取属性
获取属性: 节点.getAttribute(‘属性名’);
/*
1. 获取属性: 节点.getAttribute(‘属性名’);
*/
console.log(box.getAttribute(‘tag’));
console.log(box.getAttribute(‘id’));
设置属性
设置属性: 节点.setAttribute(‘属性名’, ‘属性值’);
class不需要用className 直接class
box.setAttribute(‘class’, ‘a b c’);
移除属性
移除属性: 节点.removeAttribute(‘属性名’);
box.id = ‘’;
box.removeAttribute(‘id’);
注意
写属性名就能起作用的属性 在js中的值就是布尔 true false
不能使用set
一般推荐设置的时候使用 . []
var btn = document.querySelector(‘button’);
var inps = document.querySelectorAll(‘input’);
console.log(btn, inps);
inps[1].checked = true;
inps[1].setAttribute(‘checked’, true);
快速获取表格元素
// 1. 获取table
var table = document.getElementsByTagName(‘table’)[0];
console.log(table);
// 2. 快速获取
console.log(table.tHead); // 头
console.log(table.tFoot); // 脚
console.log(table.tBodies); // 表格体的集合 [tbody]
console.log(table.tBodies[0]); // 第一个表格体
console.log(table.rows); // 表格的行的集合 [tHead, tr, tr, tr]
console.log(table.tBodies[0].rows); // 第一个表格体中所有的行
// 表格是由行组成 行是由单元格
// 单元格必须通过行获取
console.log(table.tBodies[0].rows[0].cells); // 表格体中的第一个行的所有的单元格
console.log(table.cells); // undefined
表单元素
快速获取表单元素: 语法: form.name值
获取form表单的值: form.name值.value
form表单事件:
\1. 提交 onsubmit
return true; 当前表单可以提交 默认
return false; 当前表单不提交
\2. 重置 onreset
return true; 当前表单可以重置 默认
return false; 当前表单不重置
var form = document.querySelector(‘form’);
form.onsubmit = function () {
console.log(1);
// return false;
// return true;
// 如果用户名是123 密码是123 禁止提交 否则 允许提交
if(form.user.value == ‘123’ && form.pass.value == ‘123’){
console.log(‘禁止提交’);
return false;
} else {
return true;
}
};
form.onreset = function () {
console.log(‘重置’);
// return true;
// return false;
};
form中的表单元素事件:
\1. 聚焦: onfocus: 当光标定位到输入框的时候 触发的事件
\2. 失焦: onblur: 当光标在输入框移出 触发的事件
\3. 表单失去焦点且内容改变事件: onchange
\4. 边输入边改变: oninput(标准) onpropertychange(ie)
form.user.onfocus = function () {
this.style.border = ‘10px solid red’;
};
form.user.onblur = function () {
this.style.border = ‘1px solid black’;
};
form.pass.onchange = function () {
this.style.background = ‘red’;
};
form.pass.oninput = form.onpropertychange = function () {
console.log(this.value);
};
form.user.oninput = function () {
console.log(this.value);
}
方法:
form表单: reset() submit()
表单中的元素: blur() focus() select();
// form.user.select();
form.pass.focus();
setTimeout(function () {
form.pass.blur();
}, 3000);
var divs = document.getElementsByTagName(‘div’);
divs[0].onclick = function () {
form.reset();
};
divs[1].onclick = function () {
form.submit();
};
BOM
BOM: Browser Object Model 浏览器对象模型
window 最大对象
所有全局中声明的变量和方法都属于window
document也是存在于window中
其他: location localstorage cookie document history 提示框 frames
对话框
\1. 警告框
\2. 带有确认取消按钮的对话框 true—确认 false–取消
\3. 带有输入框的对话框 确认–输入框的内容 取消–null
// 1. 警告框
// alert(‘是否同意此协议’);
// 2. 带有确认取消按钮的对话框 true—确认 false–取消
// var c = confirm(‘是否选择购买99999的套餐’);
// console.log©;
// 3. 带有输入框的对话框 确认–输入框的内容 取消–null
// var res = prompt(‘请输入要购买的金额’, ‘99’);
// console.log(res);
open与close
open
open(打开地址, 打开的方式, 特殊值);
打开的方式: _blank: 新的页面 _self: 自身
特殊值: 页面样式 打开方式必须是_blank 属性名=属性值,属性名=属性值
具有返回值: 将新页面的window对象返回回来
setTimeout(function () {
// 打开百度
// open(‘https://www.baidu.com’, ‘_blank’);
// open(‘https://www.baidu.com’, ‘_self’);
var w = open(‘https://www.baidu.com’, ‘_blank’, ‘width=100px, height=100px’);
console.log(w);
setTimeout(function () {
w.close();
}, 2000);
}, 3000);
close
close: window对象.close();
close写在页面结构html中 window不可省略
setTimeout(function () {
w.close();
}, 2000);
location
location既是BOM的对象 也是window下的一个对象
整个BOM中最有用的对象的之一 相关当前页面的网址相关信息
// http://www.ujiuye.com/zt/webqzgcs/
// http://xue.ujiuye.com/list/?title=web
console.log(location);
console.log(location.href); // 完整地址
console.log(location.protocol); // 协议 file http https
console.log(location.host); // 服务器名称+端口号 —> 映射地址
console.log(location.hostname); // 服务器名称
console.log(location.port); // 端口号
console.log(location.pathname); // 地址
console.log(location.hash); // 哈希值 散列 #+后面
console.log(location.search); // 搜索内容 ?a=1&b=1
// setTimeout(function () {
// location.reload(); // 刷新页面
// }, 3000)
// 跳转到其他
// location.href = ‘https://www.baidu.com’;
window.location.href = ‘https://www.baidu.com’;
history
history.back(); 回退到上一个页面
history.forward(); 前进到下一个页面
history.go(数字); 跳转到某个页面
正数: 前进到后面第几个页面
负数: 回退前面第几个页面
0: 刷新
01:
刷新
前进到03
前进到下一个页面
02:
history03
回退到01
03:
回退到01
事件
onload
// 1. 等待页面加载: 等页面结构及资源加载完成后 在执行function
// 当js写在页面结构之前
// 外链的js文件中
window.onload = function () {
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
};
onscroll
// 2. 页面滚动
window.onscroll = function () {
console.log(‘滚滚滚’);
};
onresize
// 3. 窗口大小发生改变
window.onresize = function () {
console.log(‘变变变’);
};
client
client: 可视宽高
clientWidth/clientHeight: 元素的可视宽/可视高 content+padding
clientLeft/clientTop: left/top的边框的宽度
var div = document.getElementsByTagName(‘div’)[0];
console.log(div);
console.log(div.clientWidth, div.clientHeight); // 200+20+40 300+10+30
console.log(div.clientTop, div.clientLeft); // 3 1
获取浏览器的可视宽高:
document.documentElement.clientHeight/clientWidth
console.log(document.documentElement.clientHeight, document.documentElement.clientWidth);
offset
offset: 占位宽高
offsetWidth/offsetHeight: 元素的占位宽/元素的占位高 content+padding+border
offsetLeft/offsetTop: 元素距离具有定位属性的父元素的偏移的距离, 如果没有定位父元素 距离body的偏移距离
left: 左 top: 上
console.log(div.offsetWidth, div.offsetHeight); // 200+20+40+1+5=266 300+10+30+3+2=345
console.log(div.offsetLeft, div.offsetTop); // 50 0 – 50 20
scroll
scroll: 滚动距离
scrollWidth/scrollHeight: 元素内容所占的实际的宽高
scrollLeft/scrollTop: 元素的滚动的距离
left: 水平 top: 垂直
console.log(div.scrollWidth, div.scrollHeight);
div.onscroll = function () {
console.log(div.scrollTop, div.scrollLeft);
};
页面的滚动距离:
document.documentElement.scrollLeft/scrollTop
window.onscroll = function () {
console.log(document.documentElement.scrollTop, document.documentElement.scrollLeft);
};
懒加载
\1. 布局 元素必须有宽高
\2. 将图片地址存储在img的自定义属性(_src)上
\3. 如果img进入页面 将自定义属性的地址赋值给 src 属性
offsetTop == scrollTop + clientHeight 刚刚好进入页面
offsetTop < scrollTop + clientHeight 图片进入页面且超出页面的过程
offsetTop <= scrollTop + clientHeight
auto();
// 当窗口大小发生改变的时候
window.onresize = window.onscroll = function () {
auto();
};
// 事件可以连等
function auto() {
// 5. 获取滚动距离
var t = document.documentElement.scrollTop;
var cw = document.documentElement.clientHeight;
// console.log(cw);
// console.log(t);
// 3. 判断每一张
for (var i = 0; i < imgs.length; i++) {
// 4. 获取每个img距离页面顶部的距离
// console.log(imgs[i].offsetTop);
if (imgs[i].offsetTop <= t + cw) {
// 6. 将img的_src的值赋值给src
// console.log(imgs[i].getAttribute(’_src’));
imgs[i].src = imgs[i].getAttribute(’_src’);
}
}
}
事件对象
事件对象: 当页面中触发事件的时候 浏览器会将当前相关事件的信息都存储在一个对象中, 就是事件对象
ie/chrome/高ff: window.event
低ff: 以事件处理函数的第一个形参
事件对象: 鼠标、触发源、页面、事件…
var div = document.querySelector(‘div’);
console.log(div);
div.onclick = function () {
console.log(window.event);
console.log(event.type); // 事件类型
console.log(event.target, event.srcElement); // 事件的触发源
console.log(event.target || event.srcElement); // 事件的触发源
console.log(event.clientX, event.clientY); // 鼠标相对于屏幕的可视区域的左上角的位置
console.log(event.pageX, event.pageY); // 鼠标相对于页面body左上角的距离
console.log(event.screenX,event.screenY); // 鼠标相对于电脑屏幕的左上角的距离
};
事件绑定
元素.事件 = function(){} 只能给同一个元素的同一个事件添加一个处理函数 如果添加多个后面的就会覆盖前面的
div.onclick = function () {
console.log(1);
}
div.onclick = function () {
console.log(5);
}
语法
ie: 元素.attachEvent(on+事件类型, 事件处理函数)
标准: 元素.addEventListener(事件类型, 事件处理函数, 是否捕获)
// ie: 对象不支持“addEventListener”属性或方法
// 标准: div.attachEvent is not a function div.attachEvent不是一个函数
console.log(div.addEventListener); // ie: undefined 标准: 函数
console.log(div.attachEvent); // ie: 函数 标准: undefined
// div.addEventListener(‘click’, function () {
// console.log(2);
// }, false);
// div.attachEvent(‘onclick’, function () {
// console.log(3);
// });
兼容
if (div.attachEvent) {
div.attachEvent(‘onclick’, function () {
console.log(3);
});
} else {
div.addEventListener(‘click’, function () {
console.log(2);
}, false);
}
封装
bind(div, ‘click’, a);
bind(div, ‘click’, b);
function bind(ele, type, fn) {
// ele: 元素
// type: 事件类型
// fn: 函数
if (ele.attachEvent) {
ele.attachEvent(‘on’ + type, fn);
} else {
ele.addEventListener(type, fn, false);
}
}
事件解绑
元素.事件 = 事件处理函数 元素.事件 = null;
元素.addEventListener 元素.removeEventListener(事件类型, 函数名, 是否捕获);
元素.attachEvent 元素.detachEvent(on+事件类型, 函数名);
unbind(div, ‘click’, a);
function unbind(ele, type, fn) {
// ele: 元素
// type: 事件类型
// fn: 函数名
if (ele.removeEventListener) {
ele.removeEventListener(type, fn, false);
} else {
ele.detachEvent(‘on’ + type, fn);
}
}
函数高级
回调函数
回调函数: 等一个动作执行完成后 还要执行的动作
// 先定义一个后续要使用的函数
function a() {
console.log(1);
}
// 等待点击页面之后 执行a函数中的代码
document.onclick = function () {
console.log(‘点击’);
a();
}
function b() {
console.log(‘成功’);
}
// 获取数据
function getData(fn) {
// 执行自己代码的函数
fn();
}
getData(b);
getData(a);
匿名函数
匿名: 没有名字的函数
匿名函数直接写会报错 将匿名函数转成表达式 外面加上()
匿名函数自执行:
匿名函数可以传参: 形参写在function后面的() 实参写在调用()
匿名函数可以接受返回值:
(function () {
console.log(‘匿名函数’);
});
// IIFE: 立即执行函数 Immediately Invoke Function Expression
// 注意: 必须加;
// 匿名函数自执行:
(function () {
console.log(‘匿名函数自执行’);
})();
(function () {
console.log(‘匿名函数自执行’);
}());
// 匿名函数可以传参: 形参写在function后面的() 实参写在调用()
(function (a, b) {
console.log(a, b); // 10, 20
console.log(arguments);
})(10, 20);
// 匿名函数可以接受返回值:
var res = (function () {
return 10 + 20;
})();
console.log(res);
闭包
闭包: 可以访问其他函数内部变量的函数(函数里面套函数, 内部函数访问外部函数的变量)
优点: 扩大了内部变量的作用范围
缺点: 数据量大量缓存 导致内存浪费
unction outer() {
var b = 10;
function inner() {
b++;
console.log(b);
}
// 设置返回值
return inner;
};
var res = outer(); // res == inner
res(); // 11
res(); // 12
res(); // 13
F12 开控制台 —> Sources
----> 点到自己的文件
设置断点:
\1. 外层函数outer的第一行代码
\2. 内层函数inner的带一行代码
查看Scope:
local: 当前局部作用域
global: 全局作用域
Closure: 闭包
// 外层函数每调用一次就形成一个新的闭包
var r = outer();
r(); // 11
// 闭包一直存在与内存中 造成内存浪费(垃圾回收)
r = null;
闭包应用
解决全局变量i的影响
原因: for循环中的 i 是一个全局变量 由于点击函数没有局部变量
解决: 给循环的事件的时候 添加局部变量
for(var j = 0; j < btns.length; j++){
(function (s) {
console.log(s);
btns[s].onclick = function () {
console.log(s);
}
})(j);
}
模拟私有变量
function student(name) {
var user = name; // 档案入库
// console.log(user);
// 查看函数
function see() {
console.log(user);
}
// 修改函数
function edit() {
user = '迪丽热巴';
}
// 提供接口 设置返回值
return {
'see': function () {
console.log(user);
},
'edit': edit
};
}
var res = student(‘张三’);
console.log(res); // {see: ƒ, edit: ƒ}
// 查看名字
res.see();
res.edit();
res.see();
递归
递归: 函数里面调用自己 必须要有函数结束的条件
报错: Maximum call stack size exceeded 栈溢出
解决: 加上函数结束的条件
阶乘
function jc(n) {
if(n == 1) {
return 1;
}
return n * jc(n-1);
}
var s = jc(6);
console.log(s);
console.log(jc(1000));
斐波那契数列
月 兔子
1 1
2 1
3 1 1
4 1 1 1
5 1 1 1 1 1
6 1 1 1 1 1 1 1 1
1月 1
2月 1
3月 2 = 1+1
4月 3 = 2+1
5月 5 = 3+2
6月 8 = 5+3
// 计算第6个月有多少对兔子
function fib(n) {
/*
第n个月的兔子 = 第n-1个月 + 第n-2个月
6 = 5 + 4
= (4 + 3) + 4
= (3 + 2 + 3) + 3 + 2
= 2 + 1 + 2 + 2 + 1 + 2 + 1 + 2
= 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
*/
// 判断条件
if(n == 1 || n == 2) return 1;
return fib(n-1) + fib(n-2);
}
console.log(fib(6));
// 不要算20以上
console.log(fib(21));
快速排序/二分法
\1. 找到中间下标
\2. 找到中间下标对应的值
\3. 原数组中删除中间值
\4. 声明2个空数组
\5. 判断原数组剩下的每一个项和中间值得大小, 比中间值小的 放在left
比中间值大的放在 right
\6. 封装代码
\7. 设置结束条件
\8. 设置整个函数的返回值
function qs(array) {
// 7. 设置结束条件
if(array.length <= 1){
return array;
}
// 1. 找下标
var ind = Math.floor(array.length / 2);
// 2. 存值
var val = array[ind];
// console.log(val);
// 3. 删除中间值
array.splice(ind, 1);
// console.log(array);
// 4. 声明2个空数组
var left = [],
right = [];
// 5. 每一个
for (var i = 0; i < array.length; i++) {
if (array[i] < val) {
left.push(array[i]);
} else {
right.push(array[i]);
}
}
// console.log(left, right);
// 6. 递归排序
// 8. 设置整个函数的返回值
return qs(left).concat(val, qs(right));
}
var a = qs(arr);
console.log(a);
防抖
防抖: 只要用户触发事件, 清除定时器, 重新开始计时
避免造成全局污染 选择使用闭包实现效果
// 当鼠标滑动的时候 对n进行累加 div的内容显示n
var n = 0;
// 事件三部曲
// 获取元素
var div = document.getElementsByTagName(‘div’)[0];
// 加事件
div.onmousemove = debounce(100, a);
function a() {
n++;
// div的内容显示n
div.innerHTML = n;
}
// 防抖: 只要用户触发事件, 清除定时器, 重新开始计时
// 避免造成全局污染 选择使用闭包实现效果
function debounce(date, fn) {
// 声明一个变量 用来接收定时器的唯一标识
var timer = null;
// 内部函数表示事件处理函数
function inner() {
// 清除定时器
clearTimeout(timer);
// 重新开始计时
timer = setTimeout(fn, date);
};
// 设置返回值
return inner;
}
节流
节流: 让用户在一段时间之内 只能执行一次
判断当前的状态tag tag是true 允许用户执行 tag是false不让执行
到时间之后重新变成可执行状态
// 当鼠标滑动的时候 对n进行累加 div的内容显示n
var n = 0;
// 事件三部曲
// 获取元素
var div = document.getElementsByTagName(‘div’)[0];
// 加事件
div.onmousemove = throttle(500, a);
function a() {
n++;
// div的内容显示n
div.innerHTML = n;
}
// 节流: 让用户在一段时间之内 只能执行一次
// 判断当前的状态tag tag是true 允许用户执行 tag是false不让执行
// 到时间之后重新变成可执行状态
function throttle(date, fn) {
// date: 间隔时间
// fn: 执行的函数
// 声明一个变量 接收唯一标识
var timer = null;
// 假设一个可以执行的状态
var tag = true;
// 内部代码 表示 用户的事件处理函数
function inner() {
// 判断函数是否可以执行
if(tag){
timer = setTimeout(function () {
fn();
// 当定时器函数执行的时候 表示用户的间隔时间已经到了
// 将tag = true
tag = true;
// 定时器执行后 清除定时器
clearTimeout(timer);
}, date);
// 更新状态
tag = false;
}
}
// 设置返回值
return inner;
}
call与apply
作用: 改变this的指向
区别: 传参的时候不同
call和apply都是用来改变函数中this的指向
call: 函数.call(this的新指向, 值1, 值2, … 值n);
apply: 函数.apply(this的新指向, [值1, 值2, … 值n]);
call
function a() {
console.log(this);
}
a(); // window
// 改变this的指向
a.call(1);
a.call(document);
a.call([]);
function b(x, y) {
console.log(this, x, y);
}
b(10, 20); // window 10 20
b.call(1, ‘a’, ‘b’); // {1} ‘a’ ‘b’
// 用来判断数据的类型
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
// 使用对象的toString方法可以判断数据类型
// prototype: 原型对象
console.log(Object.prototype.toString());
console.log(Object.prototype.toString.call(123)); // [object Number]
console.log(Object.prototype.toString.call(‘qwer’)); // [object String]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call([]).slice(8, -1)); // Array
console.log(Object.prototype.toString.call({}).slice(8, -1)); // Object
// 复杂–>对象
var obj = {
name: ‘迪丽热巴’,
say: function () {
console.log(this);
console.log(this.name);
}
}
obj.say(); // obj {name: “迪丽热巴”, say: ƒ} 迪丽热巴
var o1 = {
name: ‘杨洋’
};
obj.say.call(o1); // o1 {name: “杨洋”} 杨洋
apply
// apply: 找到数组的最大值
var arr = [32, 54, 13, 54, 233, 54, 23, 457, 99, 5];
console.log(Math.max(3, 4, 5, 6));
// this的新指向写任何东西
console.log(Math.max.apply(1, [3, 4, 5, 6]));
console.log(Math.max.apply(1, arr));
面向对象创建
字面量
语法:
var 变量 = {
属性名: 属性值,
方法名: 方法
}
优点: 直观
缺点: 只适用于创建单个对象
var obj = {
name: ‘迪丽热巴’,
age: 32,
work: function () {
console.log(‘演戏、唱歌、跳舞’);
}
};
console.log(obj);
console.log(obj.name);
console.log(obj.age);
obj.work();
new关键字创建
var 变量 = new Object();
变量.属性名 = 属性值;
变量.方法名 = 函数;
缺点: 代码冗余
var obj = new Object();
obj.name = ‘迪丽热巴’;
obj.age = 32;
obj.work = function () {
console.log(‘唱歌跳舞演戏’);
};
console.log(obj);
工厂模式
工厂模式问题: 识别不清
对象 instanceof 函数名 判断对象是否由函数创建 false-不是 true–是
function createObj(name, age) {
// 1. 创建对象
var obj = new Object();
// 2. 添加属性和方法
obj.name = name;
obj.age = age;
obj.work = function () {
console.log('唱歌跳舞演戏');
}
// 3. 出厂 设置返回值
return obj;
};
var dlrb = createObj(‘迪丽热巴’, 32);
var yy = createObj(‘杨洋’, 33);
console.log(dlrb, yy);
// 问题: 识别不清
// 对象 instanceof 函数名 判断对象是否由函数创建 false-不是 true–是
console.log(dlrb instanceof createObj);
构造函数
构造函数: 就是个函数 用来构造对象
\1. 函数名首字母大写(约定)
\2. 所有的方法和属性 加给 this
\3. 调用的时候必须用new调用 否则和普通函数一样
\4. 不需要创建和设置返回值
缺点: 内存浪费
new的时候发生了什么:
\1. 创建一个空对象
\2. 将this指向空对象
\3. 将函数的prototype赋值给对象的__proto__
\4. 指向函数中的代码 添加属性和方法
\5. 隐式返回
function CreateObj(name, age) {
console.log(this);
this.name = name;
this.age = age;
this.work = function () {
console.log(‘演戏唱歌跳舞’);
}
}
var obj = new CreateObj(‘迪丽热巴’, 32);
var yy = new CreateObj(‘杨洋’, 32);
console.log(obj, yy);
// 优点: 解决了识别不清
console.log(obj instanceof CreateObj);
obj.work();
yy.work();
// 判断是否是同一个函数 ==
console.log(obj.work == yy.work); // false
原型
原型对象 prototype: 在每一个函数被创建的时候 用来存储共享的方法和属性的对象
原型属性 proto: 在每一个实例对象被创建的时候 用来存储共享的方法和属性的对象
共享的方法和属性都加给原型对象prototype, 后期通过构造函数创建的实例化对象都可以使用共享的方法和属性
console.log(String);
console.log(String.prototype);
var str = new String(123);
console.log(str);
console.log(str.proto);
console.log(String.prototype == str.proto); // true
原型创建
缺点: 1. 不能传参
一改全改
function CreateObj() { }
// 给原型对象添加属性和方法
CreateObj.prototype.name = ‘张三’;
CreateObj.prototype.age = 33;
CreateObj.prototype.money = [‘基金’, ‘股票’, ‘影视’];
CreateObj.prototype.work = function () {
console.log(‘吃饭睡觉打豆豆’);
};
// 实例化对象
var obj = new CreateObj();
console.log(obj);
console.log(obj.name);
var obj1 = new CreateObj();
console.log(obj1);
console.log(obj.work == obj1.work); // true
obj1.name = ‘迪丽热巴’;
console.log(obj.name, obj1.name);
console.log(obj.money, obj1.money); // [“基金”, “股票”, “影视”]
// 一改全改
obj.money.push(‘定期’);
console.log(obj.money, obj1.money);
原型链: 当一个对象被创建的时候所自带的链表关系, 可以实现继承和查找, 从自身开始查找, 有就直接使用, 没有往上一级原型上去查找.
混合创建
混合创建: 构造函数(可变的) + 原型创建(不变的 共享的)
// 构造函数
function CreateObj(name, age) {
this.name = name;
this.age = age;
this.money = [‘基金’, ‘股票’, ‘影视’];
};
// 原型创建
CreateObj.prototype.work = function () {
console.log(‘挣钱’);
};
// 实例化对象
var obj = new CreateObj(‘迪丽热巴’, 32);
var obj1 = new CreateObj(‘杨洋’, 33);
console.log(obj, obj1);
console.log(obj.name, obj1.name);
console.log(obj.money, obj1.money);
obj.money.push(‘定期’);
console.log(obj.money, obj1.money);
console.log(obj.work == obj1.work); // true
面向对象继承
特点: 封装 继承 多态(date + null ‘123’+null 123null 123+null=123)
继承: 子承父
原型链继承
原型链: 当一个对象被创建的时候 所自带的链表关系 实现继承和查找
继承: 子类构造函数的原型对象 = 父类构造函数的实例化对象;
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
this.arr = [‘理财’, ‘股票’, ‘期权’];
};
Father.prototype.money = function () {
console.log(‘月入100w’);
};
// 子类构造函数
function Son() { }
// 继承: 子类构造函数的原型对象 = 父类构造函数的实例化对象;
Son.prototype = new Father(‘张恒’, 38);
// 子类构造函数:实例化对象
var obj = new Son();
console.log(obj);
console.log(obj.name);
console.log(obj.toString);
查找过程
先找自身, 自身没有就往上一级找,
找到自己的原型属性(父类构造函数的实例化对象),
找不到在找父类构造函数的原型属性,
如果没有,找object, 如果没有返回undefined, 有就直接返回;
问题:
\1. 不能传参
\2. 一改全改
var obj1 = new Son();
console.log(obj.arr, obj1.arr);
obj.arr.push(‘定期’);
console.log(obj.arr, obj1.arr);
对象冒充继承
对象冒充继承: 将父类构造函数的this指向变成子类构造函数的this
问题: 不能继承父类构造函数的原型对象上的方法和属性
核心: 在子类构造函数中调用父类构造函数 改变this
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
this.arr = [‘基金’, ‘股票’];
}
Father.prototype.money = function () {
console.log(‘月入百万’);
};
// 子类构造函数
function Son(name, age) {
// 在子类构造函数中调用父类构造函数 改变this
Father.call(this, name, age);
this.play = function () {
console.log(‘玩王者荣耀’);
};
};
Son.prototype.work = function () {
console.log(‘写作业’);
};
// 实例化
var obj = new Son(‘张恒’, 38);
var obj1 = new Son(‘郑爽’, 36);
console.log(obj, obj1);
console.log(obj.toString);
console.log(obj.money); // undefined
console.log(obj.arr, obj1.arr);
obj.arr.push(‘定期’);
console.log(obj.arr, obj1.arr);
组合继承
组合继承: 对象冒充继承 + 原型链继承
问题:
\1. 父类构造函数的属性和方法会存储2次
\2. 子类构造函数的原型对象上的方法和属性找不到
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
this.arr = [‘基金’, ‘股票’];
}
Father.prototype.money = function () {
console.log(‘月入百万’);
};
// 子类构造函数
function Son(name, age) {
// 在子类构造函数中调用父类构造函数 改变this
Father.call(this, name, age);
this.play = function () {
console.log(‘玩王者荣耀’);
};
};
Son.prototype.work = function () {
console.log(‘写作业’);
};
// 原型链继承: 子类构造函数的原型对象 = 父类构造函数的实例化对象
Son.prototype = new Father();
// 实例化
var obj = new Son(‘小凯’, 23);
console.log(obj);
console.log(obj.toString);
寄生式组合继承
寄生式组合继承: 对象冒充继承 + 原型链继承
\1. 在子类构造函数中调用父类构造函数 改变this
\2. 原型链继承: 子类构造函数的原型对象 = 利用父类构造函数的原型对象创建的实例化对象
\3. 手动修改子类构造函数的原型对象指向的构造函数
// 寄生式组合继承: 对象冒充继承 + 原型链继承
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
this.arr = [‘基金’, ‘股票’];
}
Father.prototype.money = function () {
console.log(‘月入百万’);
};
// 子类构造函数
function Son(name, age) {
// 1. 在子类构造函数中调用父类构造函数 改变this
Father.call(this, name, age);
this.play = function () {
console.log(‘玩王者荣耀’);
};
};
// 2. 原型链继承: 子类构造函数的原型对象 = 利用父类构造函数的原型对象创建的实例化对象
// Object.create(原型对象): 使用原型对象创建一个对象
Son.prototype = Object.create(Father.prototype);
// 3. 手动修改子类构造函数的原型对象指向的构造函数
Son.prototype.constructor = Son;
// 子类构造函数的原型对象
Son.prototype.work = function () {
console.log(‘写作业’);
};
// 实例化
var obj = new Son(‘小凯’, 23);
console.log(obj);
console.log(obj.toString);
Less
Less是一个CSS预处理器, 用js实现的可以在live
使用变量 利于修改网站风格
实现嵌套 代码编写更简洁明了
查找:
less: https://less.bootcss.com/
使用:
插件: easy Less
写完less文件后 按ctrl+s保存后 就会生成css文件
\1. 创建后缀为.less的文件 写less
\2. 在html引入.css后缀的文件
配置:
设置—>扩展设置–>在setting.json中设置
“out”: “…/css/”,
out: 产出css的位置
变量
@变量名: 设置的值;
@color: blue;
/* 这是边框 */
@bd: 10px dotted pink;
div{
color: @color;
border: @bd;
}
注释:
/* 块注释 */ 在css中会显示
// 单行注释 在css中不显示
// @color: red;
@color: blue;
/* 这是边框 */
@bd: 10px dotted pink;
作用域
@color: yellow;
div{
@color: blue;
color: @color;
}
混入Mixins
在一个选择器中 使用其他选择器的所有样式
选择器a{
选择器b();
}
.a{
width: 200px;
height: 200px;
background: red;
}
.b{
// 混入
.a();
color: yellow;
border: 1px solid #000;
}
嵌套
父{
子{}
&: 表示当前这级选择器
}
*{
margin: 0;
padding: 0;
list-style: none;
}
// 轮播图
#wrap{
width: 1180px;
height: 350px;
margin: 40px auto;
position: relative;
ul{
position: relative;
width: 100%;
height: 100%;
li{
position: absolute;
top: 0;
left: 0;
display: none;
width: 100%;
height: 100%;
img{
width: 100%;
height: 100%;
}
&.active{
display: block;
}
&:hover{
// border: 1px solid #000;
animation: auto 2s linear infinite;
}
}
&::after{
content: '';
clear: both;
display: block;
}
@keyframes auto {
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
@media screen and (min-width: 1200px) {
width: 1180px;
}
@media screen and (min-width: 920px) and (max-width: 1199px){
width: 800px;
}
@media screen and (min-width: 768px) and (max-width: 919px) {
width: 760px;
}
}
}
转义
转义(Escaping)允许你使用任意字符串作为属性或变量值。
当需要一串字符串原样输出 , 常用于样式过长且字符过多的时候
@变量: ~“字符”;
@变量: ~‘字符’;
简化:
@变量: (字符);
@color: red;
@aw12: ~“max-width: 1200px”;
@iw12: ~‘min-width:1200px’;
// 报错不影响页面的css的生成和渲染
@aw92: (min-width: 920px);
div{
color: @color;
width: 1200px;
height: 400px;
background: pink;
@media screen and (@iw12) {
width: 1200px;
}
@media screen and @aw92 and (@aw12) {
width: 990px;
}
}
计算
计算: 倍数的计算
对任何数字、颜色或变量进行运算
如果单位之间可以转换会尽可能的转换,不能的就忽略单位
@w: 1000px;
@h: 500px;
@r: 50;
div.a{
margin: 0;
padding: 0;
width: 1000px;
height: 500px;
.left{
width: @w - 300 + 100 + 10pt;
height: @h - 200 + 10rem + 10pt;
background: rgb(@r * 4, @r * 10, 0);
}
}
映射
映射: 用于有一系列相关的数据的时候 颜色
声明:
#变量名(){
属性名: 属性值;
}
使用: #变量名[属性名]
#color(){
default: #000;
high: blue;
light: skyblue;
}
div:nth-child(1){
color: #color[default];
}
div:nth-child(2){
color: #color[high];
}
div:nth-child(3){
color: #color[light];
}
导入
在less文件中要引入其他的less文件或者css文件
// 引入less文件的时候 后缀.less可以省略
@import “13”;
// 引入css文件的时候 后缀.css不可以省略
@import “…/css/14.css”;
项目流程
部门及职责
产品: 接收到需求 出需求文档 原型图
UI: 出设计图
web: 精准还原 渲染数据 实现功能
后台: 接口
测试: 测试场景
项目规范:
\1. 规范目的
\2. 规范部分
2.1 文件命名规范: 各版块分文件夹 英特殊符文+号_ 对应文件命名: 首页的html\css\js: index.html\css\js
2.2 样式规范 提高选择器的优先级 父子 后代 交叉 属性 内容
主题风格 颜色、使用变量
2.3 页面结构 语义化 起名 banner onlinelist poster 从大块划小块
2.4 js: 引入位置: body的结束标签
2.4.1 引入数据
2.4.2 公用js库
2.4.3 引入小的板块
2.4.4 自己的js window.onload—一个页面只能出现一个
事件绑定
数据渲染
\1. 先写板块注释
\2. 获取到数据
\3. 获取要渲染的父元素 ul
\4. 页面原有的子元素注释掉
\5. 生成页面片段
本地缓存
所需要的数据存储到电脑中
所存储的所有数据全部都是字符串
记住密码、记住登录状态
// localStorage: 对象
console.log(localStorage);
// 存储数据
// 对象.属性名 = ‘属性值’;
localStorage.name = ‘张三四’;
// localStorage.setItem(‘属性名’, ‘属性值’);
localStorage.setItem(‘name1’, ‘李四三’);
// 获取数据
// 对象.属性名
console.log(localStorage.name);
// localStorage.getItem(‘属性名’);
console.log(localStorage.getItem(‘name1’));
// 删除数据
// localStorage.removeItem(‘属性名’)
localStorage.removeItem(‘name’);
// 清空本地缓存
// localStorage.clear();
console.log(localStorage);
video
src: 视频播放的地址
width: 宽
height: 高
controls: 控制器
poster: 海报
muted: 静音
autoplay: 自动播放 只有静音状态下
currentSrc: 当前播放的地址
volume: 音量: 0-1
duration: 时长 在视频可以播放之后才能拿到 NaN 单位: s 秒
playbackRate: 当前视频的播放速度 默认1 可设置: >0 改变当前视频的播放速度
defaultPlaybackRate: 默认视频的播放速度 默认1 可设置: >0 改变后续视频的播放速度
paused: 暂停状态 true–暂停 false–播放
ended: 结束状态 true–结束 false–未结束
currentTime: 当前的播放时间的位置
loop: 循环播放
获取属性
// 获取video
var video = document.querySelector(‘video’);
console.log(video);
// video的属性均可操作
// 获取: 直接写属性名就能起作用的在js中的值就是true和false
console.log(video.src);
console.log(video.currentSrc); // 当前播放的地址
console.log(video.width, video.height);
console.log(video.controls); // 是否有控制器
console.log(video.poster); // 海报地址
console.log(video.muted);
console.log(video.autoplay);
console.log(video.volume); // 音量: 0-1
console.log(video.duration); // 时长 在视频可以播放之后才能拿到 NaN 单位: s 秒
console.log(video.playbackRate); // 当前视频的播放速度 默认1 可设置: >0 改变当前视频的播放速度
console.log(video.defaultPlaybackRate); // 默认视频的播放速度 默认1 可设置: >0 改变后续视频的播放速度
console.log(video.paused); // 暂停状态 true–暂停 false–播放
console.log(video.ended); // 结束状态 true–结束 false–未结束
console.log(video.currentTime); // 当前的播放时间的位置
console.log(video.loop); // 循环播放
设置属性
// video.loop = true;
video.poster = ‘./小U课堂/img/index/tbanner2.png’;
video.autoplay = true;
var btns = document.querySelectorAll(‘button’);
btns[0].onclick = function () {
video.src = ‘./video/岳小康、计应3班2019020336.mp4’;
};
btns[1].onclick = function () {
video.width = 1000;
video.height = 700;
};
btns[2].onclick = function () {
video.controls = !video.controls;
console.log(video.controls);
};
btns[3].onclick = function () {
video.muted = !video.muted;
console.log(video.muted);
};
video.volume = 1;
btns[4].onclick = function () {
video.volume += 0.1;
console.log(video.volume);
};
btns[5].onclick = function () {
// video.playbackRate = 0.1;
video.defaultPlaybackRate = 0.1;
console.log(video.playbackRate, video.playbackRate);
};
btns[6].onclick = function () {
// video.playbackRate = 1;
video.defaultPlaybackRate = 1;
console.log(video.playbackRate, video.playbackRate);
};
btns[7].onclick = function () {
// video.playbackRate = 10;
video.defaultPlaybackRate = 10;
console.log(video.playbackRate, video.playbackRate);
};
btns[8].onclick = function () {
video.currentTime = video.duration / 2;
};
事件
// 事件
video.onplay = function () {
console.log(video.currentSrc); // 当前播放的地址
console.log(video.duration); // 时长 在视频可以播放之后才能拿到 NaN 单位: s 秒
console.log(video.paused);
console.log(video.ended);
};
// 当用户播放过程中时间发生改变
video.ontimeupdate = function () {
console.log(video.currentTime);
}
// 当整个视频播放结束 且没有下一个的时候
video.onended = function () {
console.log(video.ended);
};
// 当视频暂停的时候 触发的事件
video.onpause = function () {
console.log(‘当前视频是否暂停’, video.paused);
};
方法
load: 重新载入视频
pause: 暂停播放
play: 开始播放
btns[9].onclick = function () {
video.load();
};
btns[10].onclick = function () {
video.pause();
};
btns[11].onclick = function () {
video.play();
};
Jquery
介绍
jquery: js的一个插件库
06年 Join resig
理念: 写得少 做得多(write less, do more)
特点:
完善的DOM操作机制
强大的选择器
链式调用
隐式迭代
解决了兼容: 1XX 兼容ie >2XX 不兼容ie
完善ajax实现数据请求
开源
jq的完善文档
使用:
https://www.bootcdn.cn/jquery/
jquery.js: 未压缩 学习
jquery.min.js: 压缩 工作
api网站: https://jquery.cuishifeng.cn/
ready
window.onload: 等待页面和资源加载完成后在执行
ready: 等待页面结构加载完成
window.onload和ready方法的区别:
load: 等待页面和资源都加载完成后才执行, 后面的会覆盖前面的, 没有简写
ready: 等待页面加载完成后执行, 多个会叠加依次执行, 有简写 $(function(){});
// $ is not defined: jq没有引入
window.onload = function () {
console.log(1);
};
window.onload = function () {
console.log(2);
};
$(document).ready(function () {
console.log(3);
});
$().ready(function () {
console.log(4);
});
( f u n c t i o n ( ) c o n s o l e . l o g ( 5 ) ; ) ; 冲 突 解 决 当 j q 的 (function () { console.log(5); }); 冲突解决 当jq的 (function()console.log(5););冲突解决当jq的覆盖其他人的$
当别人的覆盖自己的:
对象互转
js的方法和属性只能给js对象使用 jq的方法和属性只能给jq对象使用
原生转成jq对象 ( 原 生 j s 对 象 ) c o n s o l e . l o g ( (原生js对象) console.log( (原生js对象)console.log((div));
console.log($(div[0]));
jq对象转js对象
\1. 通过下标获取到具体的元素
\2. get方法: jq对象.get(下标);
// 1. 通过下标获取到具体的元素
console.log(div1[0]);
// 2. get方法: jq对象.get(下标);
console.log(div1.get(0));
jq方法特性
取赋值一体化: 取值、赋值用的是同一个方法
取值: 获取到符合选择器条件的第一个元素的值 除了text
赋值: 隐式迭代设置所有的元素
隐式迭代: 所有的设置\所有的添加事件\所有的动画 在做添加的时候, 而是隐式的遍历所有的元素设置上
链式调用: 方法可以使用连点的方式依次执行
原理: jq的方法都有返回值, 返回被操作的对象或者操作以后的对象
选择器
基础选择器
基础选择器: tagname .classname #id
console.log( ( ′ l i ′ ) ) ; c o n s o l e . l o g ( ('li')); console.log( (′li′));console.log((’.box’));
console.log(KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲awrap')); conso…(’.box, #awrap’));
层级选择器
父 子: 后代选择器 在父元素获取所有的后代的子元素
父 > 子: 直接子元素 在父元素中获取直接包裹的第一级子元素
兄a + 弟b: 相邻兄弟选择器 获取紧跟着a选择器后面的b选择器
兄a ~ 弟b: 后面兄弟 获取a后面所有的b
console.log( ( ′ u l l i ′ ) ) ; / / 6 c o n s o l e . l o g ( ('ul li')); // 6 console.log( (′ulli′));//6console.log((‘ul > li’)); // 5
console.log( ( ′ l i + d i v ′ ) ) ; c o n s o l e . l o g ( ('li + div')); console.log( (′li+div′));console.log((’.box + div’)); // 不能
console.log($(’.box ~ div’)); // .box后面所有的div标签
基础过滤选择器
/ 通过样式设置
// jq对象.css(属性名, 属性值);
$(‘ul li:first’).css(‘background’, ‘red’); // 获取li中的第一个
$(‘ul li:last’).css(‘background’, ‘red’); // 获取li中的最后一个
$(‘ul li:nth-child(2)’).css(‘background’, ‘red’); // 获取li中的第2个
// 奇偶数
$(‘ul li:odd’).css(‘background’, ‘pink’); // 获取li中下标为奇数
$(‘ul li:even’).css(‘background’, ‘skyblue’); // 获取li中下标为偶数
// 大于小于
$(‘ul li:gt(4)’).css(‘background’, ‘blue’); // 获取li下标大于4
$(‘ul li:lt(4)’).css(‘background’, ‘blue’); // 获取li下标小于4
$(‘ul li:eq(4)’).css(‘background’, ‘red’); // 获取li下标等于4
// 不为
$(‘ul li:not(.box)’).css(‘background’, ‘pink’); // 获取li中类名不为box的
属性过滤选择器
$(‘li[class]’).css(‘background’, ‘red’); // 获取li中有class属性
$(‘li[class=box]’).css(‘background’, ‘skyblue’); // 获取li中class值为box的元素
$(‘li[class^=b]’).css(‘background’, ‘orange’); // 获取li中class属性值以b为开头的元素
( ′ l i [ c l a s s ('li[class (′li[class=b]’).css(‘background’, ‘purple’); // 获取li中class属性值以b为结尾的元素
$(‘li[class*=b]’).css(‘background’, ‘aqua’); //获取li中class属性值有b的元素
( ′ l i [ c l a s s ! = b o x ] ′ ) . c s s ( ′ b a c k g r o u n d ′ , ′ d e e p p i n k ′ ) ; / / 获 取 l i 中 c l a s s 属 性 值 不 等 于 b o x 的 元 素 表 单 过 滤 选 择 器 c o n s o l e . l o g ( ('li[class!=box]').css('background', 'deeppink'); // 获取li中class属性值不等于box的元素 表单过滤选择器 console.log( (′li[class!=box]′).css(′background′,′deeppink′);//获取li中class属性值不等于box的元素表单过滤选择器console.log((’:input’)); // 获取所有表单元素
console.log( ( ′ : i n p u t : t e x t ′ ) ) ; c o n s o l e . l o g ( (':input:text')); console.log( (′:input:text′));console.log((’:input:password’));
console.log( ( ′ : i n p u t : r a d i o ′ ) ) ; c o n s o l e . l o g ( (':input:radio')); console.log( (′:input:radio′));console.log((’:input:checkbox’));
console.log( ( ′ : c h e c k e d ′ ) ) ; c o n s o l e . l o g ( (':checked')); console.log( (′:checked′));console.log((’checked’));
console.log( ( ′ : c h e c k b o x : c h e c k e d ′ ) ) ; 节 点 遍 历 / / 查 找 子 节 点 : j q 对 象 . c h i l d r e n ( 筛 选 条 件 ) c o n s o l e . l o g ( (':checkbox:checked')); 节点遍历 // 查找子节点: jq对象.children(筛选条件) console.log( (′:checkbox:checked′));节点遍历//查找子节点:jq对象.children(筛选条件)console.log((‘ul’).children()); // 找到直接子节点
console.log( ( ′ u l ′ ) . c h i l d r e n ( ′ . b o x ′ ) ) ; / / 找 到 直 接 子 节 点 c o n s o l e . l o g ( ('ul').children('.box')); // 找到直接子节点 console.log( (′ul′).children(′.box′));//找到直接子节点console.log((‘ul’).find(’.box’)); // 找到子节点
console.log($(‘ul’).find(‘div’)); // 找到子节点
// 找父节点
console.log( ( ′ . b o x ′ ) . p a r e n t ( ) ) ; / / 直 接 父 节 点 c o n s o l e . l o g ( ('.box').parent()); // 直接父节点 console.log( (′.box′).parent());//直接父节点console.log((’.box’).parents()); // 所有父节点 html
// 上面的兄弟节点 prev/prevAll(筛选条件)
console.log( ( ′ . b o x ′ ) . p r e v ( ) ) ; / / 紧 跟 的 上 一 个 c o n s o l e . l o g ( ('.box').prev()); // 紧跟的上一个 console.log( (′.box′).prev());//紧跟的上一个console.log((’.box’).prevAll()); // 前面所有的
// 下面的兄弟节点
console.log( ( ′ . b o x ′ ) . n e x t ( ) ) ; / / 紧 跟 的 下 一 个 c o n s o l e . l o g ( ('.box').next()); // 紧跟的下一个 console.log( (′.box′).next());//紧跟的下一个console.log((’.box’).nextAll()); // 后面的所有的
// 所有兄弟节点
console.log($(’.box’).siblings());
操作属性
prop:
语法: jq对象.prop(属性名, 属性值)
获取: jq对象.prop(属性名)
设置: jq对象.prop(属性名, 属性值)
操作固有属性
attr:
语法: jq对象.attr(属性名, 属性值)
获取: jq对象.attr(属性名)
设置: jq对象.attr(属性名, 属性值)
操作所有的属性
移除属性:
jq对象.removeProp(‘属性名’);
jq对象.removeAttr(‘属性名’);
console.log( ( ′ d i v ′ ) . p r o p ( ′ i d ′ ) ) ; c o n s o l e . l o g ( ('div').prop('id')); console.log( (′div′).prop(′id′));console.log((‘div’).prop(‘class’));
console.log($(‘div’).prop(‘tag’)); // undefined
console.log( ( ′ d i v ′ ) . a t t r ( ′ i d ′ ) ) ; c o n s o l e . l o g ( ('div').attr('id')); console.log( (′div′).attr(′id′));console.log((‘div’).attr(‘class’));
console.log($(‘div’).attr(‘tag’)); // 123456
$(‘div’).prop(‘class’, ‘a’);
$(‘div’).prop(‘tag’, ‘这是tag’); // 没效果
$(‘div’).attr(‘tag’, ‘这是小的taga’);
$(’:checkbox’).attr(‘checked’, true);
// $(’:checkbox’).attr(‘checked’, false);
$(‘div’).removeAttr(‘class’);
操作类名
添加: jq对象.addClass(‘类名’) 在原有的基础上添加新的类名
删除: jq对象.removeClass(‘类名’) 在原有的基础上删除类名
切换: jq对象.toggleClass(‘类名’) 原来有就去掉 原来没有就加上
// $(‘div’).addClass(‘active’);
// $(‘div’).removeClass(‘active’);
$(‘div’).click(function () {
console.log(this);
$(this).toggleClass(‘active’);
});
操作样式
语法: jq对象.css(‘属性名’, ‘属性值’); jq对象.css({});
获取: jq对象.css(‘属性名’); 获取一个属性的值
设置: jq对象.css(‘属性名’, ‘属性值’);
jq对象.css({
‘属性名’: ‘属性值’,
‘属性名’: ‘属性值’
});
属性名: 引号可加可不加 建议加 可以使用-
属性值: 数字 加不加单位都可以
表达式 ‘+=’ ‘-=’
KaTeX parse error: Expected '}', got 'EOF' at end of input: … console.log((this).css(‘background’));
// var a = $(this).css(‘background’, ‘red’);
// console.log(a);
// a.css(‘height’, 200);
$(this).css('background', 'red').css('height', 200).css({
// 'width': 200,
// fontSize: 30
'font-size': 30,
'width': '+=10'
});
});
操作内容
val
表单: jq对象.val(); jq对象.val(值);
单复选框: 默认的value值就是on
val: 设置单选、复选的值: jq对象.val([‘值’, “值”]);
console.log( ( ′ : t e x t ′ ) . v a l ( ) ) ; c o n s o l e . l o g ( (':text').val()); console.log( (′:text′).val());console.log((’:text’).val(‘admin’));
console.log( ( ′ : r a d i o ′ ) ) ; c o n s o l e . l o g ( (':radio')); console.log( (′:radio′));console.log((’checked’).val());
console.log($(’:checkbox’).val());
$(’:radio’).val([‘man’]);
$(’:checkbox’).val([‘smooking’, ‘yq’]);
console.log( ( ′ s e l e c t ′ ) . v a l ( ) ) ; c o n s o l e . l o g ( ('select').val()); console.log( (′select′).val());console.log((‘select’).val(‘sh’));
html
共同点: 后面的会覆盖前面的
获取: jq对象.html();
可以识别标签的
设置: jq对象.html(值);
不想覆盖原内容 原内容 + 新内容
console.log( ( ′ d i v ′ ) . t e x t ( ) ) ; c o n s o l e . l o g ( ('div').text()); console.log( (′div′).text());console.log((‘div’).html());
var a = $(‘div’).html();
$(‘div’).text(‘这是一个新的内容’);
$(‘div’).html(‘这是一个新的内容’);
// 不想覆盖原内容 原内容 + 新内容
$(‘div’).html(a + ‘这是斜体’);
text
共同点: 后面的会覆盖前面的
获取: jq对象.text();
会获取到所有符合选择器元素的内容, 不能识别标签
设置: jq对象.text(值);
不想覆盖原内容 原内容 + 新内容
console.log($(‘div’).text());
var a = $(‘div’).text();
$(‘div’).text(‘这是一个新的内容’);
$(‘div’).html(‘这是一个新的内容’);
// 不想覆盖原内容 原内容 + 新内容
$(‘div’).text(a + ‘这是斜体’);
元素宽高
内容宽高
width(数值)
height(数值)
console.log($(‘div’).width(), ( ′ d i v ′ ) . h e i g h t ( ) ) ; / / c o n s o l e . l o g ( ('div').height()); // console.log( (′div′).height());//console.log((‘div’).width(300), $(‘div’).height(200));
可视宽高
可视宽高: 内容 + 内边距
innerWidth(数值)
innerHeight(数值)
屏幕的可视宽高:
$(window).innerWidth(), $(window).innerHeight()
console.log($(‘div’).innerWidth(), ( ′ d i v ′ ) . i n n e r H e i g h t ( ) ) ; / / 340225 / / c o n s o l e . l o g ( ('div').innerHeight()); // 340 225 // console.log( (′div′).innerHeight());//340225//console.log((‘div’).innerWidth(300), ( ′ d i v ′ ) . i n n e r H e i g h t ( 200 ) ) ; / / c o n t ( 260 ) + 40 = 300 c o n t ( 175 ) + 25 = 200 / / 屏 幕 的 可 视 宽 高 c o n s o l e . l o g ( ('div').innerHeight(200)); // cont(260) + 40 = 300 cont(175) + 25 = 200 // 屏幕的可视宽高 console.log( (′div′).innerHeight(200));//cont(260)+40=300cont(175)+25=200//屏幕的可视宽高console.log((window).innerWidth(), $(window).innerHeight());
占位宽高
占位宽高: 内容 + 内边距 + 边框
布尔: 是否包含外边距在内 false: 默认 不包含外边距margin true: 包含
outerWidth(数值, 布尔)
outerHeight( 数值, 布尔)
console.log( ( ′ d i v ′ ) . o u t e r W i d t h ( ) ) ; / / 200 + 40 + 22 = 262 c o n s o l e . l o g ( ('div').outerWidth()); // 200 + 40 + 22 = 262 console.log( (′div′).outerWidth());//200+40+22=262console.log((‘div’).outerWidth(true)); // 200 + 40 + 22 + 60 = 322
$(‘div’).outerWidth(400); // cont(338) + 40 + 22 = 400
$(‘div’).outerWidth(400, true); // cont(278) + 40 + 22 + 60 = 400
获取元素偏移距离
offset(): 获取的是元素距离页面左侧和顶部的距离
{top: 0, left: 0}
console.log( ( ′ d i v ′ ) . o f f s e t ( ) ) ; / / t o p : 10 , l e f t : 40 c o n s o l e . l o g ( ('div').offset()); // {top: 10, left: 40} console.log( (′div′).offset());//top:10,left:40console.log((‘div’).offset().top); // 10
滚动距离
scrollLeft()
scrollTop()
KaTeX parse error: Expected '}', got 'EOF' at end of input: … console.log((window).scrollTop(), $(window).scrollLeft());
});
$(‘button’).click(function () {
$(window).scrollTop(500);
$(window).scrollLeft(500);
});
循环
jq对象.map(函数) jq对象.each(函数)
map会将函数的返回值组成新数组返回
each就返回被操作的对象
var res = $(‘div’).map(function (i, v) { // 第一个形参: 下标 第二个形参: 项
console.log(i, v);
return 1;
});
var res1 = $(‘div’).each(function (i, v) { // 第一个形参: 下标 第二个形参: 项
console.log(i, v);
return 2;
});
console.log(res, res1);
创建节点
var li = $(‘
子.appendTo(‘父’);
// $(‘ul’).append(li);
li.appendTo(‘ul’);
添加到父节点的开头
父.prepend(子);
子.prependTo(父);
$(‘ul’).prepend(‘
新节点.inserAfter(参考节点);
$(’.box’).after(‘
新节点.insertBefore(参考节点);
$(’.box’).before(‘
remove: 删除元素,返回被删除的元素,不保留元素原来的事件
empty: 清空元素
$(‘li’).click(function () {
$(this).css(‘background’, ‘skyblue’);
});
$(‘button’).click(function () {
// var li = $(this).parent().detach();
var li = $(this).parent().remove();
console.log(li);
$(‘ul’).append(li);
return false;
});
$(‘div’).click(function () {
$(‘ul’).empty();
});
克隆节点
clone: jq对象.clone(boolean);
返回一个新节点
true: 克隆行为
false: 不克隆行为
$(‘li’).click(function () {
$(this).css(‘background’, ‘red’);
});
// var l = $(’.box’).clone();
var l = $(’.box’).clone(true);
console.log(l);
l.appendTo(‘ul’);
替换节点
参考节点.replaceWith(新节点);
新节点.replaceAll(参考节点);
$(‘li’).eq(0).replaceWith(li);
( ′ < l i > 4 < / l i > ′ ) . r e p l a c e A l l ( ('
事件对象
事件对象: 当事件发生的时候 浏览器会将相关事件的信息存储在一个对象中 这个对象就叫做事件对象(鼠标位置、触发源、事件类型…)
jq: 事件对象的兼容, 是以事件处理函数的第一个形参
$(‘div’).click(function (ev) {
console.log(ev); // jQuery.Event jq的事件对象
console.log(ev.originalEvent); // js的事件对象
console.log(ev.target); // 触发源
console.log(ev.delegateTarget); // 事件绑定的对象
console.log(ev.type); // 事件类型
console.log(ev.ctrlKey, ev.altKey, ev.shiftKey); // 对应的键是否被按下
console.log(ev.which); // 对应的按键的编码 左中右(123)
console.log(ev.clientX, ev.clientY); // 页面距离屏幕可视区域左侧和顶部的距离
console.log(ev.pageX, ev.pageY); // 鼠标距离页面左侧和顶部的距离
console.log(ev.screenX, ev.screenY); // 鼠标距离屏幕左侧和顶部的距离
console.log(ev.offsetX, ev.offsetY); // 鼠标距离触发源左侧和顶部的距离 不推荐
});
$(‘div’).contextmenu(function (ev) {
console.log(ev.which);
ev.preventDefault();
});
$(‘p’).click(function (ev) {
// 阻止冒泡兼容:
// ev.stopPropagation();
// 取消默认行为
// ev.preventDefault();
// 阻止冒泡 + 取消默认行为
return false;
});
事件绑定on
给同一事件添加多个事件处理函数
jq对象.on(‘事件类型’, 事件处理函数);
不会覆盖 会叠加
$(‘div’).on(‘click’, fn1);
$(‘div’).on(‘click’, fn2);
给多个事件添加同一事件处理函数
jq对象.on(‘事件 事件 事件’, 事件处理函数);
function fn3(ev) {
console.log(ev.type);
}
$(‘div’).on(‘mouseenter mouseleave’, fn3);
给多个事件添加不同事件处理函数
jq对象.on({
事件类型: 事件处理函数,
事件类型: 事件处理函数,
事件类型: 事件处理函数
});
$(‘div’).on({
mousedown: fn1,
mouseup: fn2,
mousemove: fn3
});
绑定自定义事件
事件类型: 自己定义
手动触发自定义事件: jq对象.trigger(‘事件类型’);
其他元素控制本元素事件 \ 页面结构清晰
$(‘div’).on(‘call’, function () {
console.log(‘你妈妈喊你回家吃饭’);
});
// 点击按钮 触发call事件
$(‘button’).click(function () {
$(‘div’).trigger(‘call’);
});
命名空间: 当一个项目足够大的时候 命名不够用
jq对象.on(‘事件类型.名’, 事件处理函数);
$(‘div’).on(‘click.fn1’, function () {
console.log(‘这是新的fn1’);
});
事件委托:
jq对象.on(‘事件类型’, ‘子选择器’, 事件处理函数)
this–> 触发的子元素
$(‘ul’).on(‘click’, ‘li, div’, function () {
console.log(this);
});
// 优势: 元素可以发生在未来
$(‘ul’).append(‘
只能触发一次
$(‘div’).one(‘click mousemove’, function () {
console.log(this);
});
取消事件
jq对象.off();
不传参: 表示取消所有的事件
事件类型: 表示取消当前事件的所有事件处理函数
两个参数: 表示取消当前事件的指定的事件处理函数
// $(‘div’).on(‘click mousemove mouseenter’, function (ev) {
// console.log(ev.type);
// });
// $(‘div’).on(‘mousemove’, function () {
// console.log(1);
// });
function fn1() {
console.log(1);
};
function fn2() {
console.log(2);
};
$(‘div’).on(‘click’, fn1);
$(‘div’).on(‘click’, fn2);
$(‘div’).on(‘click.fn1’, function () {
console.log(‘这是新的fn1’);
});
$(‘button’).click(function () {
// $(‘div’).off();
// $(‘div’).off(‘mousemove’);
// $(‘div’).off(‘click’, fn1);
$(‘div’).off(‘click.fn1’); // 事件类型.名: 表示取消当前的事件类型下的事件处理函数
});
合成事件
hover: 滑入滑出
jq对象.hover(函数);
一个函数: 划入滑出都触发这个函数
两个函数: 第一个划入 第二个滑出
// $(‘div’).hover(function (ev) {
// console.log(ev.type);
// });
$(‘div’).hover(function (ev) {
console.log(ev.type);
}, function () {
console.log(2);
});
动画
显示隐藏
show hide toggle
改变: w + h + o
不传参: 没有动画效果
show(speed, easing, callback)
speed: 动画执行的时间 单位: ms
easing: linear匀速 swing慢快慢
callback: 当动画执行完成后的回调函数
$(‘button’).eq(0).click(function () {
// $(‘div’).eq(0).show();
$(‘div’).eq(0).show(2000, ‘swing’, function () {
console.log(‘动画已经完成’);
});
});
$(‘button’).eq(1).click(function () {
// $(‘div’).eq(0).hide();
$(‘div’).eq(0).hide(2000, ‘swing’, function () {
console.log(‘完成’);
});
});
$(‘button’).eq(2).click(function () {
// $(‘div’).eq(0).toggle();
$(‘div’).eq(0).toggle(1000, ‘linear’, function () {
console.log(‘toggle’);
});
});
下拉收起
slideDown slideUp slideToggle
不传参: 有默认动画 400ms
slideDown(speed, easing, callback)
speed: 动画执行的时间 单位: ms
easing: linear匀速 swing慢快慢
callback: 当动画执行完成后的回调函数
$(‘button’).eq(0).click(function () {
// $(‘div’).slideDown();
$(‘div’).slideDown(1000, ‘swing’, function () {
console.log(‘下拉结束’);
});
});
$(‘button’).eq(1).click(function () {
// $(‘div’).slideUp();
$(‘div’).slideUp(1000, ‘linear’, function () {
console.log(‘收起结束’);
});
});
$(‘button’).eq(2).click(function () {
// $(‘div’).slideToggle();
$(‘div’).slideToggle(1000, ‘swing’, function () {
console.log(‘切换完成’);
});
});
透明度
fadeIn fadeOut fadeToggle
不传参: 有动画效果 400ms
fadeIn(speed, easing, callback)
fadeTo(speed, to, easing, callback)
speed: 动画执行的时间 单位: ms
easing: linear匀速 swing慢快慢
callback: 当动画执行完成后的回调函数
to: 到某一个透明度 0-1
$(‘button’).eq(0).click(function () {
// $(‘div’).fadeIn();
$(‘div’).fadeIn(1000, ‘swing’, function () {
console.log(‘显示了’);
});
});
$(‘button’).eq(1).click(function () {
// $(‘div’).fadeOut();
$(‘div’).fadeOut(2000, ‘linear’, function () {
console.log(‘隐藏’);
});
});
$(‘button’).eq(2).click(function () {
// $(‘div’).fadeToggle();
$(‘div’).fadeToggle(2000, ‘swing’, function () {
console.log(‘切换’);
});
});
$(‘button’).eq(3).click(function () {
$(‘div’).fadeTo(2000, 0.5, ‘swing’, function () {
console.log(‘0.5’);
});
});
自定义
jq对象.animate({动画属性}, speed, easing, callback);
$(‘button’).click(function () {
$(‘div’).animate({
width: 500,
opacity: 0.1,
height: 300
}, 2000, ‘linear’, function () {
console.log(‘已完成’);
});
});
jq对象.animate({动画属性}, {options});
options:
duration: 动画时长
easing: 运动曲线
complete: 回调函数
step: 每一步的回调函数
queue: 是否队列 布尔值 true: 排队(等前面动画执行完成) false: 不排队(跟随第一个动画一起执行)
var n = 0;
$(‘button’).click(function () {
$(‘div’)
.animate({margin: 100}, 2000)
.animate({borderWidth: 100}, 2000)
.animate({
width: 500,
opacity: 0.1,
height: 300
},{
duration: 3000,
easing: ‘linear’,
complete: function () {
console.log(‘完成’);
},
step: function () {
n++;
console.log(‘当前走了’, n);
},
// queue: true
queue: false
});
});
停止动画
jq对象.stop(clearQueue, gotoEnd):
clearQueue:
false/不传: 开始下一个动画
true: 后续所有动画都清除
gotoEnd: 是否在停止的一瞬间到达本次动画的结束位置
false/不传: 在哪里停就在哪里
true: 挺值得一瞬间到达本次动画的结束位置
jq对象.finish(): 1.8+ 一次性结束所有动画并且到达目标值
$(‘button’).eq(0).click(function () {
$(‘div’).animate({
width: 1000,
height: 1000
}, 10000).animate({
opacity: 0.1
}, 10000);
});
$(‘button’).eq(1).click(function () {
// $(‘div’).stop(false, false); // 停止后下一个动画继续执行 不到达目标值,留在当前位置
// $(‘div’).stop(true, false); // 停止后后续没有动画 不到达目标值,留在当前位置
// $(‘div’).stop(true, true); // 停止后后续没有动画 到达目标值
$('div').finish();
});
循环
jq对象.map/each
jq对象.map(函数)
jq对象.each(函数)
2个形参: 第一个下标 第二个值
map: 会接受返回值组成一个新数组返回
each: 返回被操作的对象
var res = $(‘li’).map(function (i, v) {
console.log(i, v);
return 1;
});
console.log(res);
var res1 = $(‘li’).each(function (i, v) {
console.log(i, v);
return 1;
});
console.log(res1);
var arr = [1,2,3,4,5];
/*
数组.map()
第一个形参: 值 第二个形参: 下标
数组不可以使用each
*/
var r1 = arr.map(function (v, i) {
console.log(i, v);
return 2;
});
console.log(r1);
// 报错
// var r2 = arr.each(function (i, v) {
// console.log(i, v);
// return 2;
// });
// console.log(r2);
$.map/each
$.each(数据, 回调函数)
第一个形参: 下标/属性名
第二个形参: 项
$.map(数据, 回调函数)
第一个形参: 项
第二个形参: 下标/属性名
map: 会接受返回值组成一个新数组返回
each: 返回被操作的对象
var obj = {
name: ‘迪丽热巴’,
age: 33,
height: 173
};
console.log(obj);
var e1 = $.each(obj, function (key, val) {
console.log(key, val);
return 3;
});
console.log(e1);
var m1 = $.map(obj, function (val, key) {
console.log(key, val);
return val;
});
console.log(m1);
extend
浅拷贝
浅拷贝: deep: 可传可不传 不传/false默认浅拷贝
比较每一个对象的属性名, 如果属性名相同, 用后面的覆盖前面的, 如果属性名不同 拷贝到目标对象
var obj = {
name: ‘迪丽热巴’,
age: 33,
money: {
movie: ‘热火军校’,
song: ‘sugar’,
dance: ‘明日之子’
}
};
var obj1 = {
name: ‘李现’,
height: 177,
money: {
movie: ‘河神’
}
};
var o = $.extend(false, {}, obj, obj1);
console.log(o);
深拷贝
深拷贝: 第一个参数是true, 递归拷贝, 会比较每一属性名, 如果属性名相同并且属性值都是对象, 对比子属性, 如果相同, 后面的覆盖前面的, 如果不同, 直接拷贝
var o1 = $.extend(true, {}, obj, obj1);
console.log(o1);
深拷贝合集
$.extend(true, 目标对象, 拷贝对象)
// 深拷贝
var o1 = $.extend(true, {}, obj);
// console.log(o1);
// console.log(o1 == obj);
JSON.stringify: 将js数据转成json数据
JSON.parse: 将json数据转成js数据
// var s = JSON.stringify(obj);
// console.log(s);
// var o2 = JSON.parse(s);
var o2 = JSON.parse(JSON.stringify(obj));
// console.log(o2, o2 == obj);
递归拷贝: 封装递归函数实现拷贝
// 1. 函数
function deepClone(json) {
// console.log(json);
// 2. 克隆: 拷贝的是数组 创建新的数组 拷贝的是对象 创建新的对象 其他的数据 直接返回
// console.log(getType(json));
if(getType(json) == ‘Object’){
var obj = {};
} else if(getType(json) == ‘Array’){
var obj = [];
} else {
// 其他数据不做克隆和处理 直接返回
return json;
}
// 3. 存数据: 将原来数据每一个属性都存储
for(var key in json){
// console.log(key, json[key]);
// 4. 判断要存储的数据有没有数组或者对象 如果有 深拷贝 如果不是数组或对象 直接存储
// console.log(getType(json[key]));
if(getType(json[key]) == 'Object' || getType(json[key]) == 'Array'){
obj[key] = deepClone(json[key]);
} else {
obj[key] = json[key];
}
}
// console.log(obj);
// 4. 设置返回值
return obj;
}
var o = deepClone(obj);
var a = deepClone([1,2,4]);
console.log(o);
console.log(a);
使用插件
插件: 在jq基础上二次封装实现的功能性函数
百度
CSDN
swiper
fullpage
github
jq22.com
用:
\1. 找
\2. 下载
插件拓展
对象级别插件拓展
插件相当于将功能进行封装
$.fn.extend({
方法名: 函数,
方法名: 函数
});
对象级别插件使用: jq对象.方法();
$.fn.extend({
‘lunbo’: function () {
// console.log(1);
// 实现轮播功能
// 1. this: 调用方法的jq对象
console.log(this);
// 存储正确的this
var that = this;
// 2.1 假设当前是第一张
var n = 0;
// 2. 每隔3s换下一张图
setInterval(function () {
n++;
// 判断
if(n == $(that).find('li').length){
n = 0;
}
// console.log(this); // this-->window
$(that).find('li').animate({
'opacity': 0
}, {
'duration': 500
}).eq(n).animate({
'opacity': 1
}, {
'duration': 500,
'queue': false
});
// 更新小圆点
$(that).find('span').removeClass('active').eq(n).addClass('active');
}, 3000);
// 设置返回值
return $(that);
},
'drag': function () { }
});
类级别插件拓展
用类级别插件:
$.extend({
方法名: 函数,
方法名: 函数
});
调用: $.方法名();
$.extend({
getMax: function (string) {
var obj = {};
// 每个字符
for (var i = 0; i < string.length; i++) {
// split: 将字符按照分割分割成数组
var arr = string.split(string[i]);
obj[string[i]] = arr.length - 1;
}
// 找到最大次数的字符
// 用每一个字符出现的次数做对比
var max = 0;
var maxstr = '';
for (var k in obj) {
// console.log(k, obj[k]); // 字符 字符的次数
if (max < obj[k]) {
max = obj[k];
maxstr = k;
}
}
// console.log(max, maxstr);
return {
max: max,
ms: maxstr
};
}
});
Zepto
介绍
zepto专门给移动端设计的轻量级的javascript库 只针对现代高级浏览器
几乎一样 但是还有2点是不一样
官网: https://zeptojs.bootcss.com/
github: https://github.com/madrobby/zepto
\1. jq有 zepto没有: innerWidth/innerHeight outerWidth/OuterHeight
\2. offset: jq: {top: 0, left: 0} zepto: {top:0, left: 0, width: 0, height: 0}
/*
zepto专门给移动端设计的轻量级的javascript库 只针对现代高级浏览器
几乎一样 但是还有2点是不一样
*/
// 1. jq有 zepto没有: innerWidth/innerHeight outerWidth/OuterHeight
// console.log($(‘div’).innerWidth(), $(‘div’).outerWidth());
// 2. offset: jq: {top: 0, left: 0} zepto: {top:0, left: 0, width: 0, height: 0}
console.log($(‘div’).offset());
模块使用
先引入完整的zepto文件
再引入src下的模块的文件
Bootstrap
bootstrap: html和css和js的框架
官网: https://v3.bootcss.com/
注意: bootstrap的js都是基于jq基础, 先引入jq
简单使用
容器 固定布局 固定布局: 1200px 左右自带15px内边距 Document
流式布局 流式布局: 占满整个视口 左右自带15px内边距 Document
456
栅格系统 使用 认为页面都是有行与列组成, 认为一行分12列 会先化 行 row
再写 列 col–
第一个星: lg md sm xs
第二个星: 1-12数字
移动端的尺寸:
超大屏幕: > 1200px
中等屏幕: 992 < x < 1200
小屏幕: 768 < x < 992
超小屏幕: < 768
col-lg-*: 在>=1200以上堆叠排列 <1200 水平排列
col-md-*: 在>=992堆叠排列 <992 水平排列
col-sm-*: 在>=768堆叠排列 <768 水平排列
col-xs-*: 始终堆叠排列
1200以上 一行显示6个
992-1200 一行显示 4个
768-992 一行显示3个
768 一行显示2个
第一个星: lg md sm xs
第二个星: 1-12
col-lg-offset-6: >1200 向右偏移 6 个
col-md-offset-4: >992 < 1200 向右偏移4个
col-sm-offset-3: >768 <992 向右偏移3个
col-xs-offset-2: <768 向右偏移2个
col–push-:
第一个星: lg md sm xs
第二个星: 1-12
col–push-/col–pull-:
第一个星: lg md sm xs
第二个星: 1-12
table-striped: 条纹表格
table-bordered:边框
table-hover:悬停
table-responsive:响应式
# | 姓名 | 性别 |
---|---|---|
1 | 张三 | 22 |
# | 姓名 | 性别 |
---|---|---|
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
1 | 张三 | 22 |
# | 姓名 | 性别 |
---|---|---|
1 | 张三 | 22 |
如果需要帮助可以点击这里.
使用form-group添加单行
input-sm:小尺寸
col--:在不同屏幕尺寸下控制大小
北京 上海 天津 北京 上海 天津 北京 上海 天津
导航
默认
data-toggle: dropdown 控制是否显示下拉菜单
navbar-default: 默认导航
navbar-right: 放在菜单的右侧
navbar-left: 放在菜单的左侧
data-toggle: 控制元素显示的方式 modal模态框
data-dismiss: 元素消失的效果 modal模态框
通过为 .modal-dialog 增加一个样式调整类实现大小控制:
modal-lg: 大模态框
modal-sm: 小模态框
打开模态
切换模态
// open按钮 打开模态框
$(’#open’).click(function () {
$(’#my’).modal(‘show’);
});
// save按钮 隐藏模态框
$(’#save’).click(function () {
$(’#my’).modal(‘hide’);
});
// 点击change按钮 切换模态框
$(’#change’).click(function () {
$(’#my’).modal(‘toggle’);
});
菜单
下拉菜单
$(’.only’).click(function () {
console.log(1);
// 选中的是下拉的整个菜单
$(’.btn-group’).dropdown(‘toggle’);
});
事件
// 显示事件
$(’.btn-group’).on(‘show.bs.dropdown’, function () {
// do something…
console.log(‘显示’);
});
// 动画显示
$(’.btn-group’).on(‘shown.bs.dropdown’, function () {
// do something…
console.log(‘动画显示’);
});
// 隐藏事件
$(’.btn-group’).on(‘hide.bs.dropdown’, function () {
// do something…
console.log(‘隐藏’);
});
// 动画隐藏
$(’.btn-group’).on(‘hidden.bs.dropdown’, function () {
// do something…
console.log(‘动画隐藏’);
});
标签页
无动画切换
nav-tabs: 标题
id: 控制的是哪一部分 名字的显示
tab-panes: 显示的标签块
aria-controls: 当前按钮 点击切换显示的内容 tab-panes中的div的id一致
data-toggle: 切换方式 tab–标签页
home
profiles
msg
set
给默认显示的 tab-pane 加 in 类名
html
csss
js
jq
data-target: 整个轮播图最外层盒子的id
data-slide-to: 切换到第几张
data-slide: 切换方式 prev: 上一张 next: 下一张
方法 $('#id').carousel();interval: 轮播时间
pause: 划上是否停止 hover:停止 null:不停止
wrap: 是否循环播放 true: 循环 false: 不循环
$(’#my’).carousel({
interval: 2000, // 每隔2s切换下一张
pause: ‘hover’, // 划上是否停止
// wrap: false // 是否循环播放
});
// 停止轮播图
$(’.newWrap’).mouseenter(function () {
$(’#my’).carousel(‘pause’);
});
// 开始轮播
$(’.newWrap’).mouseleave(function () {
$(’#my’).carousel(‘cycle’);
});
// 切换上一张
$(‘button’).eq(0).click(function () {
$(’#my’).carousel(‘prev’);
});
// 切换下一张
$(‘button’).eq(1).click(function () {
$(’#my’).carousel(‘next’);
});
// 切换到对应下标的轮播图
KaTeX parse error: Expected '}', got 'EOF' at end of input: … console.log((this).index() - 2);
KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲my').carousel((this).index() - 2);
});
事件
// 事件
$(’#my’).on(‘slide.bs.carousel’, function () {
// do something…
console.log(‘已切换’);
});
$(’#my’).on(‘slid.bs.carousel’, function () {
// do something…
console.log(‘已切换1’);
});