JS的核心--第三周

118 阅读9分钟

第一天

一、DOM的常用对象
1、history对象:保存了当前窗口的历史记录
前进:history.go(正数)//这个正数是几就前进几个网页
后退:history.go(负数)//这个负数是几就倒退几个网页
刷新:history.go(0)
2.location对象:保存了当前窗口正在打开的url
程序员常识
一个url由几个部分组成?每部分分别有什么用?
一个url有五个部分:
1、协议--->请求--响应式模型:https(加密) http(未加密)
2、主机号/IP地址号/域名:
域名是需要花钱购买的,主机号和IP地址是免费的
例:
127.0.0.1才是主机号,只能访问自己
3、端口号:https默认的端口号为443,http默认的端口号是80,只有默认的端口号可以省略不写
4、文件的相对路径|路由
5、查询字符串请求消息,前端输出到后端的东西
属性
获取5个部分的内容:
协议:location.protocal; 域名:location.hastname;
端口:location.port;
路由:location.pathname;
请求消息:location.search;
跳转:location=“新url”-->替换单签窗口,可以后退
跳转后禁止后退:location.replace("新url");替换当前窗口,禁止后退
刷新:loc.reload();

DOM:

1、查找元素
1、通过关系查找元素
2、直接查找元素:
1、document.getElementsByXXX(); 返回一个动态集合
2、两种查找元素方法
1、let elem=document.querySelector("css选择器");//单个选择器,只能找到第一个,多个相同元素则只烦恼会显示第一个,没找到则为null;
2、let elem=document.querySelectorAll("css选择器");//选择出多个,是一个集合
优点:
1、找到一个集合,找不到就是空集合
2、复杂查找方便
3、返回的是一个静态集合:Nodelst;

面试题

document.getXXX和document.querySelector的区别 ? 1、querySelector更适合复杂查找
2、动态集合和静态集合的区别
1、动态集合:DOM发生变化,数据也会发生变化,不支持forEach遍历,效率较低
2、静态集合:DOM发生变化,数据不会变化,支持forEach,效率相对较高

2、操作属性:

1、获取属性值:
核心DOM:elem。getAttribute("属性名","属性值"); HTML DOM:elem.属性名
2、设置属性值:
核心DOM:elem.setAttribute("属性名","属性值"); HTML DOM:elem.属性名="属性值";
elem.on事件名=function(){}
3、上树的三种方法
1、父元素:append.Child(elem);//在父元素的末尾追加一个子元素elem
2、父元素.insertBefore(elem,已有子元素)//在父元素追加一个放在全部已有子元素前面的子元素
3、父元素.replace.Child(elem,已有子元素)
4.删除元素:elem.remove();

扩展

1、创建变量:新增的一个let关键字 相当于var却有不同 let 变量名=值;
作用:

  1、解决了声明提前
2、带来了块级作用域,一个{}就是一个块,这个变量就只能在单签变量下的{}里面使用
3、如果let去当做下标绑定事件,那么他会记住你当前元素的下标,不再需要自定义下标,forEach中的形参i就是用let创建的

2、类数组转为普通数组:
Array.from(类数组对象);

第二天

1、递归:在函数中再次调用了函数自己,会停下来
何时使用:专门用于变能力层级不明确的情况。
DOM树和数据Children只能找到儿子层找不到孙子层
使用:

function  函数名(root){
1、第一层做什么直接做
2、判断有没有下一次,入过有下一层,则再次调用此方法,只不过传入的实参是自己的下一层  
}
函数名(实际根);

算法:
深度有限,先遍历当前结点的子节点,字节点遍历完了才会跳到兄弟节点。
缺陷:性能相对较差,会同时开启大量的函数调用,浪费内存,只在层级不明确时候使用

第三天

DOM:两个重点:定时器和event
1、周期:从时间发生到所有时间处理函数执行完毕的全过程
3个阶段:
1、捕获阶段:由外向内,记录要发生的事件有哪些,
2、目标优先触发:目标元素-->当前点击的实际发生事件的元素
3、冒泡触发:由内向外,依次执行我们之前记录的要发生的事件

2、获取事件对象 event
主流:会自动作为事件处理函数的第一个形参传入
老IE:event:全局都有个变量
兼容:even:兼容各个版本的浏览器
得到事件对象event可以做什么呢?
1、获取鼠标的坐标
获取鼠标相对于屏幕的坐标
e.screen X\Y;
获取鼠标相对于窗口/客户端/文档显示区域坐标
e.elient X/Y;
获取鼠标相对于网页的坐标
e.page X/Y;
鼠标移动时间:
onmousemove=function(){}
2、阻止时间冒泡,笔试题
主流:e.stopPropagation();
老IE:e.cancelBubble=true;
兼容:e.cancelBubble=true;
3、利用冒泡-->时间委托--实际开发中使用较多
优化:如果多个子元素定义了相同或相似的事件操作,最好只给父元素定义一次
为什么?
每一次绑定事件函数,其实就是建立了一个对象,创建多了性能就差了
target:点哪个,永远就是哪个。
主流:e.target
老IE:e.srcElement
兼容:e.srcElement;
4、阻止浏览器的默认行为
主流:e.preventDefault();
老IE:e.returnValue()==false;
兼容:e.returnValue==false

新事件:
1、右键事件:windows.oncontextmenu
2、键盘事件:游戏发开用的多
window.onkeydown:接住或按下任意键会触发
window.onkeypress:按住和按下任意键,只有数字,空格,回车可以触发 可以触发
5、获取键盘上键盘的键盘
e.keyCode:可以获取到按下的是哪个按键

事件委托

1、如何判断目标元素是什么标签
xx.nodeName;得到标签名,但是都是由大写组成的
2、事件处理函数用箭头函数,this会失效 所以必须使用target

第四天

1、事件的取消绑定
1、elem.onclick=()>{}
取消:elem.onclick;
2、

elem.addEventListener("事件名",回调函数);  
elem.removeEventListener("事件名",回调函数);  
事件名和回调函数必须和条件的时候是一样的  

重点来喽

this 的指向:
单个元素绑定事件 this就是这个元素
多个元素绑定事件 this指的是当前元素
箭头函数中的this 外部对象
函数中的this-->当前正在调用函数的这个人
定时器: this-->window

** 强制改变this 的指向**

call/apply:临时的替换了函数的 this
语法
函数名.call(借用的对象,实参,...);//单穿实参
函数名.apply(借用的对象,arr);//只能传一个实参,并且只能是数组
apply其实会悄悄打散数组,
强调:call/apply:相当于立刻调用函数并且立即执行
bind:永久替换了函数中的this
1、创建了一个和原函数功能完全相同的新函数
2、将新元素的this永久绑定为了指定对象更
别不能够引用
3、将新函数的部分参数永久固定
语法:
var 新函数=函数名.函数名.bind(永久对象,永久实参...)
不是立刻执行的,需要再次调用
强调:bind绑定新函数没办法被call/apply再次借走

三个固定套路:

1Math.max/min.apply(Math,arr);  
2Object.prototype.toString.call/apply(x)==="[objeck Array]";//判断xx是不是数组
 

3、类数组转换为普通数组

1、接住=Array.prototype.slice.call/apply(类数组对象);  
2、接住=Array.from(类数组对象);

4、ES6带来的
1、let .const 关键字,箭头函数
2、模板字符串中,可以直接识别变量,不再需要+运算去拼接了,而且实现了一个简单的js环境,甚至在里面书写API

`我的名字叫${name};` 

第五天

超重点来了

解构赋值:解析结构再赋值,--赋值的新方式
语法:
1、类似数组的解析结构赋值
第一种

    let [a,b,c]=[1,2,3];
    console.log(a);
    console.log(b);
    console.log(c);

第二种,类似对象的结构赋值,形参可以是默认值,如果传入了急用自己的传入的

let { a, b = 2, c } = { a: 5, c: 1 }
        console.log(a);
        console.log(b);
        console.log(c);  

第三种,调用函数时:传递实参的顺序无所谓

        function zwjs({name, age, hobby}) {
            return `我的名字叫${name},今年${age}岁,我的爱好是${hobby}`;
        }
        console.log(zwjs({ hobby: "学习", age: 90, name: "孢子" })); `

第四种 :函数的返回结果,可以有多个

    function f1() {
        let a = 1;
        let b = 2;
        let c = 3;
        return [a, b];
    }
    let [a, b] = f1();
    console.log(b,a);

只要见到方法名({里面放着键值对就是使用了ES6的解构赋值})
4、Set和Map新的数据类型
1、Set:类似数组的一种数据格式
《去重数组,再转为数组》
let S=new Set(arr);
...S三个点代表扩展原酸符
[...new Set(arr)]//不用记忆如何的api
let m=new Map();
添加:m.set("键","值";
获取:m.get("键);
清空:m.clear();
删除:m.delete("键);
5、新的循环
for(let val of arr){ val;//得到的就是素组里面的具体指; } 缺陷:
1、没有提供过下标,不能遍历修改原数组
2、只能遍历索引数组,不能遍历hash数组,也不能遍历 所有对象

第五天 正则表达式
1、后缀:g:找全部 i:忽略大小写;
2、备选字符集:/^[备选字符集]$/;

强调:
1、一个中括号只能管一个字符;
2、问题:正则表达式默认只要满足就不会管后面的了,而我们希望从头到尾的按照我们的要求验证
解决:
前面加一个^后面加一个 $,两者同时使用

/^[备选字符集]$/; 

特殊:若备选字符集中的ASCII码是连续的那么可以省略中间的部分
例:
一位数字:[0-9];
除了什么之外:[^0-9],^放在中括号里面,就是除了什么之外

3、预定义字符集:已经被定义好的直接使用
一位数字:\d;
一位数字,字母,下划线:\w;
一位空白字符:\s;
一位除了换行外的任意字符:.空格
4、量词:规定字符集出现的次数
1、有明确数量:
字符集?;前面相邻字符集可有可无,最多一个
字符集*:前面相邻字符集可有可无,多了无限
字符集+:至少一个,多了无限
5、选择和分组:
选择:在两个规则中选一个
规则1|规则2
分组:将多个字符集临时组成一个子规则
(规则1|规则2 )
6、指定匹配位置
^:开头
$:结尾

7、密码强度验证:
2-4位,可以输入数字、字母,但是必须出现一位大写和一位数字的组合

  /^[0-9A-Za-z]{2,4}$/  

预判公式:

(?![0-9]+$) -> 不能全由数字组成,可能有大写、小写、汉字、日文、特殊符号...  
(?![a-z]+$) -> 不能全由小写组成,可能有数字、大写、汉字、日文、特殊符号...  
(?![0-9a-z]+$) -> 不能全由数字组成、也不能全由小写组成、也不能全由数字和小写的组合组成

例:

/(?![0-9a-z]+$)(?![A-Za-z]+$)[0-9A-Za-z]{2,4}/2-4位,可以输入数字、字母,但是必须出现一位大写和一位数字的组合  
/(?![0-9a-z]+$)(?![A-Za-z]+$)(?![A-Z0-9]+$)[0-9A-Za-z]{2,4}/必须三者都有
/(?![0-9A-Za-z]+$)[0-9A-Za-z_]{2,4}/至少要有下划线

2、支持正则表达式的字符串API

1、基本替换法

str=str.replace(/正则表达式/后缀,"新内容");//replace支持正则,并且搭配上后缀g就能找到全部  
缺陷:替换的新内容是一个固定的

2、高级替换法:

str=str.replace(/正则表达式/后缀,function(a,b,c){
console.log(a);//正则匹配到的关键字
console.log(b);//正则匹配到的关键字的下标
console.log(c);//原字符串
return 判断a关键字的长度,而返回不同的星星数量
})

3、身份证格式化

let id="532126199810230893";
			var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;
			id.replace(reg,function(a,b,c,d,e,f,g,h){
				//第一个形参胡i拿到匹配到的关键字
				//第二个形参会拿到第一个分组匹配到的内容
				//第三个形参会拿到第二个分组匹配到的内容
				//...
				//倒数第二个一定是下标
				//倒数第一个一定是原文本身
			})

例:

        let user = "53212620001027031X";
        let reg = /^([0-9]{15}|[0-9]{17}[Xx0-9])$/;
        console.log(reg.test(user));

4、格式化手机号

let phone="17787909313";
let reg=/(\d{4})\d{4}(\d{3})/;
phone=phone.replace(reg,(a,b,c)=>{
return a+"****"+c;
})
console.log(phone);

总结:何时前面加^,后加$,何时后加后缀g

1、前加^ 后加$ ---> 验证

2、替换,替换所有的 --> 必须加g

5、正则对象 创建:
1、直接量:let reg=/正则表达式/后缀
2、构造函数:let reg=new RegExp(“正则”,"后缀")
API:
1、验证:
let bool=reg.test(用户输入的);