js第三周

90 阅读5分钟

day01

BOM:

1、history:保存当前窗口的历史记录:
	前进后退刷新:history.go(正数/负数/0);

2、location:保存当前窗口的正在打开的url:
	常识:一个url由5部分:
		协议://域名:端口号/文件相对路径?请求消息

	跳转:location="新url";
	跳转后禁止后退:location.replace("新url");
	刷新:location.reload();

DOM:

1、找到元素:
    
	1、直接找:
		动态集合:var elems=document.getElementsByTag/ClassName("标签名/class名");

		静态集合:var elems=document.querySelectorAll("任意的css选择器"); - 效率更高、而且支持forEach

	2、通过关系:
		父:parentNode
		子:children
		第一个儿子:firstElementChild
		最后一个儿子:lastElementChild
		前一个兄弟:previousElementSibling;
		后一个兄弟:nextElementSibling;

2、操作元素
	内容:innerHTML(识别标签)/innerText(识别纯文本)/value(input、option)
		获取:elem.上面的;
		设置:elem.上面的="新内容";

	属性:
		获取:elem.getAttribute("属性名");	HTML DOM:elem.属性名;

		设置:elem.setAttribute("属性名","属性值");	HTML DOM:elem.属性名="属性值";

		删除:elem.removeAttribute("属性名"); - 可以删干净属性节点

		判断有没有:elem.hasAttribute("属性名"); true->有  false->没有

	样式:
		内联样式:
			获取:elem.style.css属性名;
			设置:elem.style.css属性名="css属性值";

		样式表:
			var sheet=document.styleSheets[i];
			var rules=sheet.cssRules;
			var rule=rules[i];
			获取:rule.style.css属性名;
			设置:rule.style.css属性名="css属性值";

3、创建元素&上树:3步
	1、创建空标签:
		var elem=document.createElement("标签名");

	2、为其添加必要的属性和事件
		elem.属性名="属性值";
		elem.on事件名=function(){}

	3、上树:3种
		*父元素.appendChild(elem);
		父元素.insertBefore(elem,已有子元素);
		父元素.replaceChild(elem,已有子元素);

4、删除元素:elem.remove();

day02

1、递归:函数中又一次调用了函数自己,迟早有一天会停下来。
  何时使用:遍历层级不明确的情况,DOM树和数据。
  如何使用:
function 递归(x){
	1、只管第一层要做什么

	2、判断有没有下一层,如果有再次调用此方法,只不过传入的是下一层的东西		
}
递归(实际的根DOM/根数据);

缺陷:同时开启大量的函数调用,浪费内存,仅在需要的时候使用

算法:深度优先算法!

2、三个绑定事件的方式:
1、<elem on事件名="函数()"></elem>

2、elem.on事件名=function(){}

3、兼容:
	if(elem.addEventListener){
		elem.addEventListener("事件名",callback);
	}else{
		elem.attachEvent("on事件名",callback);//老IE不支持箭头函数
	}

day03

事件:

    1、事件周期:3个
	1、捕获阶段:由外向内,记录着要发生的事件有哪些
	2、目标元素优先触发:目标元素->实际点击的那个元素
	3、冒泡阶段:由内向外,依次触发之前记录着的事件

2、获取到事件对象event
	主流:事件函数内写一个形参,就会自动得到了
	老IE:event;
	兼容:event;

	可以干什么?
		1、获取鼠标的位置
			相对于屏幕:e.screenX/Y
			相对于文档显示区域:e.clientX/Y
			相对于页面:e.pageX/Y

		2、阻止冒泡:
			主流:e.stopPropagation();
			老IE:e.cancelBubble=true;
			兼容:e.cancelBubble=true;

		3、事件委托:利用冒泡
			优化:绑定的事件越多,网站的性能越差
			为什么:因为每绑定一个事件,相当于就创建了一个事件对象
			把事件绑定在父元素身上:主要学会找到目标元素
			主流:e.target;
			老IE:e.srcElement;
			兼容:e.srcElement;
			事件内可以淘汰了this,但是淘汰不完
			搭配上判断标签名:xx.nodeName; - 得到全大写的标签名

		4、阻止浏览器的默认行为
			主流:e.preventDefault();
			老IE:e.returnValue=false;

			新事件:
				1、右键事件 - oncontextmenu
				2、键码事件 - onkeydown/press/up

		5、获取键盘键码:e.keyCode;

day04

1、取消事件:

    1、elem.onclick=()=>{}	-	取消:elem.onclick=null;
2、elem.addEventListener("事件名",函数名);	-	取消:elem.removeEventListener("当初的事件名",当初函数名);

2、this的指向:

    1、单个元素绑定事件this->这个元素
2、多个元素绑定事件this->当前元素
3、定时器中this->window
4、箭头函数的this->外部对象
5、函数中的this->当前正在调用函数的对象

3、强制改变this的指向:

    pcall/apply:临时替换了函数中的this - 借
	语法:函数名.call(借用的人,实参,...);
	          函数名.apply(借用的人,arr);
	借用相当于立刻执行

bind:永久替换了函数中的this - 买
	语法:var 新函数=函数名.bind(永久绑定的人,永久实参,...);
	不会立刻执行的,需要我们需要的时候再去调用。

三个固定套路:
	1、获取数组的最大值和最小值:Math.max/min.apply(Math,arr);//悄悄打散数组,其实还可以这么写:Math.max/min(...arr)
	2、判断x是不是一个数组:Object.prototype.toString.call/apply(x)=="[object Array]"
	3、类数组转为普通数组:var 接住=Array.prototype.slice.call/apply(类数组对象) - 被代替:Array.from()

4、模板字符串:

            `我的名字叫${name},今年${age}岁`;

5、解构赋值:赋值的新方式

1、类似数组的解构赋值
	var [a,b,c]=[1,2,3]; - 函数的return可以返回多个数据

2、类似对象的解构赋值
	var {a,b,c}={a:1,c:3,b:2} - 衍生出函数的传参其实顺序是无所谓的

6、Set:将数组去重再转回数组,因为set提供的功能很少 arr=[...new Set(arr)];

7、for(var v of arr){ v;//当前值 } 不能修改原数组 而且不能遍历hash数组,也就不能遍历对象

day05

1、正则表达式:定义字符串中字符出现规则的表达式 何时使用:切割 替换 【验证】! 如何使用:语法:/正则表达式/

	1、最简单的正则就是关键字原文 "no" -> /no/后缀
		后缀:g:找全部		i:忽略大小写

	2、备选字符集:/^[备选字符集]$/
		强调:1、一个中括号,只管一位字符
		          2、问题:正则表达式默认只要满足就不管后续了,而我们做验证的人,希望的是用户从头到尾按照我们的要求来,希望从头到尾完全匹配:
			解决:前加^,后加$,两者同时使用,代表要求从头到尾完全匹配/^[备选字符集]$/ - 只要做验证必加!
		特殊:如果备选字符集中的ascii码是连续的,那么可用-省略掉中间部分
			比如:
				一位数字:[0-9];
				一位字母:[A-Za-z];
				一位数字、字母、下划线:[0-9A-Za-z_]
				一位汉字:[\u4e00-\u9fa5]

				除了xxx之外的:[^0-9] - 很少使用,范围太广了

	3、预定义字符集:前辈们提前定义了一些字符集,方便我们程序员 - 简化了备选字符集
		一位数字:\d ===>[0-9]
		一位数字、字母、下划线:\w ===> [0-9A-Za-z_]
		一位空白字符:\s

		一位除了换行外的任意字符:.   - 很少使用,范围太广了

		建议:优先使用预定义字符集,预定义满足不了我们再用备选字符集补充

	问题:不管是备选字符集,还是预定义字符集,一个都只管一位

	4、量词:规定一个字符集出现的次数:
		1、有明确数量:
			字符集{n,m}:前边相邻的字符集,至少n个,最多m个
			字符集{n,}:前边相邻的字符集,至少n个,多了不限
			字符集{n}:前边相邻的字符集,必须n个

		2、无明确数量:
			字符集?:前边相邻的字符集,可有可无,最多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、切割:var arr=str.split("固定切割符"/RegExp);

2、*****替换:很有可能出现在笔试之中
	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、格式化:身份证
		var id="500103198602215933";
		var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;
		id.replace(reg,function(a,b,c,d,e,f,g,h){
			//再replace的时候,正则出现了分组,我们会得到更多的形参
			//再形参a的后面就会出现n个形参,就看你有多少个分组
			//第1个分组获得的内容会保存在第2个形参之中
			//第2个分组获得的内容会保存在第3个形参之中
			//...
			//倒数第二个一定是下标
			//倒数第一个一定是原文本身
		})
	      格式化:手机号
		var phone="13452390312";
		var reg=/(\d{4})\d{4}(\d{3})/;
		
		phone=phone.replace(reg,(a,b,c)=>{
			return b+"****"+c;
		})
		
		console.log(phone);

	总结:何时前加^后加$,何时又该添加后缀g?
		1、前加^后加$ - 验证
		2、替换,你希望替换所有 - 必须加g

3、正则对象:

创建:
	1、直接量:var reg=/正则表达式/后缀;
	2、构造函数:var reg=new RegExp("正则表达式","后缀");

API:
	1、验证:var bool=reg.test(用户输入的);