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. 局限性
<div οnclick="alert('Hello World')"></div>
内嵌
行内: 事件 不推荐使用
缺点: 1. 没有实现三分离
\2. 不利于封装复用
\3. 局限性
从上到下依次执行每一个script
<script> // 代码块 alert('这是额外的弹出'); </script>
外链
外链式: script双标签 工作 推荐使用
script可以放在页面的任何位置 推荐放在body的结束标签之前
注意: 外链的script标签 不允许写内嵌代码
<script src="03.js"> alert('这是外部2'); </script> 再写一个script放内嵌代码 <script> alert('这是外部3'); </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>这是b标签</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); // 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(c); 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; // 0*8的0次 + 7*8的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(c); // 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(c); // 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')); // <div id="odiv"></div> 获取正确 console.log(document.getElementById('od')); // null 获取错误 // console.log(document.getElementbyId('od')); // document.getElementbyId is not a function: document.getElementbyId不是一个函数 拼写错误
\2. 通过tagName
语法: 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 = '<b>这是新内容</b>'; // div.innerHTML = '<b>这是新内容</b>'; // 4. 如果想要在元素内容的最后添加其他内容 不覆盖原来的内容 // 使用 原内容 + 新内容 div.innerHTML = div.innerHTML + '<b>这是新内容</b>'; // 简写 div.innerHTML += '<b>这是第二个新内容</b>';
操作属性
属性: 写在起始标签上的 除了标签名以外的都是属性
操作属性:
获取属性的值: 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(初始化变量; 循环结束条件; 变量更新){ 重复执行的代码块 } 1. 初始化变量: var 变量名 = 起始值(数字、下标); 2. 循环结束条件: 当条件为true的时候 循环可以继续执行 为false 循环结束 3. 变量更新: i++ i-- 执行时机: 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 += '<li>' + data[i] + '</li>'; }
for异种
for: 异种结构
强调: 两个分号不能省
初始化变量;
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('<br>'); }
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(c); /* 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(c); var w = getStyle(div, 'width'); console.log(w);
使用
js库: 将封装好的函数 放到一个js文件中 在后续有需要的时候 直接引入js库 调用函数
每个函数 必须要: 函数的作用 参数说明
<p>qwert</p> <!-- 1. 引入js库 --> <script src="fsy.js"></script> <!-- 2. 再写script --> <script> var p = document.getElementsByTagName('p')[0]; var w = getStyle(p, 'width'); console.log(w); </script>
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
-
保存js文件:
moment.js: 未压缩 学习
moment.min.js: 压缩 工作
-
使用
<!-- 3.1 引入公用库 --> <script src="./js/moment.js"></script> <!-- 3.2 自己的script标签 --> <script> /* format */ // 创建时间对象 var m = moment(); console.log(m); // 格式化: console.log(m.format('YYYY')); // 年 console.log(m.format('MM')); // 月 console.log(m.format('DD')); // 日 console.log(m.format('d')); // 星期 console.log(m.format('HH')); // 小时 console.log(m.format('mm')); // 分钟 console.log(m.format('ss')); // 秒 // 可以用任何格式拼接起来 document.body.innerHTML = m.format('YYYY年MM月DD日 星期d HH:mm:ss'); </script>
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('<b>123</b>'); 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位加密 133****1111 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 action=""> 姓名: <input type="text" name="username" id="" value="张三" placeholder="123"><br> 密码: <input type="password" name="password" id=""> <br> 城市: <select name="city" id=""> <option value="bj">北京</option> <option value="tj">天津</option> <option value="sh">上海</option> </select> <br> 性别: <input type="radio" name="sex" id="" value="man" checked>男 <input type="radio" name="sex" id="" value="woman">女 <br> 爱好: <input type="checkbox" name="hobby" id="">LOL <input type="checkbox" name="hobby" id="" checked>唱 <input type="checkbox" name="hobby" id="">跳 <input type="checkbox" name="hobby" id="" checked>rap <input type="checkbox" name="hobby" id="">打篮球 </form> <script> /* 1. 快速获取表单元素 */ var form = document.querySelector('form'); console.log(form); // 每个表单元素需要有name值 // 语法: form.name值 console.log(form.username); // 获取form表单的值: form.name值.value console.log(form.username.value); console.log(form.password); console.log(form.city); console.log(form.sex); console.log(form.hobby); </script>
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(c); // 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: <button οnclick="history.go(0);">刷新</button> <button οnclick="history.go(2);">前进到03</button> <button οnclick="history.forward();">前进到下一个页面</button> 02: <a href="./08 history03.html">history03</a> <button οnclick="history.back();">回退到01</button> 03: <button οnclick="history.go(-2);">回退到01</button>
事件
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: Less 快速入门 | Less.js 中文文档 - Less 中文网
使用:
插件: 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的完善文档
使用:
jquery.js: 未压缩 学习
jquery.min.js: 压缩 工作
api网站: jQuery API 中文文档 | jQuery API 中文在线手册 | jquery api 下载 | jquery api chm
<!-- 1. 引入cdn地址 --> <!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script> --> <!-- 2. 引入本地: 下载之后 --> <!-- 验证是否引入成功: $ 是否是个函数 --> <script src="js/jquery.js"></script> <script> console.log($); </script>
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); }); $(function () { console.log(5); });
冲突解决
当jq的$覆盖其他人的$
<script> var $ = 30; console.log($); </script> <script src="./js/jquery.js"></script> <script> console.log($, window.$); jQuery.noConflict(); // 将$的控制权交给其他 console.log($, window.$); console.log(jQuery, window.jQuery); // 使用自执行函数 接收jQuery为实参 $为形参 (function ($) { console.log($); })(jQuery); </script>
当别人的覆盖自己的:
<script src="./js/jquery.js"></script> <script> var $ = 30; console.log($); console.log(jQuery); // 使用自执行函数 (function ($) { console.log($); })(jQuery); </script>
对象互转
js的方法和属性只能给js对象使用 jq的方法和属性只能给jq对象使用
原生转成jq对象 $(原生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($('li')); console.log($('.box')); console.log($('#awrap')); console.log($('.box, #awrap'));
层级选择器
父 子: 后代选择器 在父元素获取所有的后代的子元素
父 > 子: 直接子元素 在父元素中获取直接包裹的第一级子元素
兄a + 弟b: 相邻兄弟选择器 获取紧跟着a选择器后面的b选择器
兄a ~ 弟b: 后面兄弟 获取a后面所有的b
console.log($('ul li')); // 6 console.log($('ul > li')); // 5 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为开头的元素 $('li[class$=b]').css('background', 'purple'); // 获取li中class属性值以b为结尾的元素 $('li[class*=b]').css('background', 'aqua'); //获取li中class属性值有b的元素 $('li[class!=box]').css('background', 'deeppink'); // 获取li中class属性值不等于box的元素
表单过滤选择器
console.log($(':input')); // 获取所有表单元素 console.log($(':input:text')); console.log($(':input:password')); console.log($(':input:radio')); console.log($(':input:checkbox')); console.log($(':checked')); console.log($(':radio:checked')); console.log($(':checkbox:checked'));
节点遍历
// 查找子节点: jq对象.children(筛选条件) console.log($('ul').children()); // 找到直接子节点 console.log($('ul').children('.box')); // 找到直接子节点 console.log($('ul').find('.box')); // 找到子节点 console.log($('ul').find('div')); // 找到子节点 // 找父节点 console.log($('.box').parent()); // 直接父节点 console.log($('.box').parents()); // 所有父节点 html // 上面的兄弟节点 prev/prevAll(筛选条件) console.log($('.box').prev()); // 紧跟的上一个 console.log($('.box').prevAll()); // 前面所有的 // 下面的兄弟节点 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($('div').prop('id')); console.log($('div').prop('class')); console.log($('div').prop('tag')); // undefined 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({
'属性名': '属性值',
'属性名': '属性值'
});
属性名: 引号可加可不加 建议加 可以使用-
属性值: 数字 加不加单位都可以
表达式 '+=' '-='
$('div').click(function () { 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($(':text').val()); console.log($(':text').val('admin')); console.log($(':radio')); console.log($(':radio:checked').val()); console.log($(':checkbox').val()); $(':radio').val(['man']); $(':checkbox').val(['smooking', 'yq']); console.log($('select').val()); console.log($('select').val('sh'));
html
共同点: 后面的会覆盖前面的
获取: jq对象.html();
可以识别标签的
设置: jq对象.html(值);
不想覆盖原内容 原内容 + 新内容
console.log($('div').text()); console.log($('div').html()); var a = $('div').html(); $('div').text('这是一个新的内容'); $('div').html('<b>这是一个新的内容</b>'); // 不想覆盖原内容 原内容 + 新内容 $('div').html(a + '<i>这是斜体</i>');
text
共同点: 后面的会覆盖前面的
获取: jq对象.text();
会获取到所有符合选择器元素的内容, 不能识别标签
设置: jq对象.text(值);
不想覆盖原内容 原内容 + 新内容
console.log($('div').text()); var a = $('div').text(); $('div').text('这是一个新的内容'); $('div').html('<b>这是一个新的内容</b>'); // 不想覆盖原内容 原内容 + 新内容 $('div').text(a + '<i>这是斜体</i>');
元素宽高
内容宽高
width(数值)
height(数值)
console.log($('div').width(), $('div').height()); // console.log($('div').width(300), $('div').height(200));
可视宽高
可视宽高: 内容 + 内边距
innerWidth(数值)
innerHeight(数值)
屏幕的可视宽高:
$(window).innerWidth(), $(window).innerHeight()
console.log($('div').innerWidth(), $('div').innerHeight()); // 340 225 // console.log($('div').innerWidth(300), $('div').innerHeight(200)); // cont(260) + 40 = 300 cont(175) + 25 = 200 // 屏幕的可视宽高 console.log($(window).innerWidth(), $(window).innerHeight());
占位宽高
占位宽高: 内容 + 内边距 + 边框
布尔: 是否包含外边距在内 false: 默认 不包含外边距margin true: 包含
outerWidth(数值, 布尔)
outerHeight( 数值, 布尔)
console.log($('div').outerWidth()); // 200 + 40 + 22 = 262 console.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($('div').offset()); // {top: 10, left: 40} console.log($('div').offset().top); // 10
滚动距离
scrollLeft()
scrollTop()
$(window).scroll(function () { 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 = $('<li>新节点</li>'); console.log(li);
添加节点
追加到父节点的末尾
父.append(子);
子.appendTo('父');
// $('ul').append(li); li.appendTo('ul');
添加到父节点的开头
父.prepend(子);
子.prependTo(父);
$('ul').prepend('<li>新1</li>'); $('<li>新2</li>').prependTo('ul');
添加到某个节点之后
参考节点.after(新节点);
新节点.inserAfter(参考节点);
$('.box').after('<li>加入1</li>'); $('<li>加入2</li>').insertAfter('.box');
添加到某个节点之前
参考节点.before(新节点);
新节点.insertBefore(参考节点);
$('.box').before('<li>before1</li>'); $('<li>before2</li>').insertBefore('.box');
删除节点
detach: 删除元素,返回被删除的元素,会保留元素原来的事件
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); $('<li>4</li>').replaceAll($('li').eq(1));
事件对象
事件对象: 当事件发生的时候 浏览器会将相关事件的信息存储在一个对象中 这个对象就叫做事件对象(鼠标位置、触发源、事件类型...)
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('<li>这是li</li>');
一次性事件 one
one: 与on方法用法一致
只能触发一次
$('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. 下载
<link rel="stylesheet" href="css/style.css"> <div class="nav"> <div class="nav_li"> <ul> <li><a href="#">Demo1</a></li> <li><a href="#">Demo2</a></li> <li><a href="#">Demo3</a></li> <li><a href="#">Demo4</a></li> </ul> </div> </div> <script src="https://www.jq22.com/jquery/jquery-1.10.2.js"></script> <script type="text/javascript" src="js/style.js"></script>
插件拓展
对象级别插件拓展
插件相当于将功能进行封装
$.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点是不一样
官网: Zepto.js: 轻量且兼容 jQuery API 的 JavaScript 工具库 | Zepto.js 中文网
\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下的模块的文件
<!-- src文件下的 zepto 禁止使用!!!! --> <!-- 先引入完整的zepto文件 --> <script src="./js/zepto.js"></script> <!-- 再引入src下的模块的文件 --> <script src="./src/touch.js"></script> <script> /* doubleTap 双击 tap, singleTap 单击 longTap 长按 swipe 滑动 swipeLeft 左滑 swipeRight 右滑 swipeUp 上滑 swipeDown 下滑 */ $('div').on('tap singleTap doubleTap swipe swipeUp swipeDown swipeLeft swipeRight', function (ev) { console.log(ev.type); }); </script>
Bootstrap
bootstrap: html和css和js的框架
注意: bootstrap的js都是基于jq基础, 先引入jq
简单使用
<!doctype html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>Bootstrap 101 Template</title> <!-- Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"> <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 --> <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 --> <!--[if lt IE 9]> <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script> <![endif]--> </head> <body> <h1>你好,世界!</h1> <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) --> <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script> <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script> </body> </html>
容器
固定布局
固定布局: 1200px 左右自带15px内边距
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css"> </head> <body> <!-- 固定布局: 1200px 左右自带15px内边距 --> <div class="container"> 123 </div> <script src="./js/jquery.min.js"></script> <script src="./bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> </body> </html>
流式布局
流式布局: 占满整个视口 左右自带15px内边距
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css"> </head> <body> <!-- 固定布局: 1200px 左右自带15px内边距 --> <div class="container"> fcghds </div> <!-- 流式布局: 占满整个视口 左右自带15px内边距 --> <div class="container-fluid"> 456 </div> <script src="./js/jquery.min.js"></script> <script src="./bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> </body> </html>
栅格系统
使用
认为页面都是有行与列组成, 认为一行分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-*: 始终堆叠排列
<div class="container"> <div class="row"> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> <div class="col-lg-1">col-lg-1</div> </div> <div class="row"> <div class="col-lg-12">col-lg-12</div> </div> <div class="row"> <div class="col-lg-3">col-lg-3</div> <div class="col-lg-3">col-lg-3</div> <div class="col-lg-3">col-lg-3</div> <div class="col-lg-3">col-lg-3</div> </div> <div class="row"> <div class="col-lg-2">col-lg-2</div> <div class="col-lg-10">col-lg-10</div> </div> </div>
兼容
处理屏幕尺寸不同显示兼容: 给一个列加多个类名
1200以上 一行显示6个
992-1200 一行显示 4个
768-992 一行显示3个
768 一行显示2个
<div class="row"> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容1</div> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容2</div> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容3</div> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容4</div> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容5</div> <div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">内容6</div> </div>
列偏移
col--offset-:
第一个星: 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个
<div class="row"> <div class="col-lg-2 col-lg-offset-6 col-md-offset-4 col-sm-offset-3 col-xs-offset-2">偏移</div> </div>
push
不会改变其他元素的位置 会形成重叠
col--push-:
第一个星: lg md sm xs
第二个星: 1-12
<div class="row"> <div class="col-xs-2 col-lg-push-6 col-md-push-3 col-sm-push-2 col-xs-push-1" style="background: pink;">col-xs-1</div> <div class="col-xs-2">col-xs-21</div> <div class="col-xs-2">col-xs-22</div> <div class="col-xs-2">col-xs-23</div> <div class="col-xs-2">col-xs-24</div> </div>
pull
不会改变其他元素的位置 会形成重叠
col--push-/col--pull-:
第一个星: lg md sm xs
第二个星: 1-12
<div class="row"> <!-- 不会改变其他元素的位置 会形成重叠 col-*-push-*/col-*-pull-*: 第一个星: lg md sm xs 第二个星: 1-12 --> <div class="col-xs-2 col-lg-push-6 col-md-push-3 col-sm-push-2 col-xs-push-1" style="background: pink;">col-xs-1</div> <div class="col-xs-2">col-xs-21</div> <div class="col-xs-2">col-xs-22</div> <div class="col-xs-2 col-lg-pull-6 col-md-pull-5 col-sm-pull-3 col-xs-pull-1" style="background: skyblue;">col-xs-23</div> <div class="col-xs-2">col-xs-24</div> </div>
列嵌套
每一个列都可以在当做一个新的行做栅格系统划分
<div class="container"> <div class="row"> <div class="col-md-4">col-md-4</div> <div class="col-md-4">col-md-4</div> <div class="col-md-4">col-md-4</div> </div> <div class="row"> <div class="col-md-4"> <div class="row"> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> <div class="col-md-1">col-md-1</div> </div> </div> <div class="col-md-4">col-md-4</div> <div class="col-md-4">col-md-4</div> </div>
表格
table: 表格
table-striped: 条纹表格
table-bordered:边框
table-hover:悬停
table-responsive:响应式
<table class="table"> <thead> <th>#</th> <th>姓名</th> <th>性别</th> </thead> <tbody> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> </tbody> </table> <table class="table table-striped table-bordered table-hover"> <thead> <th>#</th> <th>姓名</th> <th>性别</th> </thead> <tbody> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr class="active"> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr class="success"> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr class="warning"> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr class="danger"> <td>1</td> <td>张三</td> <td>22</td> </tr> <tr class="info"> <td>1</td> <td>张三</td> <td>22</td> </tr> </tbody> </table> <div class="table-responsive"> <table class="table"> <thead> <th>#</th> <th>姓名</th> <th>性别</th> </thead> <tbody> <tr> <td>1</td> <td>张三</td> <td>22</td> </tr> </tbody> </table> </div>
表单
垂直表单
使用form-group添加单行
<form> <div class="form-group"> <label for="exampleInputEmail1">中文邮箱:</label> <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email"> </div> <div class="form-group"> <label for="exampleInputPassword1">密码:</label> <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password"> </div> <div class="form-group"> <label for="exampleInputFile">选择文件:</label> <input type="file" id="exampleInputFile"> <p class="help-block">如果需要帮助可以点击这里.</p> </div> <div class="checkbox"> <label> <input type="checkbox"> Check me out </label> </div> <button type="submit" class="btn btn-default">Submit</button> </form>
水平表单
form-horizontal: 实现水平排列表单
使用form-group添加单行
<form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">Password</label> <div class="col-sm-10"> <input type="password" class="form-control" id="inputPassword3" placeholder="Password"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <div class="checkbox"> <label> <input type="checkbox"> Remember me </label> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">Sign in</button> </div> </div> </form>
内联表单
form-inline: 实现内联表单布局
<form class="form-inline"> <div class="form-group"> <label for="exampleInputName2">Name</label> <input type="text" class="form-control" id="exampleInputName2" placeholder="Jane Doe"> </div> <div class="form-group"> <label for="exampleInputEmail2">Email</label> <input type="email" class="form-control" id="exampleInputEmail2" placeholder="jane.doe@example.com"> </div> <div class="form-group"> <label for="addressInput">adress</label> <input type="email" class="form-control" id="addressInput" placeholder="beijing"> </div> <button type="submit" class="btn btn-default">Send invitation</button> </form> <form class="form-inline"> <div class="form-group"> <label class="sr-only" for="exampleInputEmail3">Email address</label> <input type="email" class="form-control" id="exampleInputEmail3" placeholder="Email"> </div> <div class="form-group"> <label class="sr-only" for="exampleInputPassword3">Password</label> <input type="password" class="form-control" id="exampleInputPassword3" placeholder="Password"> </div> <div class="checkbox"> <label> <input type="checkbox"> Remember me </label> </div> <button type="submit" class="btn btn-default">Sign in</button> </form>
表单控件大小
input-lg: 大尺寸
input-sm:小尺寸
col-*-*:在不同屏幕尺寸下控制大小
<input class="form-control input-lg" type="text" placeholder=".input-lg"> <input class="form-control" type="text" placeholder="Default input"> <input class="form-control input-sm" type="text" placeholder=".input-sm"> <select class="form-control input-lg"> <option value="bj">北京</option> <option value="sh">上海</option> <option value="tj">天津</option> </select> <select class="form-control"> <option value="bj">北京</option> <option value="sh">上海</option> <option value="tj">天津</option> </select> <select class="form-control input-sm"> <option value="bj">北京</option> <option value="sh">上海</option> <option value="tj">天津</option> </select> <form class="form-horizontal"> <div class="form-group form-group-lg"> <label class="col-sm-2 control-label" for="formGroupInputLarge">Large label</label> <div class="col-sm-10"> <input class="form-control" type="text" id="formGroupInputLarge" placeholder="Large input"> </div> </div> <div class="form-group form-group-sm"> <label class="col-sm-2 control-label" for="formGroupInputSmall">Small label</label> <div class="col-sm-10"> <input class="form-control" type="text" id="formGroupInputSmall" placeholder="Small input"> </div> </div> </form> <div class="row"> <div class="col-xs-2 col-md-3"> <input type="text" class="form-control" placeholder=".col-xs-2"> </div> <div class="col-xs-3 col-md-3"> <input type="text" class="form-control" placeholder=".col-xs-3"> </div> <div class="col-xs-4 col-md-3"> <input type="text" class="form-control" placeholder=".col-xs-4"> </div> </div>
图片
图片形状
<!-- 圆角边框 --> <!-- <img src="../day06/img/1.jpg" alt="..." class="img-rounded"> --> <!-- 圆形 --> <!-- <img src="../day06/img/1.jpg" alt="..." class="img-circle"> --> <!-- 带有边框的直角图片 --> <!-- <img src="../day06/img/1.jpg" alt="..." class="img-thumbnail"> -->
响应式图片
<img src="../day06/img/1.jpg" class="img-responsive" alt="Responsive image">
字体图标
使用过程: 新建一个空标签 复制icon的类名 直接粘贴就可以使用
<i class="glyphicon glyphicon-play"></i> <i class="glyphicon glyphicon-pause"></i> <i class="glyphicon glyphicon-hdd"></i>
导航
默认
data-toggle: dropdown 控制是否显示下拉菜单
navbar-default: 默认导航
navbar-right: 放在菜单的右侧
navbar-left: 放在菜单的左侧
<nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <a class="navbar-brand" href="#">首个菜单</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">链接 <span class="sr-only">(c当前)</span></a></li> <li><a href="https://www.baidu.com">百度</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">下拉菜单 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">下拉菜单1 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li role="separator" class="divider"></li> <li><a href="#">4</a></li> <li role="separator" class="divider"></li> <li><a href="#">5</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav>
反差色
<nav class="navbar navbar-inverse"> <!-- <button class="btn btn-default">首页</button> --> <div class="container-fluid"> <ul class="nav nav-tabs"> <li role="presentation" class="active"><a href="#">Home</a></li> <li role="presentation"><a href="#">Profile</a></li> <li role="presentation"><a href="#">Messages</a></li> <li role="presentation"> <div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> Dropdown <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div> </li> </ul> </div> </nav>
模态框
基础使用
data-target: 按钮控制的元素
data-toggle: 控制元素显示的方式 modal模态框
data-dismiss: 元素消失的效果 modal模态框
通过为 .modal-dialog 增加一个样式调整类实现大小控制:
modal-lg: 大模态框
modal-sm: 小模态框
<div class="container"> <!-- Button trigger modal --> <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#my"> Launch demo modal </button> <button id="open">打开模态</button> <button id="change">切换模态</button> <!-- Modal --> <div class="modal fade" id="my" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">这是标题</h4> </div> <div class="modal-body"> 这是内容部分 </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" id="save">Save changes</button> </div> </div> </div> </div>
事件
// 显示事件 $('#my').on('show.bs.modal', function (e) { console.log('显示'); }); // 动画显示完成后触发 $('#my').on('shown.bs.modal', function (e) { console.log('显示'); }); // 隐藏事件 $('#my').on('hide.bs.modal', function (e) { console.log('隐藏'); }); // 动画隐藏完成后 $('#my').on('hidden.bs.modal', function (e) { console.log('隐藏'); });
方法
$('#id').modal();
// open按钮 打开模态框 $('#open').click(function () { $('#my').modal('show'); }); // save按钮 隐藏模态框 $('#save').click(function () { $('#my').modal('hide'); }); // 点击change按钮 切换模态框 $('#change').click(function () { $('#my').modal('toggle'); });
菜单
下拉菜单
<div class="dropdown"> <button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown trigger <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dLabel"> <!-- 具体菜单展示的内容 --> <li>html</li> <li>css</li> <li>js</li> <li>jq</li> </ul> </div>
上拉菜单
<div class="dropup"> <button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Dropdown trigger <span class="caret"></span> </button> <ul class="dropdown-menu" aria-labelledby="dLabel"> <!-- 具体菜单展示的内容 --> <li>html</li> <li>css</li> <li>js</li> <li>jq</li> </ul> </div>
按钮式下拉菜单
<!-- Single button --> <div class="btn-group"> <a class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Action <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div>
分裂下拉菜单
<!-- Split button --> <div class="btn-group"> <a class="btn btn-danger" href="https://www.baidu.com">跳转链接</a> <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <span class="caret"></span> <span class="sr-only">Toggle Dropdown</span> </button> <ul class="dropdown-menu" id="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div>
方法
$().dropdown('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--标签页
<div> <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">Home</a></li> <li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">Profile</a></li> <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">Messages</a></li> <li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">Settings</a></li> </ul> <!-- Tab panes --> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="home">home</div> <div role="tabpanel" class="tab-pane" id="profile">profiles</div> <div role="tabpanel" class="tab-pane" id="messages">msg</div> <div role="tabpanel" class="tab-pane" id="settings">set</div> </div> </div>
透明度显示和隐藏
给tab-pane 加 fade 类名
给默认显示的 tab-pane 加 in 类名
<div> <!-- Nav tabs --> <ul class="nav nav-tabs last" role="tablist"> <li role="presentation" class="active"><a href="#html" aria-controls="html" role="tab" data-toggle="tab">html</a></li> <li role="presentation"><a href="#css" aria-controls="css" role="tab" data-toggle="tab">css</a></li> <li role="presentation"><a href="#js" aria-controls="js" role="tab" data-toggle="tab">js</a></li> <li role="presentation"><a href="#jq" aria-controls="jq" role="tab" data-toggle="tab">jq</a></li> </ul> <!-- Tab panes --> <div class="tab-content"> <div role="tabpanel" class="tab-pane fade in active" id="html">html</div> <div role="tabpanel" class="tab-pane fade" id="css">csss</div> <div role="tabpanel" class="tab-pane fade" id="js">js</div> <div role="tabpanel" class="tab-pane fade" id="jq">jq</div> </div> </div>
方法
$('.last a').click(function (e) { e.preventDefault(); $(this).tab('show'); });
事件
$('a[data-toggle="tab"]').on('show.bs.tab', function (e) { console.log(e.target); // 即将出现的标签页 console.log(e.relatedTarget); // 即将消失的标签页 }); $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { console.log(e.target); // 即将出现的标签页 console.log(e.relatedTarget); // 即将消失的标签页 }); $('a[data-toggle="tab"]').on('hide.bs.tab', function (e) { console.log(e.target); // 即将出现的标签页 console.log(e.relatedTarget); // 即将消失的标签页 }); $('a[data-toggle="tab"]').on('hidden.bs.tab', function (e) { console.log(e.target); // 即将出现的标签页 console.log(e.relatedTarget); // 即将消失的标签页 });
轮播图
data-ride: 元素块的功能 carousel: 轮播
data-target: 整个轮播图最外层盒子的id
data-slide-to: 切换到第几张
data-slide: 切换方式 prev: 上一张 next: 下一张
<div id="my" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <!-- 小圆点 --> <ol class="carousel-indicators"> <li data-target="#my" data-slide-to="0" class="active"></li> <li data-target="#my" data-slide-to="1"></li> <li data-target="#my" data-slide-to="2"></li> <li data-target="#my" data-slide-to="3"></li> </ol> <!-- Wrapper for slides --> <!-- item: 轮播图的每个页面 --> <div class="carousel-inner" role="listbox"> <div class="item active"> <img src="../day06/img/1.jpg" alt="..."> <div class="carousel-caption"> 内容1 </div> </div> <div class="item"> <img src="../day06/img/2.jpg" alt="..."> <div class="carousel-caption"> 内容2 </div> </div> <div class="item"> <img src="../day06/img/3.jpg" alt="..."> <div class="carousel-caption"> 内容3 </div> </div> <div class="item"> <img src="../day06/img/4.jpg" alt="..."> <div class="carousel-caption"> 内容4 </div> </div> </div> <!-- Controls --> <!-- 左右箭头 --> <a class="left carousel-control" href="#my" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#my" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div>
方法
$('#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'); }); // 切换到对应下标的轮播图 $('.num').click(function () { console.log($(this).index() - 2); $('#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'); });