1.remainder 求余运算符 % 返回两个数相除得到的余数const remainder = 11%3;只要用%就行
2.在 JavaScript 中,可以通过在引号前面使用反斜杠(\)来转义引号。
const sampleStr = "Alan said, \"Peter is learning JavaScript\".";
3.
\' 单引号
\" 双引号
\\ 反斜杠
\n 换行符
\r 回车符
\t 制表符
\b 退格
\f 换页符
4.pop()是取出第最后数组,.shift()是取出第一个数组,而.unshift()是在数组头部加一个数组,b.push(a),在数组b里面添加a,a.slice(a, b) 截取数组以a开始,以b结束的数组,【a数组虽然被截取,但是原a数组不变】.splice(a,b,c,d)删除数组,两个参数,a是从索引为a的开始删除,b是删除b个数组,后面的参数是在索引为a后面加上c,d。
const threeArr = [1, 4, 6];
const oneDown = threeArr.pop();
console.log(oneDown);
console.log(threeArr);
第一个 console.log 将显示值 6,第二个将显示值 [1, 4]
console.log(threeArr .slice(2, 3)); 结果为6;
4.1.indexOf('a'),检查是否有a这个数组,没有返回-1,有就会返回数组的索引,同时也可以在字符串中使用,indexOf('a',3),从下标为开始查找.lastIndexOf(),跟indexOf一样是从后往前面寻找
(1)Math.max(...arr) 取出数组中最大的值
5.对象和 arrays 类似,区别在于数组使用索引来访问和修改数据,而对象中的数据是通过 properties 访问的
去对象中的值有.方法与[]的方法,有空格的属性必须用[]
例:object.name 或 object['name'],若name属性字符之间有空格,必须用[],在[]中的属性必须要用引号引起来
6.对象写法,在属性是一个字符时,引号可以省略,若多个字符,之间有空格,引号不能省略。
7.删除属性delete.myDog.name删除了myDog的name属性。
8.查找对象是否具有name这个属性.hasOwnProperty('name')有就返回true。
9.return Math.random()。可以用 Math.random() 生成一个在0(包括 0)到 1(不包括 1)之间的随机小数。 因此 Math.random() 可能返回 0,但绝不会返回 1
Math 对象
Math.floor(数字) 向下取整,获得它最近的整数,向上取整: Math.ceil(数字);
Math.max(),Math.min(),取最大值与最小值乘方(几次方)
Math.pow(x,y); 计算x的y次方
开方: Math.sqrt(数字); 计算开平方
四舍五入: Math.round(数字) 饥渴读取到四舍五入结果 只能四舍五入第一位小数,只要不够0.5 全部舍弃 //PI 圆周率:3.1415926...
11.生成的随机数是在两个指定的数之间。Math.floor(Math.random() * (max - min + 1)) + min
12.parseInt() 函数解析一个字符串返回一个整数:const a = parseInt("007"); a为7
Date时间对象
时间对象的创建 new Date
13.1时间对象的操作
get/setFullYear 时间对象.getFullYear(); 获取整年 时间对象.setFullYear(); 设置时间对象的年份 get/setMonth() 时间对象.getMonth() 获取月份 时间对象.setMonth() 设置月份 注意:在js中月份的操作 是按照0-11 进行计数的
get/setDate 时间对象.getDate() 获取日期 时间对象.setDate() 设置日期 getDay 时间对象.getDay() 获取周几 周日值为0 从周一到周六为0--6
getHours/setHours 时间对象.getHours() 获取小时 时间对象.setHours() 设置小时 getMinutes/setMinutes 时间对象.getMinutes() 获取分钟数 时间对象.setMinutes(分钟) 设置分钟 getSeconds/setSeconds 时间对象.getSeconds() 获取秒数 时间对象.setSeconds(秒) 设置秒 getTime 时间对象.getTime() 获取时间戳 得到的是一个数字到 1970年1月1日00:00:00 的时间差,单位为ms setTime 时间对象.setTime(时间戳) 根据时间戳来设置时间
Date.parse
- 将时间字符串转换为时间戳,进行排序
-
<p id="demo">单击按钮显示给定日期与1970年1月1日的毫秒数:</p> <button onclick="myFunction()">点我</button> <script> function myFunction(){ var d = Date.parse("March 21, 2022"); var x = document.getElementById("demo"); x.innerHTML=d; }
13.2 原生对象的格式化写法
时间对象.toDateString() 获取时间对象日期部分
时间对象.toTimeString() 获取时间对象时间部分
时间对象.toString() 获取时间对象所有部分
时间对象.toLocaleDateString() 获取时间对象本地日期部分
时间对象.toLocaleTimeString() 获取时间对象本地时间部分
时间对象.toLocaleString() 获取时间对象本地所有部分
<p id="demo">单击按钮以字符串来显示时间。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
var d = new Date();
var x = document.getElementById("demo");
x.innerHTML=d.toLocaleString() ;
}
</script>
字符串对象String
1.1模型字符串``用反引号,好处:
(1)换行不报错
(2) 可以直接在字符串内解析变量
var a =18;
var b = `我今年${a}`
console.log(b);
//可以直接输出我今年18,
等同于 var b = '我今年'+a+''
var a =18;
var b = var b = '我今年'+a+''
//注意这个地方在字符串拼接的时候,
//必须外面是单引号,内部也是单引号,外部是双引号,内部也是双引号
console.log(b);
1.2indexOf('a'),检查是否有a这个数组,没有返回-1,有就会返回数组的索引,同时也可以在字符串中使用,indexOf('a',3),从下标为开始查找.lastIndexOf(),跟indexOf一样是从后往前面寻找
indexOf('a'),检查是否有a这个数组,没有返回-1,有就会返回数组的索引,同时也可以在字符串中使用,indexOf('a',3),从下标为开始查找.lastIndexOf(),跟indexOf一样是从后往前面寻找
2.substring 与slice截取字符串 substr(开始坐标,截取多少个)(包含开始坐标)
2.1 相同之处:subString(初始下标,结束下标) slice(初始下标,结束下标)
作用:截取字符串 从起始下标开始截取 到结束下标结束 注意:可以取到起始下标 取不到 结束下标
2.2不同之处:
2.21.如果 起始下标 和结束下标 传入的顺序颠倒了 substring会自动将顺序调整好 slice 不会调整顺序 因此 截取出现问题
2.22.如果传参的时候 传入负数 substring 会将传入的负数参数转化为 零 slice会先给负数参数 +字符串.length 用加完值大于零 用加完的值 替换原参数 如果加完之后 值仍小于 零 就直接将 该参数归零 slice更适合高端玩家
2.3截取整个字符串的用法 字符串.substring/slice(0) 表示0 为起始下标 不传结束下标 表示从0开始一直截取完整个字符串
3.字母转换大小写
str.toLowerCase(); 大写转换为小写 str=str.toUpperCase(); 小写转换为大写
4.split()
字符串的切割方法 split str.split('切割标识'); 从开始,每次遇到切割符就切一刀,返回值为切割后的数组。 【切割后是数组,也是字符串转换成数组的方法】
str.split('切割标识',n); n为数字,如果长度小于切割后数组的实际长度,多出的舍弃,如果长度大于切割后数组的长度,则按照实际长度。
5.字符串的替换 replace str.replace('旧字符片段','新字符片段'); 新字符片段代替旧字符片段
6.去除字符串两端空格的方法 trim 用法:字符串.trim() 作用:去除字符串两端的空格 " abc " 这个方法一般用在 注册页面
7. ,includes()查找字符串有没有某个值,方法:正则,【indexof,includes()】这两个区分大小写
includes()方法:includes() 方法用于判断字符串是否包含指定的子字符串,如果找到匹配的字符串则返回 true,否则返回 false。
注意: includes() 方法区分大小写。
var a='hello word';
var b =a.includes("llo");
console.log(b);//返回true
数组对象Array
1.pop()是取出第最后数组,.shift()是取出第一个数组,而.unshift()是在数组头部加一个数组,b.push(a),在数组b里面添加a,a.slice(a, b) 截取数组以a开始,以b结束的数组,【a数组虽然被截取,但是原a数组不变】.splice(a,b,c,d)删除数组,两个参数,a是从索引为a的开始删除,b是删除b个数组,后面的参数是在索引为a后面加上c,d。
2.删除重复数组方法
var arr = [1,2,3,3,3,4,4,8,0,8,9];
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]===arr[j]){
arr.splice(i,1);
}
}
}
console.log(arr);
3.选择排序
3.1
var arr = [1,3,2,5,8,4,7];
// 从小到大
//循环数组arr
for(var i = 0;i < arr.length;i++){
//循环当前项后面的所有项
for(var j = i+1;j < arr.length;j++){
//比较 后面有比当前项小的就交换
if(arr[i] > arr[j]){
var a=arr[j]; //通过索引进行赋值
arr[j]=arr[i];
arr[i]=a;
}
}
}
console.log(arr);
3.2 sort()排序方法
数组.sort(); 注意:按照数字对应的ASCII码值 进行排序 // 数组.sort(function(a,b){return a-b/b-a}); 作用:升序或降序排列数组
<p id="demo">单击按钮升序排列数组。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
var points = [40,100,1,5,25,10];
points.sort(function(a,b){return b-a});//进行降序
var x=document.getElementById("demo");
x.innerHTML=points;
}
</script>
4.join将数组拼接成字符串
arr.join()将数组变成字符串,但是之间有逗号,arr.join(" ")没有逗号,没空格所有字符串连在一起arr.join(" "),没有逗号,用空格隔开
arr.join(' ').split(),将数组变成没有中括号也没逗号的数组
5.数组进行反转arr.reverse();
特殊:arr.join().split().reverse()【join与split括号里面必须有引号,并且引号内容相同才能反转】
解决:把reverse()写在最前面:arr.reverse().join().split()
6.indexOf寻找数组中是否存在改参数,用法与字符串一样
7.slice 截取数组
a.slice(a, b) 截取数组以a开始,以b结束的数组,【a数组虽然被截取,但是原a数组不变】
8. concat 将多个数组拼接在一起
var txt1 = ['hello' ,1];
var txt2 = "world!";
var n=txt1.concat(txt2);
n输出为[ 'hello',1,'word'],输出形式为数组,也可以合并字符串
总结:两个字符串拼接,结果为字符串,一个数组与字符串拼接,输出为数组,数组也可以与对象拼接,但是对象不能与对象拼接
9.filter 过滤器
数组.filter(function(item,index){ return 条件判断; });
var ages = [32, 33, 16, 40];
var a=ages.filter(function (age) {
return age >= 18;
});
console.log(a) //输出a为[32, 33, 40],但是ages还是[32, 33, 16, 40]
10.map
- 自动循环每一个数组项 给每一个数组项都 *10 乘完之后将得到的结果作为数组项 拼成一个新数组,将新数组返回出来
数组.map(function(item,idx){ return item*10; });
var ages = [32, 33, 16, 40];
var a=ages.map(function (age) {
return age /10;
});
console.log(a) 输出[3.2, 3.3, 1.6, 4.0]
11.forEach
数组.forEach(function(item,idx){ //直接写入对数组或数组项的操作 就可以直接对数组进行操作 console.log(item); console.log(idx); });
标准浏览器: 事件对象.preventDefault()
12. if(i in arr)
if(i in array){//判断array数组第有没有第i项或者第i项是不是为空
initValue=array[i];
i--;
break;
}
-> IE 低版本: 事件对象.returnValue = false
1. 阻止鼠标右键单击行为
window.oncontextmenu = function (e) {
// 阻止默认行为
e.preventDefault()
console.log('右键单击了')
}
阻止默认行为发生:
标准浏览器: 事件对象.preventDefault()
-> IE 低版本: 事件对象.returnValue = false
函数内的this指向
this 指向
+ 官方: 指当前代码执行的上下文环境(context)
+ 私人:
=> 就是一个使用在作用域内(全局/函数内)的关键字
=> 全局作用域 this
-> 在全局作用域内, this 就是 window (特指前端 JS)
=> 函数作用域 this(熟读并背诵全文)
-> 定义: 不管函数在哪定义, 不管函数怎么定义, 只看函数的调用方式(箭头函数除外)
1. 普通调用
=> 函数名()
=> 函数内的 this 指向 window
2. 对象调用
=> 对象名.函数名()
=> 函数内的 this 指向 点前面的全部内容
3. 事件处理函数
=> 事件源.on事件类型 = 函数
=> 事件源.addEventListener('事件类型', 函数)
=> 函数内的 this 指向 事件源(绑定在谁身上的事件)
4. 定时器处理函数
=> setTimeout(函数, 数字)
=> setInterval(函数, 数字)
=> 函数内的 this 指向 window
5. 自调用函数
=> (函数)()
=> 函数内的 this 指向 window
6. 箭头函数
=> () => {}
=> 函数内的 this 是该箭头函数外部作用域的 this
=> 唯一一个不看调用看定义决定 this 的,不会被call(),apply(),bind()改变this指向
强行改变 this 指向(熟读并背诵全文)
+ this 指向是因为函数的调用而出现的
+ 在本次调用函数的时候, 改变函数内的 this 指向
1. call()
+ 语法: 直接连接在函数后面使用
=> 函数名.call()
=> 对象名.函数名.call()
+ 参数:
=> 第一个参数: 函数内的 this 指向
=> 第二个参数开始: 依次给是该函数的实参
+ 特点: 立即调用函数
2. apply()
+ 语法: 直接连接在函数后面使用
=> 函数名.apply()
=> 对象名.函数名.apply()
+ 参数:
=> 第一个参数: 函数内的 this 指向
=> 第二个参数: 是一个数组或者伪数组类型都可以, 内部每一个数据按照顺序是该函数的实参
+ 特点: 立即调用函数
+ 特殊作用: 改变函数传递参数的方式
3. bind()
+ 语法: 直接连接在函数后面使用
=> 函数名.bind()
=> 对象名.函数名.bind()
+ 参数:
=> 第一个参数: 函数内的 this 指向
=> 第二个参数开始: 依次给是该函数的实参
+ 特点: 不会立即调用函数, 而是返回一个新的函数, 新函数内的 this 被锁定死了
+ 特殊作用: 改变那些不会被立即调用的函数的 this
*/
事件抛出
var div1=document.querySelector(".div1");
div1.addEventListener("click",clickhandler);
var div3=document.querySelector(".div3");
// 冒泡抛发
var evt=new MouseEvent("click",{bubbles:true});
div3.dispatchEvent(evt);
function clickhandler(e){
console.log(e)
}
ES6
1.let与var的区别:let 关键字的行为类似,但有一些额外的功能。 在代码块、语句或表达式中使用 let 关键字声明变量时,其作用域仅限于该代码块、语句或表达式,不能作为全局变量,而var在代码块、语句或表达式中定义可以作用与全局,都能调用。例如:
var printNumTwo;
for (var i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo())
console。log(i);结果为3 和3。因为赋值给i的值已经更新
------------
var printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
console.log(i) 结果为2和i is not defined。
let与const具有暂时性死区,
在块级作用域内用let 或const在块级作用域定义了后,将把这个作用域封住,不在访问全局变量
var a=1;
function fn1(){
console.log(a);
let a=2 //会报错而不是undefined
}
fn1()
2.let与const的区别:const在定义了之后不能够重新赋值。
例如const s = [5, 6, 7];
s = [1, 2, 3];
s[2] = 45;
console.log(s);输出的只能是[5, 6, 45]而let可以显示出[1,2,45]
3.Object.freeze( ) 这个函数也会保证定义的对象不会被重新赋值,也不能给对象添加属性
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);
obj.age=18;
console.log(obj); //会报错
4.箭头函数:func(){}可以写成()=>{ },当函数有参数的时候const doubler = (item) => item * 2;只有一个参数的时候括号可以省略item=>item*2;
const increment = (number, value=1) => number + value;
//给函数 increment 传入默认参数,使得在 value 没有被赋值的时候,默认给 number 加上 1。
5.解构 解构数组与对象
5.11解构数组
var arr=[1,2,3,4,5,6]
var [a,b,c,d,e,,f]=arr//a就等于1相当于var a=arr[0]
...
var [a,...b] =arr //a为1,b为[2,3,4,5,6]
5.12解构多维数组
const arr = [100, 200, [300, 400, [500, [600, 700, [800, [900]]]]]]
var [a, b, [c, d, [e, [f, g, [h, [i]]]]]]=arr
console.log(i)//就是输出900
5.13数组用于函数传参
function fn(a,b){
console.log(a,b) //打印出1,2
}
var arr=[1,2];
fn(...arr)
集合为数组
function fn(...arr){
console.log(arr)
}
fn(1,2,3,4);//打印出[1,2,3,4],因为打印的是arr,...arr是1,2,3,4而arr是一个数组
输出嵌套数组
function fn(...arg){
console.log(arg)
}
fn([1,2,3,4])[[1,2,3,4]];
对象的...
function fn(...obj){
console.log(obj)
}
fn({a:1,b:2});//输出[{a:1,b:2}]
5.2.1解构对象 特点:按key解构,不用按照顺序
const obj = { day: 10, hours: 12, minutes: 13, seconds: 14 }
const { day, hours, minutes, seconds }=obj //相当于const day=obj.day
console.log(hours)//输出12
//注意:可以给重新赋值
const { day:d, hours, minutes, seconds }=obj//这就是把day改为d,相当于const d=obj.day
5.22多维对象解构
const obj = {
name: 'Jack',
age: 18,
gender: '男',
info: {
weight: 180,
height: 180,
address: {
city
},
hobby: [ '篮球', '足球', [ '游泳', '健身' ] ]
}
}
const {
name, //相当于var name=obj.name
age:a, //相当于 var a=obj.age ,给重新赋值了
gender:g,
info: {
weight:w,
height,
address: {
city
},
hobby
}
}=obj
console.log(a) //输出18
console.log(hobby)//输出一个数组[ '篮球', '足球', [ '游泳', '健身' ] ]
//若想解构对象中的数组,先把数组整体解构出来,拿到这个数组在进行解构
var [a,b,[c,d]]=hobby;
console.log(c)//就会输出游泳
5.2.3 解构不起别名会覆盖前面的
var obj={a:1,b:{a:2,b:{a:3}}};
var {a,b:{a,b:{a}}}=obj;
console.log(a) //打印出来是3
5.24 赋初始值
var obj={a:1,b:2};
// 赋值初始值
var {a,b,c=3}=obj;
console.log(a,b,c)
//打印出1,2,3,其中3是c的初始值,若在obj中有c:4,就会把初始值覆盖
例如
var obj={a:1,b:2,c:4};
// 赋值初始值
var {a,b,c=3}=obj;
console.log(a,b,c)//1,2,4.c的初始值将会被覆盖
var obj={a:1,b:{b:{a:3}}};
var {a,b:{a:a1=10,b:{a:a2}}}=obj;
console.log(a,a1,a2); //1,10,3 //因为对象中没有a1,但是有赋初始值,10
5.25 对象解构传参
function fn({a,b}){
console.log(a,b);
}
var obj={a:1,b:2};
// 填参时,如果使用...语法,在这里默认按照数组解构或者迭代器解构(对象不属于迭代器,因此不能解构)
// fn(...obj); //报错,不能直接...对象,可以在{}里面...对象
fn({...obj});
5.26对象传参解决 穿实参时候只传一个,但是形参是带二个赋值的
//对象解构不是按位解构,所以不区分先后顺序
function fn({a,b}){
console.log(a,b);
}
fn({b:3});//所以只传一个b参数会传递给形参的第二个,也就是b
//问题二
function fn({a,b=5}={a:1,b:2}){
console.log(a,b);
}
fn();//1,2
fn({a:10});//传入参数就会把函数初始值{a:1,b:2}给覆盖掉,但是b=5不会覆盖
// 如果没有传参 a=1 b=2;
// 传参{a:10} a=10 b=5
严格模式
用法:在script标签最上方写入严格模式 "use strict";
1.严格模式时,变量必须定义后才能赋值,如果没有定义,但是使用window赋值属性,这个变量等同于定义
a=1
conlose.log(a)//在严格模式下会报错
2.严格模式的时候函数的参数不能相同
function fn(a,a){
// 参数名不能相同
console.log(a);
}
fn(3,5); //严格模式下会报错
3.with 方法 with 只将对象中存在的属性,进行修改,如果不存在设置为全局变量
var div=document.createElement("div");
document.body.appendChild(div);
div.style.width="50px";
div.style.height="50px";
div.style.backgroundColor="red";
with(div.style){
width="50px";
height="50px";
backgroundColor="red";
} //都可以加上,因为style对象中都有这些属性
例二:
var obj={a:1,b:{c:2,d:3}};
with(obj.b){
c=10;
d=20;
e=30;
}
console.log(obj,e); 会把obj.b中的c改成10,d改成20,但是e在obj.b中没有,所以会把e定义到全局中去,就相当于在全局中 var e=30
4.严格模式与非严格模式对于作用域的问题
严格模式时,不能定义相同同名函数
严格模式如果块语句中只有一个函数,块语句外的变量为快外定义的变量值
非严格模式时,块语句中只有一个函数时,块语句外的变量为最后一个同名函数上面的赋值
如果严格模式时出现多个同名函数,将会报错
如果非严格模式时,块外的值是最后一个同名函数上面的赋值
5. 删除对象属性,不能删除不可删除的属性
var arr=[1,2,3];
delete arr.length;
6.严格模式下不允许使用8进制,不能使用arguments.callee (自身函数),arguments.callee.caller(自身函数的上一个函数)
7. eval eval 反射 将字符串反射为变量或者表达式
8.非严格模式时,this执行window严格模式时this为undefined
function fn(){
console.log(this)//非严格模式时,this执行window
// 严格模式时this为undefined
}
fn()
argments
1.arguments.callee 当前函数 与arguments.callee.caller回调当前函数外的上下文环境的函数
例子:
function fn(){
console.log(arguments.callee) n 函数体
console.log(arguments.callee.caller);fn1函数体
}
function fn1(){
fn();
}
fn1(); //打印fn 函数体 与 fn1函数体
2.回调函数中,如果直接执行参数函数,那么在回调函数中的this执行window或者undefined
function fn(f){
f();
}
function fn1(){
// console.log(this);//window || undefined(严格模式)
}
fn(fn1);
3.如果使用arguments[下标]() 这种使用arguments调用回调函数方法后,回调函数中this执行这个
function fn(f){
arguments[0]();
}
function fn1()
console.log(this);//回调当前函数的上下文环境函数的arguments
}
fn(fn1);
模块化语法
+ 利用自己本身语法规则, 在自己的文件内引入一个其他文件
当你需要按照模块化语法进行开发的时候(前提)
+ 当前页面的 script 标签需要有一个 type 属性, 值设置为 module
=> 只有这样, 浏览器在解析该 js 语句的时候, 才会按照模块化语法进行解析
+ 当前页面必须在服务器上打开, 本地打开不能使用模块化语法
模块化语法的规则
+ 当你开始使用模块化语法的时候
+ 每一个 js 文件都将会变成一个独立的 js 文件, 互相之间没有任何联系和关系
=> 文件与文件之间互相不共通
=> 我们管每一个独立文件叫做一个 文件作用域(模块作用域)
+ 当你需要互通数据的时候
=> 需要用到 导入导出 语法
导出的语法
+ 在当前自己文件内, 把某些内容向外暴露
+ 语法1:
=> export default 数据结构
+ 语法2:
=> export 数据
导入的语法
+ 在当前自己文件内, 把某些文件导入进自己内部(目的: 为了使用该文件内暴露的信息)
+ 语法1:
=> import 变量名 from 文件名
+ 语法2:
=> import { } from 文件名
+ 注意:
=> 导入语法1 只能导入 导出语法1 的内容
=> 导入语法2 只能导入 导出语法2 的内容
Set() 与 WeakSet() 弱引用集合
重点:强引用与弱引用区别:
- 强引用:变量赋值以后,变量所指向的内存空间的引用计数+1
- 弱引用:变量赋值以后,变量所指向的内存空间的引用计数不变
1.Set() Map HashMap KeyValue键值对存储映射
优点 : 松散结构,添加删除速度快,没有顺序,不能排序,查找速度快
不能使用for in 和for遍历 有专门的迭代器遍历方法 for of
不存储相同的数据,没有重复
语法:
var s=new Set();
// s.add(3); 添加 s.has(3)判断是否有,没有返回false, s.delete(3)删除元素 s.size()看下set集合 s.clear()清除集合
1.2.for of仅能用于迭代器对象遍历,对象不行 例子 for(value of s)
2.WeakSet() 弱引用集合
优点:有利于垃圾回收,防止堆栈上限溢出
因为是弱引用类型,在引用的时候引用计数不变,只要把初始的对象改成null,WeakSet()集合中的对象也会变成null,但是强引用类型不行
例子:
const wset = new WeakSet();
var frank = {
uname:{ temp:"abc" }
};
wset.add(frank.uname);
console.log(frank); //正常输出temp:"abc"
console.log(wset); //正常输出temp:"abc"
//变成null
frank = null; //只是把对象改成null
console.log(frank); //null
console.log(wset); // 里面也没值了,若是Set()的话把frank=null,他里面还是存了temp:"abc",
//因为在强引用的时候引用计数加一了
Map() 与WeakMap()
1.map() 作用就是点击这个盒子可以控制另一个,因为他存储的对象是一个对象是key,另一个对象是value,每个键值对存的是两个对象:,不一定是对象,可以是获取的两个不同的dom元素,让是key,的控制是value的dom元素
用法:var m=new Map(); 创建一个Map()
var o1={a:1} var o2={a:2} var o3={a:3}; var o4={a:4};
增加:m.set(o1,o2)
获取:m.get(o1)//o2
删除:m.delete(o1)
清空:m.clear()
判断是否存在:m.has(o1)
在遍历的时候:
//1.遍历key与value
for(var [key,value] of m){
console.log(key,value)
}
//m.entries() 获取所有keyvalue键值对形成的迭代器
for(var [key,value] of m.entries()){
console.log(key,value)
}
//两个是一样的
//2.遍历key
m.keys() 获取所有key形成的迭代器
for(var key of m.keys()){
console.log(key)
}
//3.遍历value
//m.values() 获取所有value形成的迭代器
for(var value of m.values()){
console.log(value)
}
2.WeakMap()弱引用类型
var o1={a:1};
var o2={a:2};
var m=new WeakMap();
m.set(o1,o2);
console.log(m) //若外部o1变成null,WeakMap()里面的o1也为null
try {} catch(err){}
例子
try{
var arr=[1,2,3,4,5];
arr.forEach(t=>{
console.log(t)
if(t===3) throw new Error("aaa");
})
}catch(error){
console.log("bbb")
} //输出123bbb 如果 console.log(error)的话会打印出aaa
promise 与 async/await
// 使用async/await获取成功的结果
// 定义一个异步函数,3秒后才能获取到值(类似操作数据库)
function getSomeThing(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('获取成功')
},3000)
})
}
async function test(){
let a = await getSomeThing();
console.log(a)
}
test(); // 3秒后输出:获取成功
生成器函数
例子:
function *fn(a,b){
yield a;
yield b;
a+=10;
b+=100;
yield a;
yield b;
var s=a+b;
yield s;
return s;
}
var g=fn(5,6); //先传入参数5,6给ab会一次一次执行
console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
日常总结
5.数组 .slice(a, b) 截取数组以a开始,以b结束的数组
console.log(array.slice(2, 3));
6.typeof查看变量类型,但是用typeof来查看数组或者对象类型的时候,都返回Object,没办法区分,所以可以用instanceof,或者用Object.prototype.toString.call(obj),返回一个字符串
[object Object]
例:
const a=[1,2,3,4];
const b ={
name:"kerwen"
};
const c='11111'
console.log( b instanceof Object); 【返回true】 判断的是b.__proto__是否在Object.prototype 上
console.log(typeof c) 【返回string】
7.isNaN 判断传入的数据转换为数字之后 是不是NaN.
isNaN('字符串') // 是数字或者浮点类型 :false 不是数字:true
8.转换成字符串a.toSring(),或者用a.join(""),区别是后者把数组转字符串的时候可以去掉逗号。还一种隐式转换,number+'字符串',整体类型变成字符串。
var a=10;
(1)a.toString(2);a为1010,转换成二进制的字符串
(2)var a =[0,1,2];
var c=a.join('') ; 为012,而用toString()则返回0,1,2
对象
1.Object.keys( 对象名),把对象
2.split("")把一个字符串分割成字符串数组:引号之间有空格或者没空格区别
没有空格,将会把每个单词都拆分,有空格按照空格进行拆分
第二个参数split(" ",3)拆分后只显示3个
3.反转字符串的方法
str.split('').reverse().join('');先把字符串分割,然后倒序拼接成一个新的字符串
4.str.endsWith('a')检测str字符串最后一个字符是不是a,是返回true,不是返回false
5. .repeat():使字符串重复几次
例:var str = "Runoob";
str.repeat(2); 输出RunoobRunoob
6.var a = [11,2,3,4,5]; //定义数组
var s = a.join(","); //指定分隔符
console.log(s.split(',').reverse().join(' '));
console.log(s)
7.str.charAt(下标)字符串
var str="012345";
str.charAt(2);//返回2;相当于str[2];
8.定时器
8.1延迟定时器 setTimeout,与清除延迟定时器clearTimeout
- 延迟指定的时间之后,执行的代码
- 延迟时间以毫秒(ms)为单位,1s=1000ms
- 定时器函数的返回值 被我们称为定时器ID
-
var myTime=setTimeout(founction(){延迟的代码},2000)//设置定时器 clearTimeout(myTime)//清除延迟定时器
8.2 间歇定时器 setInterval,与清除间歇定时器clearInterval
- 每个指定的时间间隔 执行一次函数中的代码
- 间歇时间以毫秒(ms)为单位,1s=1000ms
- 定时器函数的返回值 被我们称为定时器ID
-
var mytime=setInterval(function(){延迟代码段},延迟时间)//设置间歇定时器 clearInterval (mytime) //清除间歇定时器
DOM
DOM简介
1.1 DOM 文档对象模型
-
帮助我们操作html文档
-
封装了许多函数,这些函数可以帮助我们操作html文档
-
是针对 HTML 和 XML 的一个API,开发者可以通过DOM来操作HTML文档或者XML文档
-
API Application Programming Interface 应用程序接口 接口就是方法函数
-
XML 可拓展标记语言,但没有单标签,所有标签都需要用户自定义
1.2 DOM 操作html
- 会将html的结构抽象化为 DOM树状结构,这个结构中存在很多节点
- DOM操作html其实是通过操作节点实现的
1.3 DOM的节点
节点的分类
- 标签节点:html中的标签被抽象化为 DOM中的标签节点
- 属性节点:html中的属性
- 注释节点:html中的注释
- 文本节点:html中的文本
示例
1.styleSheets[a].cssRules[b],表示第a个style里面的b+1个样式
2.getPropertyValue() 方法返回指定的 CSS 属性的值,与getComputedStyle 获取计算过的样式。
(1)getPropertyValue(),可以返回Css样式的属性值。 例如:
<style>div{ color:red
}</style>
function myFunction() {
var declaration = document.styleSheets[0].cssRules[0].style;//取的0个style里的第一个样式
var propvalue = declaration.getPropertyValue("color"); //就会获取到color的属性值就是red
alert(propvalue); //弹出red
}
(2)getComputedStyle 获取计算过的样式
<p>点击按钮计算 DIV 的背景颜色。</p>
<p><button onclick="myFunction()">点我</button></p>
<div id="test" style="height: 50px;background-color:red;">测试 DIV</div>
<p>计算值为: <span id="demo"></span></p>
<script>
function myFunction(){
var elem = document.getElementById("test");
var theCSSprop = window.getComputedStyle(elem).getPropertyValue("background-color");
//就会计算出红色的rgb()值
document.getElementById("demo").innerHTML = theCSSprop;
}
</script>
(3)setProperty() 方法用于设置一个新的 CSS 属性,同时也可以修改 CSS 声明块中已存在的属性
function myFunction() {
var declaration = document.styleSheets[0].cssRules[0].style;
//定义为第一个style里面的第一个样式
var setprop = declaration.setProperty("background-color", "yellow");
}//给第一个style里面的第一个样式,添加了个背景颜色
节点 Node
区别:
- 文档节点,表示的是整个html
- 元素节点,表示的是html中的标签
- 属性节点,表示的是html标签中的属性
- 文本节点,表示的是html标签中的内容文本
-
<p>hello word </p> //hello word是文本节点,p是标签节点
4.childNodes获取自子节点
- text 文本节点
- comment 注释节点
- // 获取子节点 childNodes 含(文本节点、注释节点) 父节点.childNodes[0],或者用父节点.childNodes.item(0) 来获取父节点的第几个孩子;
5.节点的特性
5.1nodeType 节点的类型
父节点.childNodes[0].nodeType来获取
得到的值为 标签节点 : 1 属性节点 : 2 文本节点 : 3 注释节点 : 4
5.2 nodeName 节点名称
节点.nodeName 文本节点 : #text 注释节点 : #comment 标签节点 : 大写标签名
5.3 nodeValue 节点内容(主要针对文本节点)
// 节点的值 nodeValue 主要针对于文本节点 // 可以修改 文本节点 注释节点 值 // 标签节点不可以使用 nodeValue的值
获取 : 节点.nodeValue 设置 : 节点.nodeValue = '节点内容值';
获取节点
1.获取子节点:父节点.childNodes[0],获取第一个子节点;
父节点.childNodes获取父元素所有子节点(含有文本节点与注释节点)
2.父节点.children 获取父元素中所有的子标签节点
3.获取父节点 parentNode与offsetParent
3.1parentNode 子节点.parentNode 获取子元素的直接父节点
3.2 offsetParent 子节点.offsetParent
- 获取到 带定位的父节点
- 如果直接父节点没有定位,就继续往上层查找,直到body
4.获取兄弟节点
4.1 previousSibling
节点.previousSibling
- 获取 上一个 兄弟节点
- 在IE中表示获取上一个兄弟元素
4.2nextSibling 获取下一个兄弟节点
节点.nextSibling
- 获取 下一个 兄弟节点
- 在IE中表示获取下一个兄弟元素
4.3previousElementSibling (IE不兼容)
节点.previousElementSibling
- 获取 上一个 兄弟元素节点
4.4.
nextElementSibling (IE不兼容)
节点.nextElementSibling
- 获取 下一个 兄弟元素节点
5.其他节点
5.1firstChild
节点.firstChild
- 获取第一个节点
- 在IE中表示 获取第一个元素节点
5.2lastChild
节点.lastChild
- 获取最后一个节点
- 在IE中表示 获取最后一个元素节点
5.3firstElementChild (IE不兼容)
节点.firstElementChild
- 获取 第一个元素节点
5.4
lastElementChild (IE不兼容)
节点.lastElementChild
- 获取最后一个元素节点
改变样式
自定义类名
ele.setAttribute('data-gx', 100) //类名必须加data-,要不找不到
console.log(ele.dataset.gx) //会把自定义类名都存到dataset的数据中
2. 获取行内样式:元素.style.样式名
获取非行内样式 :window.getComputedStyle(要获取样式的元素).样式名
例如:window.getComputedStyle(ele)['background-color']
3. 设置元素样式(只能设置行内样式)
// 语法: 元素.style.样式名 = 样式值
// ele.style.backgroundColor = 'red'
改变非行内样式:
function css(obj,attr,value){ //对象,样式,值。传2个参数的时候为获取样式,3个是设置样式
if(arguments.length == 2){ //arguments参数数组,当参数数组长度为2时表示获取css样式
return getStyle(obj,attr); //返回对象的非行间样式用上面的getStyle函数
}else{
if(arguments.length == 3){ //当传三个参数的时候为设置对象的某个值
obj.style[attr] = value;
};
};
};
4.通过类名改变样式
改变类的方式
classList
+ 每一个 元素节点 身上自带一个属性叫做 classList
+ 是一个类似数组的数据结构, 存放的是该元素的所有类名
+ 增删改查都是对 classList 的操作, 给出专用的 api
+ 增: 元素.classList.add(类名)
+ 删: 元素.classList.remove(类名)
+ 切换: 元素.classList.toggle(类名)
-> 原先有就删除, 原先没有就增加
.div {
width: 100px;
height: 100px;
background-color: pink;
}
.active {
width: 200px;
height: 200px;
background-color: skyblue;
border-radius: 50%;
}
<div class="div"></div>
ele.onclick = function () {
ele.classList.toggle('active')
}//点击切换.active类,有就删了,没有就添加
操作节点
创建一个 "筐" - 文档碎片
// 语法: document.createDocumentFragment( ),括号不用写参数
1.创建元素节点 createElement();
- document.createElement('标签名');
- 创建指定标签名的 标签节点
- 1文本节点 (没什么卵用)
createTextNode();
- document.createTextNode('文本内容');
- 创建指定标签名的 标签节点
2.添加元素节点 appendChild()
- document.appendChild(要添加的子节点);
- 将要添加的子节点 追加到 父元素的末尾
- 如果追加的子节点 原本就存在于,就会产生物理位移,移动到父元素的后面。
-
<p id="demo">单击按钮创建文本节点。</p> <button onclick="myFunction()">点我</button> <script> function myFunction(){ var t=document.createElement("button"); document.body.appendChild(t); }; </script>
createElememt与appendChild一起使用,只能放在父元素最后面
3.插入元素节点 insertBefore(),insertAdjacentHTML
- 3.1 insertBefore()
- document.insertBefore(新节点,旧节点);
- 将要添加的子节点放到 旧节点的前面
- 如果追加的节点 原本就存在,就位产生物理位移,移动到父元素的后面。
-
<ul id="myList"><li>Coffee</li><li>Tea</li></ul> <p id="demo">单击按钮插入一个项目列表</p> <button onclick="myFunction()">点我</button> <script> function myFunction(){ var newItem=document.createElement("LI") //创建一个li的元素节点 var textnode=document.createTextNode("Water")//创建一个文本节点water newItem.appendChild(textnode) //把water放进li里面 var list=document.getElementById("myList") // 把Ul赋值为list list.insertBefore(newItem,list.childNodes[0]); //把<li>water</li>放进ul中的第一个 } </script>
3.2insertAdjacentHTML(参数1,参数2) 优点可以这直接插入html字符
-
参数1:指定位置:
beforebegin
:在当前元素节点的前面。afterbegin
:在当前元素节点的里面,插在它的第一个子元素之前。beforeend
:在当前元素节点的里面,插在它的最后一个子元素之后。afterend
:在当前元素节点的后面。-
参数2:是要插入的节点
-
<div> </div>//在div内插入li const li='<li><span>hello word</span><li>' div.insertAdjacentHTML(afterbegin,li) //这样就直接能插入到div里面
-
4.删除节点
4.1删除自身 remove()
- 节点.remover();
- 移除自己
4.2 删除子节点 removeChild()
- 节点.removeChild(指定子节点)
- 移除指定的子节点
5.修改节点
5.1替换子节点 replaceChild()
- 父元素.replaceChild(新子节点,旧子节点)
- 使用新子节点 替换旧 子节点
5.2克隆节点 cloneNode()
-
节点.cloneNode() 浅拷贝
-
直接克隆得到的是原标签 不包含内容
-
节点.cloneNode(true) 深拷贝
-
带上 true 就可以带内容克隆
6.获取节点新方法
6.1querySelector
document.querySelector('选择器');
- 如果满足条件的节点有多个 就选择第一个
6.2querySelectorAll
document.querySelectorAll('选择器');
- 选中所有满足条件的元素,返回值为一个数组 () 里面可以写标签,也可以写.class,#id.
- 注意得到是一个数组,在调用某个的时候需要。
- var x = document.querySelectorAll("p");
x[2].style.backgroundColor = "red"; //这是第三个p标签样式改变
7.DOM操作节点属性
获取节点的属性: 元素.属性名 设置节点属性值: 元素.属性名 = 属性值 不能操作 元素的非自带属性 自定义属性。 // 可以操作非自带属性和自定义属性 //
document.getElementsByTagName("p")[0].style.color="red"; //属性值需要加引号
getAttribute 得到指定的属性值 元素节点.getAttribute('指定的属性名称')
document.getElementById("demo").innerHTML=a.getAttribute("target");
//获取到a标签中target的属性值为_blank
// setAttribute 设置属性值 元素节点.setAttribute('指定的属性名称','指定的属性值')
document.getElementsByTagName("p")[0].setAttribute("style","color:red");
//添加的属性是style,而不是color
//removeAttribute 删除节点属性
元素节点.removeAttribute('属性名');
document.getElementsByTagName("H1")[0].removeAttribute("style"); //删除的是style
8.DOM操作表格
8.1// 获取表头 表格元素.tHead // 获取表格底部 表格元素.tFoot
alert(document.getElementById('myTable').tFoot.innerHTML)
8.2获取表格主体 //
tBodies 获取到的是一个数组包含表格中的所有表格主体 表格元素.tBodies[下标]
8.3获取行 表格元素.rows // 获取表格中所有行 表格元素.tBodies[n].rows // 获取tbody的所有行 // 获取列 表格元素.rows[n].cells // 我们只能获取某一行中的所有列
9.DOM操作表单
9.1获取表单元素
- form.表单元素name名
-
<form> <input type="text" name="username" value="内容"> </form> <script> var form = document.querySelector('form'); console.log(form.username.value); </script>
9.2表单元素的事件
9.2.1 form 元素的专属事件
onsubmit 提交事件 当表单提交的时候触发 return false 阻止表单提交
onreset 重置事件 当表单重置的时候触发
<form onreset="myFunction()">
输入您的名字: <input type="text">
<input type="reset">
</form>
<script>
function myFunction() {
alert("表单已重置");
}
</script> //在输入名字点击重置,会触发onreset事件,弹出一个弹窗
9.22 input 元素的专属事件
onfocus 获得焦点
onblur 失去焦点
9.3表单元素的方法
9.31form元素的方法
submit 表单元素.submit() 提交表单
reset 表单元素.reset() 重置表单
<script>
function myFunction(){
document.getElementById("qw").reset(); //获取的id必须是form的,不可以是input
}
</script>
</head>
<body>
<form id='qw'>
Email: <input type="text" id="email" value="someone@example.com">
</form>
<button type="button" onclick="myFunction()">选取内容</button>
</body> //点击按钮就会重置
9.32 input的方法
focus input.focus() 让input获取焦点
blur input.blur() 让input失去焦点
select input.select() 将input中的内容选中
<script>
function myFunction(){
document.getElementById("email").select(); //id必须是input的,不能加在form
}
</script>
</head>
<body>
<form>
Email: <input type="text" id="email" value="someone@example.com">
</form>
<button type="button" onclick="myFunction()">选取内容</button>
</body> //点击按钮输入框的内容会全被选中
BOM
1.BOM简介
- BOM --> Browser Object Model
- 浏览器对象模型 提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。
- 浏览器对象模型 不依赖任何html内容 可以独立操作浏览器
1.1 window对象的系统对话框
alert
- window.alert('提示信息');
- window 可以省略
console.log
- window.log('打印信息');
- window 可以省略
confirm
- window.confirm('询问信息');
- 弹出询问窗口 确定返回值为true 取消返回值为false
-
<p>点击按钮,显示确认框。</p> <button onclick="myFunction()">点我</button> <p id="demo"></p> <script> function myFunction(){ var x; var r=confirm("按下按钮!"); if (r==true){ x="你按下了\"确定\"按钮!"; } else{ x="你按下了\"取消\"按钮!"; } document.getElementById("demo").innerHTML=x; } </script> //点击按钮将弹出“按下按钮的对话框”,你点击确定页面显示你按下了确定按钮, //点取消页面显示你按下了取消按钮
prompt
- window.prompt('询问信息');
- 弹出一个带输入框的询问窗口 用户可以在输入框中输入内容 并选择确定或取消
- 用户点击确定, 返回值为输入的内容 如果点取消返回值为null
-
<p>点击按钮查看输入的对话框。</p> <button onclick="myFunction()">点我</button> <p id="demo"></p> <script> function myFunction(){ var x; var person=prompt("请输入你的名字","Harry Potter"); if (person!=null&& person!=""){ x="你好 " + person + "! 今天感觉如何?"; document.getElementById("demo").innerHTML=x; } } //点击按钮,将会弹出一个对话框,内容是上面是标题"请输入你的名字", //下面是一个输入框内容是"Harry Potter"。你点击确定页面会出现:你好Harry Potter!今天感觉如何?
1.2 window的open和close方法
-
open
- open(url,name,features,replace) 打开一个新的浏览器窗口
- url 要打开的页面地址
- features 设置新窗口大小
- replace 是否替换历史记录 true/false
- open('https://www.baidu.com','_blank','width=300px,height=300px',false)
- 如果open写在行内,必须加window
-
close
- close()
- 关闭当前页面
-
<script> function openWin(){ myWindow=window.open("","","width=200,height=100"); myWindow.document.write("<p>这是'我的窗口'</p>"); } function closeWin(){ myWindow.close(); } </script> //点击第一个按钮将打开空白网页,上面写着‘这是‘我的窗口’’页面宽高,很小,打开方式是_blank //点击第二个按钮页面将会关闭
2 BOM 重要对象
-
2.1 location
-
location = url 跳转页面
-
location.reload(true) 无参 刷新页面 true强制刷新 跳过本地缓存从服务器获取
-
<script> function reloadPage(){ location.reload(true) } </script> //点击刷新页面
-
location.href 获取整个URL(常用)
-
location.search 返回参数(常用)
-
<script> document.write(location.search); </script> //返回URL的查询部分。假设当前的URL就是http://www.runoob.com/submit.htm?email=someone@ //example.com: //返回值为?email=someone@example.com,是参数
-
location.host 返回域名 wwww.xxxx.xx:xxxx
-
https://www.runoob.com:8001/try/try.php?filename=tryjsref_loc_hrfe返回的是红色的,带端口号
-
location.hostname 不带端口号的 www.xxxx.xx
https://www.runoob.com:8001/try/try.php?filename=tryjsref_loc_hrf,返回的是红色的,不带端口号
-
location.port 返回端口号,如果没有返回空字符串
-
location.pathname 返回路径
-
https://www.runoob.com:8001/try/try.php?filename=tryjsref_loc_hrfe
-
location.hash 返回片段 #后的内容 常见于链接锚点
-
//返回一个 URL 的主要部分。假设当前的 URL 是 http://www.runoob.com/test.htm#PART2: document.write(location.hash); //以上实例输出结果:#part2
-
location.protocol 获取协议
2.2 history
- history对象 与浏览器历史交互,包含用户访问过的url
history.back() 相当于点击后退功能
history.forward() 相当于点击前进功能
history.go(非零数字) -1 后退一个页面,1 前进一个页面
function goBack(){
window.history.go(-2)
}//点击按钮将会后退两页
2.3 navigator
navigator.appCodeName 浏览器代号 所有浏览器代号 都是mozilla
navigator.appName 浏览器名称 标准浏览器都是 netscape IE8以下浏览器值为 microsoft Internet Explorer
navigator.appVersion 浏览器版本
navigator.platform 硬件平台
navigator.userAgent 用户代理
navigator.cookieEnabled 是否启用cookie true启用 false禁用
3 BOM 操作元素大小和位置的三大系列属性
3.1 client系列
// 获取元素大小
元素.clientWidth 获取元素的宽度 获取到的是数值
元素.clientHeight 获取元素的可视高度 获取到的是数值 可视宽高: 自身宽高+padding (不包含 border 和 margin )
// 获取边框
元素.clientLeft 获取上边框宽度
元素.clientTop 获取上边框高度
注意:以上都是只读属性
3.2 offset系列
// 获取元素大小 元素.offsetWidth 获取元素的占位宽 获取的是数值 元素.offsetHeight 获取元素的占位高 获取的是数值 占位宽高: 自身宽高+padding+border (不包含 margin)
// 获取元素位置 没有带定位的父元素 就以页面为基准 元素.offsetTop 当前元素距离 第一个带定位的父级顶部 的距离 元素.offsetLeft 当前元素距离 第一个带定位的父级左侧 的距离(只是一个只读属性,不能赋值)
// 获取带有定位的父亲 元素.offsetParent; 获取带有定位离自己最近的父元素
获取的是一个[object HTMLBodyElement]:是Body
// 页面被卷去的头部和标签不同 window.pageYOffset 是指页面滚动的距离,【以上都是只读】
window.scrollBy(10, 100); 页面在x轴与Y轴滚动的距离
3.3 scroll系列
// 如果内容超出,为真正内容大小
元素.scrollHeight 获取元素的实际内容宽度 【只读】
元素.scrollWidth 获取元素的实际内容高度 是指页面内容的总高度,有滑轮,就是整个滑轮能滑到的距离,包含padding,不包含margin与border(与client包含范围一样)
// 被卷去的距离 可以设置也可获取
元素.scrollTop 被卷去的头部(上滑的距离)
元素.scrollLeft 被卷去的左边(左滑的距离)
3.4 获取屏幕的可视宽高
- 获取屏幕的可视宽高 其实就是获取 html标签的可视宽高
- // 获取html标签 document.documentElement
- // html的可视区域 (支持 IE7 以上) document.documentElement.clientWidth /
-
document.body.clientWidth 获取浏览器所有的宽度不只是可视化
- / 获取body标签 document.body
- // html的可视区 ( IE7 以下) document.body.clientWidth 不兼容的原因是IE7 以下 document.documentElement 不能获取html标签
总结:
//浏览器bom可视化高度
window.innerHeight//包含滚动条
document.documentElement.clientHeight //dom可视化高度不包含滚动条
document.documentElement.scrollTop||document.body.scrollTop//浏览器卷去的高度:
//元素自身高度
元素.offsetHeight //包含border
元素.clientHeight//元素自身的高度不包含border
//到定位父元素之间的距离
元素.offsetTop
-
4 BOM 相关事件
- 滚动条滚动事件
- onscroll 当滚动条发生滚动的时候 触发这个事件 可视窗口大小改变事件
- onresize 当可视窗口大小发生变化的时候 触发这个事件 响应式布局的底层原理就是resize事件
浏览器滚动到
+ 语法: window.scrollTo()
+ 两种参数方式
+ 第一种: 传递数字
=> window.scrollTo(x, y)
-> x 表示横向位置
-> y 表示纵向位置
=> 注意: 必须传递两个参数, 一个报错
=> 特点: 只能瞬间定位, 不能平滑滚动
+ 第二种: 传递对象
=> window.scrollTo({
top: yyy,
left: xxx,
behavior: 'smooth'
})
=> 默认是瞬间定位, 需要一个 key 叫做 behavior 来决定是平滑滚动
5.浏览器的本地储存
cookie localStorag sessionStorage
5.1cookie
存储特点
1. cookie 是按照域名存储的
=> 本地打开的页面是无法存储 cookie 的必须在服务器打开
=> 哪一个域名存储的 cookie 哪一个域名使用
2. cookie 的存储大小
=> 4KB 左右
=> 50条 左右
3. cookie 的存储都是字符串, 有自己的固定格式
=> 'key=value; key2=value2; key3=value3'
4. cookie 的存储是有时效性的
=> 默认时效性是 会话级别
=> 我们可以手动设置过期时间
5. cookie 的通讯相关
=> 在前后端交互的时候
=> 会在每一次和后端的 "对话" 中自动携带 cookie
6. 操作权限
=> 前后端都可以操作 cookie
设置一条基本的 cookie
+ 语法: document.cookie = 'key=value'
+ 注意: 一次只能设置一条, 设置的默认就是 会话级别 的时效性
设置一条带有时间的cookie
var time = new Date('2022-3-2 11:35:30')
document.cookie = 'a=100;expires=' + time
设置多少时间删除cookie的方法
function setCookie(key, value, expires) {
// // 1. 判断 expires 参数是否传递了
if (expires) {
// // 2. 设置时间对象
var time = new Date()
time.setTime(time.getTime() - 1000 * 60 * 60 * 8 + 1000 * expires)
}
document.cookie = `${ key }=${ value };expires=${ time }`
}
// // 将来我们使用的时候
setCookie('a', 100, 30)
setCookie('b', 200, 30)
5.2浏览器的本地存储 - storage
存储特点
1. 前后端操作
=> 只能由前端操作
=> 任何后端语言不能操作
2. 存储位置
=> 浏览器本身
3. 通讯相关
=> 不能自动携带
4. 存储大小
=> 20M 左右
5. 时效性是不可设置的
=> localStroage 是永久存储
=> sessionStorage 是会话存储
6. 存储格式
=> 按照键值对存储, 但是只能存储字符串类型的数据
=> 如果你存储的是其他类型的数据, 会自动帮你转换成字符串存储
7. 操作 API
=> 一套自己完整的操作语法
设置
window.localStorage.setItem('a', 100)
删除;
window.localStorage.removeItem('a')
获取 console.log(window.localStorage.getItem('a'))
清空(所有的):window.localStorage.clear()
sessionStorage
+ 跨页面通讯能力
+ 只有当前页面跳转的才可已使用(在一个标签卡里面可以使用)
面试题
+ 解释一下 cookie localStorage sessionStorage session 的区别
+ session 是一个后端的存储空间
+ cookie / localStorage / sessionStorage 的区别
1. 存储大小
=> cookie: 4KB 左右
=> stroage: 20M 左右
2. 通讯相关
=> cookie: 随请求自动携带
=> storage: 不会自动携带
3. 操作相关
=> cookie: 操作复杂, 没有 api, 前后端都可以操作
=> storage: 操作简单, 有 api, 只能前端操作
4. 存储格式
=> cookie: 字符串格式
=> storage: 键值对
5. 时效相关
=> cookie: 默认是会话级别, 可以手动设置
=> storage: localStorage 就是永久, sessionStorage 就是会话, 不可更改
+ localStorage 和 sessionStorage 的区别
1. 跨页面通讯能力
=> lcoalStorage 随便跨页面
=> sessionStorage 只能是本页面跳转可以通讯
2. 时效性
=> localStorage 就是永久
=> sessionStorage 就是会话
+ localStorage 和 sessionStorage 的共同点
=> 不能存储其他数据类型, 只能存储字符串类型数据
=> 如果一定要存储其他数据类型, 转换成 json 格式存储
var obj={name:'jake'}
window.sessionStorage.setItem('a', JSON.stringify(obj))
*/
事件高级
1 事件对象
- 在Js中每一个事件,都有一个事件对象 这个对象是用来记录当前时间的相关信息的
1.1 获取事件对象的方式
标准浏览器 : 在事件处理函数中使用 window.event 就可得到事件对象
谷歌和IE:直接使用 window.event
火狐 : 元素.onclick = function(ev){ ev就会接收到事件对象 } 兼容处理: 元素.onclick = function(ev){ var event = window.event||ev; }
clientX/Y : 获取当前鼠标 相对于可视窗口的位置 pageX/Y : 获取当前鼠标 相对于页面顶部和左侧的距离
target/srcElement : 表示当前添加事件的元素 // target 是标准浏览器使用 // srcElement 是IE10及以下使用
type : 事件类型(事件名)
altKey ctrlKey shiftKey : 三分属性的值都是布尔值,表示事件触发的时候 是否按住了alt ctrl shift键如果按住了,值为true
1.2 事件绑定
- on方式添加事件 不能给同一元素添加多个同类事件
- 事件绑定可以绑定多个
- / 标准浏览器 元素.addEventListener('事件类型',function(){ // 事件处理函数 });
- // IE8及以下浏览器 元素.attachEvent('on事件类型',function(){ // 事件处理函数 })
1.3 DOM事件流
addEventListener('事件名',function(){},true)
- DOM 事件流 就是Js中事件执行的一个流程,分为三个阶段
-
1.3.1 事件捕获
- window --> document --> html --> body --> .... --> 触发事件的元素
- 事件捕获就是从最顶级的元素(window)开始,向实际触发事件的元素进行一层一层的捕获,这个过程中 事件会从上到下进行传递,事件在传递的过程中 如果某一元素也有同类事件就会一并触发
- 如果传入true 事件执行捕获阶段,传入false 执行冒泡阶段,默认false
- 时间冒泡与捕获的设置是在父元素设置,但是作用于子元素,
-
var x=document.getElementById('btn1'); x.addEventListener('click', dem) var z=document.getElementById('div'); z.addEventListener('click', dem1,true) //z是父元素,x是子元素,此时点击z,只弹出word,点击x将会先弹出word,再弹出hello //因此设置flase与true在父元素设置,影响的是子元素是冒泡还是捕获
1.3.2 确定目标
- 就是事件流中 找到了 实际触发事件的元素 将该 元素的事件触发
1.3.3 事件冒泡
- 触发事件的元素-->...--> body --> html --> document --> window
- 事件冒泡就是从实际触发事件的元素开始 向实际触发的元素开始,向window 进行一层一层的事件传递,传递过程中 如果某一元素也有同类事件就会一并触发
- 标准浏览器: 事件对象.stopPropagation();
-
function dem (event){ alert("hello"); event.stopPropagation();}//阻止事件冒泡,加在子元素的函数中
- //停止传播 不能继续冒泡 有兼容性问题 IE浏览器:
- // e.cancelBubble; //低版本浏览器 不是方法 是属性
- // e.cancelBubble = true; 阻止冒泡
1.4 事件解绑(取消)
// 标准浏览器 元素.addEventListener('click',fn); function fn(){事件处理函数}
// IE浏览器 元素.detachEvent('on事件类型',fn); function fn(){事件处理函数}
// on方式添加的事件移除方式 元素.on事件类型=null;
1.5 取消事件的默认行为
- 在js中 很多时间都有默认行为,例如点击事件,a标签默认为跳转
- 取消默认行为的方法
- / 标准浏览器: 事件对象.preventDefault(); 方法
- // 低版本浏览器 e.returnValue; 属性
- // e.returnValue = false;
- // on方式添加的时间: return false;
-
a href="http://www.baidu.com" id="testA" >baidu.com</a> var a = document.getElementById("testA"); a.onclick =function(e){ if(e.preventDefault){ e.preventDefault(); }else{ window.event.returnValue = false;//IE //注意:这个地方是无法用return false代替的 //return false只能取消元素 } } //写if条件是因为考虑到低版本浏览器不兼容的问题
1.6 键盘和滚轮相关事件
1.6.1 键盘类事件
键盘抬起事件 keyup 键盘抬起以后触发
// 键盘按下 keydown 键盘按下时候触发 /
/ 键盘按下抬起后触发 keypress 不能识别功能键 ctrl shift 左右箭头
键盘类事件的事件对象
key : 键盘值 用换下的键对应的值
keyCode : 键盘码 用户按下按键对应的键盘值 对应Unicode编码 // a-z 99-127
<p>在输入框中输入键盘上的字符获取按下字母的 Unicode 字符代码。</p>
<input type="text" size="40" onkeypress="myFunction(event)">
<p id="demo"></p>
<script>
function myFunction(event) {
var x = event.keyCode;
document.getElementById("demo").innerHTML = " Unicode 值为: " + x;
}
</script>//输出一个输入框,在输入框输入键盘上的按键,显示按键的keycode
. 组合按键
+ 每一个键盘事件对象内有四个信息
=> altKey
=> ctrlKey
=> shiftKey
=> metaKey(win: win 键, mac: command)
+ 以上四个按键的值都是 布尔值, true 表示按下, false 表示没有按下
if (e.ctrlKey && e.keyCode === 65) {
console.log('您按下的是 ctrl + a')
}
1.6.2 滚轮事件
mousewheel 只适用于谷歌
DOMMouseScroll 只适用于火狐浏览器 只能使用addEventListener绑定
// 在IE中不兼容(因为addEventListener在IE中不能使用)
// 兼容处理 function bindWheel(ele,fun){ ele.onmousewheel = fun; if(ele.addEventListener!=UNDEFINED){ ele.addEventListener(DOMMouseScroll) } }
// 滚轮的滚动方向 mousewheel : 事件对象中的 wheelDelta 如果向下滚动 值为负值,如果向上滚动值为正数。 DOMMouseScroll : 事件对象中的 deltail 如果向下滚动 值为正值,如果向上滚动值为负数。
绑定离开当前页面的事件 visibilitychange
参数:
visible 表示可见 hidden 表示不可见
例子:
document.addEventListener('visibilitychange', () => {
// 7-2. 判断是可见还是不可见
// document 身上有一个属性叫做 visibilityState 可视状态
// visible 表示可见
// hidden 表示不可见
if (document.visibilityState === 'hidden') clearInterval(timer)
if (document.visibilityState === 'visible') autoPlay()
})
}
1.7 事件委托
事件委托就是利用事件冒泡机制指定一个事件处理程序,来管理某一类型的所有事件。
即:利用冒泡的原理,把事件加到父级上,触发执行效果。
// 事件委托的思路
1.给子元素绑定的事件,绑定给共同的父元素。
2.事件处理函数中,判断当前实际触发事件的元素是否是子元素
3.如果是子元素 就执行形影的操作 如果不是 就不做任何操作
// 事件委托的优势
1.可以在最大限度上 节省性能
2.可以使后续追加的元素 也具备事件效果
全局捕获
1 捕获
2 回调函数
- ie低版本浏览器有效
-
元素.setCapture();
- 给某一元素设置全局捕获
- 假设元素添加了点击事件,不论点击整个文档的任何位置 点击事件都会被捕获,到添加了全局捕获的元素身上 来触发
-
1.2 释放捕获
元素.releaseCapture();
- 给某一元素释放全局捕获
- 释放掉之前添加在元素身上的捕获
- 当一个函数 作为实参 出入另一个函数时,我们就说这个函数时一个回调函数。
正则表达式
贪婪匹配
1.?是搜索后面的字符是什么,lan? 就会搜出所有和后面的字符,是因为la后面不确定是什么,就用?代替n可以是0次或者1次
2.*是搜索有0个或多个字符ab*c 是指ac之间有0个或者多个b的都能筛选出来,例如ac,abbbbbbc,abbc,而若ac之间有一个不是b的就没法筛选,例abdc,这样你发就不行
3.+ 是搜索有1个或多个字符,与*不同的是0个不能搜索,上面例子ac就筛选不出来
4.{}是搜索字符出现的几次,ab{5}c,是搜索abbbbbc,ab{1,5}c,是搜索b出现1到5次的,ab{2,}c,搜索b出现两次以上
5.若是不是搜索b而是ab可以把ab括起来就是搜ab了,(ab)+,(ab)*,等上面的符号都可以
6.|或运算符,a (cat|dog) 就会搜索错, a cat 与 a dog来。
7.[],搜索用什么字符组成字符串,例[a-z]+搜索所有小写字母组成的字符串,有大写,和数字不行,[a-z A-Z 0- 9]+是搜索有所有大小写字母加数字组成的字符。
8.^除了在中括号里的字符,由其他字符组成的字符,例[^a-z]+就是搜索除了由小写字母组成的字符,里面有一个小写字母都不行,但是包括换行符
元字符
1.\d数字字符等同于[0-9]
2.\D非数字字符
3.\w单词字符,所有英文字符加数字加下划线
4.\W非单词字符
5.\s空白府(包含Tab和换行符)
6.\S非空白字符
7. .*包含任意字符,就不包含换行符 \.
8.^ 匹配行首,^a搜索字符是a的字符
9.$ 匹配行尾 , a$搜索字符行是a的字符
零宽断言
?=用法
exp1(?=exp2):查找exp1后面是exp2的exp1。
?<=用法
(?<=exp2)exp1:查找 exp1前面是exp2的exp1。
?!用法
exp1(?!exp2):查找后面不是 exp2 的 exp1。
?<!用法
(?<!exp2)exp1:查找 exp1前面不是exp2的exp1。
元字符 - 重复元字符
1. \1 \2 \3 \4 \5 \6 \7 \8 \9
+ 重复出现
+ 需要第 n 个 () 出现的内容一模一样
+ 注意: 不是重复几次, 是重复第几个小括
问题: 如何区分第几个小括号 ?
+ 在正则内按照 小括号开始 数数
const reg = /^((ab|cd)|(hh|mm))\2$/ //从左到右第二个小括号是左边那个
console.log(reg.test('abab')) //true
console.log(reg.test('cdcd')) //true
console.log(reg.test('hh')) //true
console.log(reg.test('mm')) //true
贪婪匹配----懒惰匹配
贪婪限定符
=> *
=> +
=> ?
=> {n,}
=> {n,m}
+ 非贪婪限定符
=> *?
=> +?
=> ??
=> {n,}?
=> {n,m}?
1.<.+?>懒惰匹配
例子<span><b>This is a sample text</b></span>,用<.+?>,搜会只搜出<span><b></b></span>
若不加问号,则会全部搜出来会搜出<span><b>This is a sample text</b></span>
例子:搜索ip:\b((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)\b
10. test(),与match()方法
let waldoIsHiding = "Somewhere Waldo is hiding in this text.";
let waldoRegex = /Waldo/;
let result = waldoRegex.test(waldoIsHiding);
console.log(result);//输出true,若没有这个输出false
let twinkleStar = "Twinkle, twinkle, little star";
let starRegex = /Twinkle/ig;
let result = twinkleStar.match(starRegex); //输出两个值
11. 有时不(或不需要)知道匹配模式中的确切字符。 如果要精确匹配到完整的单词,那出现一个拼写错误就会匹配不到。 幸运的是,可以使用通配符 .
来处理这种情况。
var huRegex = /hu./ //hua,hue,huq......
12.如果想要匹配 bag
、big
和 bug
,但是不想匹配 bog
。 可以创建正则表达式 /b[aiu]g/
来执行此操作。 [aiu]
是只匹配字符 a
、i
或者 u
的字符集
13.正则的捕获
捕获
+ 语法: 正则.exec(字符串)
+ 返回值:
1. 原始字符串内没有符合正则要求的字符串片段
=> 返回值就是 null
2. 原始字符串内有符合正则要求的字符串片段
=> 返回值是一个数组数据类型, [0] 位置就是从字符串内捕获出来的内容
2-1. 正则没有 () 没有全局标识符 g
=> 返回值数组只有 [0] 数据
=> 不管你捕获多少次, 正则都是从原始字符串开始位置进行检索
2-2. 正则有 ()
=> 返回值数组 [0] 依旧是捕获出来的完整字符串片段
=> 从 [1] 开始依次是每一个小括号的单独内容捕获
const str = '我的身份证号是 : 11010820050223001x 你看对不对 ^_^'
const reg = /(\d{2})(\d{2})(\d{2})(\d{4})(\d{2})(\d{2})\d{2}(\d)(?:\d|x)/
console.log(reg.exec(str))
//因为有(),返回一个数组,索引0是'11010820050223001x',索引1是"11",就是正则第一个小括号的内容。
//索引二就是正则第二个小括号的内容
2-3. 正则有 g
=> 返回的数组 [0] 依旧是捕获出来的完整字符串片段
=> 但是从第二次开始, 会从第一次捕获结束位置开始检索
=> 以此类推, 直到找不到了为止, 返回 null
=> 再下一次又从字符串开始位置进行检索
日常积累
1.getBoundingClientRect(),获取div的宽高,不用clientX与clientY是因为页面会重绘
const div=document.querySelector('div')
const rect =div.getBoundingClientRect()
2.重绘与回流