js核心第三周

22 阅读10分钟

第一天

Bom的常用对象

1.history对象 保存了当前窗口的历史记录,过去的url

    前进:history.go(1)
    后退:history.go(-1)
    刷新:history.go(0)

2.location对象 保存了当前窗口正在打开的url(现在的url)

    常识:一个url有好几部分组成,分别每个部分有什么用
    5部分:
    1.协议:https(加密)http(未加密)、ffp(传输型)、ws(直播)前两者都属于叫做请求——响应模型
    2.主机号:/ip地址/域名 域名是需要花钱购买的,主机号/ip地址是免费的 127.0.0.1才是真的叫做主机号,只能自己访问
    3.端口号:https 默认端口号为433、http默认端口号为80,只有默认端口可以不写
    4.文件的相对路径、路由、百度加密了
    5.查询字符串、请求消息、侵短传输到后端的东西。前端对后端说的话
    属性:
    获取url的五个部分,但是不需要记忆,直接输入location对讲即可查看
        协议:location.proocal
        域名:location.hosname
        端口:location.port
        路由:location.payhname
        请求消息:location.search
        
        跳转:location="新url" 替换当前窗口可以后退
        跳转后禁止后退:location.replace("新url")--替换当前窗口禁止后退
        刷新:location.reload()

dom 1查找元素

1.通过关系查找元素
2.直接找元素

    1.document.getElementByxxx()--返回值是一个动态集合 HTML Collection
    2.两种:
        1.var elem=documentquerySelector(“任意选择器”)
        query--查询  selector--选择器:查询css选择器
        缺陷:
        只能找到单个元素,如果匹配到多个,也只会返回第一个,如果my找到返回--null 一次只能操作一个元素
        2.var elems=document.querySelectorAll(“任意css选择器”)
        优点:
        1.找到了返回一个集合,没找到是一个集合
        2.复杂查找时,非常简单
        3.返回的是一个静态集合--Node list
        面试题:
        document.getdocument.query区别
        1.后者更适合复杂选择
        2.动态集合和静态集合的区别
            1.动态集合,每次dom发生变化,他都会悄悄的再次查找,让页面和数据保持一致,但是效率也就低下了,,不支持ForEach()
            2.静态集合,每一次dom发生变化,他都不会悄悄的再次1查找,让页面和数据没有保持一致,但是效率也就提高了,支持forEach()

2.操作样式

       1.内联样式
       2.样式表达式

3.操作属性

       1.获取属性值
           核心dom elem.getAttribute(属性名“”)
           HTML dom elem.属性名
       2.设置属性值
           核心dom elem.setAttribute(“属性名”,“属性值”)
           HTML dom elem.属性名=“属性值”
       3.删除属性
           设置属性值为字符串,确实某些属性可以删除,但是只是删除了属性值,属性名还在,而有点属性哪怕只有属性名,也会具有作用(比如:href disabled readonly)
           核心dom elem.removeAttribute(“属性名”)
           HTML dom elem.属性名=“ ”---属性节点删不干净
       4.判断有没有 只能判断有没有
           核心dom elem.hasAttribute(“属性名”)
           HTML dom elem.属性名!=“”

4.操作内容——innerHTML、innerText、value 5.创建元素上树

       1.创建空标签
       var elem=document.createElment("标签名")
       2.为其设置必要的属性和事件
        elem.属性名=“属性值”
        elem.on事件名=function(){}
       3.上树 3种
        父元素.appendChild(elem)————在父元素末尾追加一个子元素elem
        父元素.insert Before(elem,已有子元素)————在父元素中追加一个子元素elem,但是放在已有的子元素前面
        父元素.replaceChild(elem.已有子元素)在父元素追加一个子元素,但是会替换掉一个子元素

6.删除元素——elem.remove()

扩展: let 变量名=值 1.作用:解决了声明提前 2.带来了块级作用域,一个{}就是一个块,此变量只能在这个{}中生效 3.如果用let去当作下标签绑定事件,那么他也会记录着你当前元素的下标,不在需要去自定义下标了,其实forEach的那个i就是let创建的 2.类数组转普通数组 arr=Array.from(类数组对象)

第二天

1.递归——在函数中再一次调用了自己 ——何时使用:专门用于遍历层级不明确的情况,dom和数据children只能找到儿子层,找不到孙子层

何时使用:
    function 函数名(root){
    1.第一次要做什么直接做
    2.判断有没有下一层,如果有下一层,则再次调用此方法,只不过传入的实参是自己的下一层
    }
    
    调用:函数名(实际的根)
    算法:深度优先,优先遍历当前节点的子节点,子节点遍历完毕,才会跳到兄弟节点
    缺陷:不要过多使用,性能较差,会同时开启大量的函数调用,浪费内存,我们只在层级不明确的时候使用
 递归和纯循环的区别:
     递归:优点——简单易用
         缺点——性能低
 纯循环:优点——几乎不占用性能    
         缺点——难 

2.绑定事件——三种方式

    1、在HTML上书写事件属性
	<elem on事件名="函数名(实参)"></elem>
	缺点:
		1、不符合内容与样式与行为的分离原则
		2、无法动态绑定,一次只能绑定一个元素
		3、不支持绑定多个函数对象

2、*在js中使用事件处理函数属性
	elem.on事件名=function(){操作}
	优点:
		1、符合内容与样式与行为的分离原则
		2、动态绑定,一次能绑定多个元素
	缺点:
		1、不支持绑定多个函数对象

3、*在js中使用事件API:如果不用考虑老IE,他也不错
	主流:elem.addEventListener("事件名",callback);
	老IE:elem.attachEvent("on事件名",callback);
	兼容:
		if(elem.addEventListener){
			elem.addEventListener("事件名",callback);
		}else{
			elem.attachEvent("on事件名",callback);
		}
	优点:
		1、符合内容与样式与行为的分离原则
		2、动态绑定
		3、支持绑定多个函数对象
	缺点:有兼容性问题

扩展: 1、select&option只有他们可以简化创建元素&上树: select.add(new Option("innerHTML","value"));

第三天

1.事件周期——从实践发生,到所有实践处理函数执行完毕的全过程

     3.个阶段:
         1.捕获阶段:由外向记录要发生的事情有哪些
         2.目标优先触发:目标元素——当前点击的实际发生事件的元素
         3.冒泡触发:由内向外,依次执行我们记录着的要发生的事件

2.获取事件对象 event

     主流:会自动作为事件处理函数的第一个形参传入
     老ie:event 老ie全局有这个变量
     兼容:不光老ie可以,主流也可以——event
     得到了事件对象event可以做什么;
         1.获取鼠标的坐标:
             获取鼠标相对于屏幕的坐标:e.screenX|Y
             获取鼠标相对于窗口、客户端、文档显示区域的坐标e.clientX|Y
             *获取鼠标相对于网页的坐标:e.pageX|Y
             鼠标移动事件——onmosemove=function(){}
         2.阻止事件冒泡:
             主流:e.stopPropagation()
             老ie:e.cancelBubble=true
             兼容:e.cancelBubble=true

3.*利用冒泡、事件委托

             可以提升性能  时间函数可以换为=>函数
             优化:如果多个子元素定义了相同或相似的时间操作,最好只给父元素定义一次
             为什么:每一次绑定一个事件函数,其实都是创建了一个事件对象,创建越多,性能越差
             淘汰了this
             认识新元素:target 点的哪个元素就永远是那个,不会发生变化
                 主流:e.target
                 老ie:e.srcElement
                 兼容:e.srcElement

4.阻止浏览器的默认行为 如——a-跳转 f5-刷新等

     主流:e.preventDefault()
     老ie:e.returnValue=false
     兼容:e.returnValue=false
     新事件:
         1.右键事件:——window.oncon textmenu
         2.键盘事件:
             1.window.onkeydown 按住 按下 任何时候都触发
             2.window.onkeypress 按住 按下 只有字母 回车 数字触发
             3.window.onkeyup 松开 任何键触发

5.获取键盘的键码:

  e.keyCode——可以获取到你按到的键,每个键都有自己读音的键码,无需记忆,可以输出查看,也可以百度表格

注:如果时间委托了

   1.如何判断目标是什么标签,xx.nodeName得到标签,只不过全是大写
   2.事件处理函数可以写为箭头函数->this会失效,所以必须使用目标函数target
   3.this的指向:
       1.单个目标绑定事件 this->这个元素
       2.多个元素绑定事件:this->当前元素
       3.箭头函数:this->外部对象

第四天

1.事件的取消绑定

1.如果使用 elem.onclick=()=>{}
    那么 elem.onclick=()=>{}
2.如果使用的 elem.addEventListener("事件名","回调函数")
    那么 elem.removeEventListener("事件名","回调函数")
    事件和回调函数必须和添加时一样,封装函数进行删除

2、*****this的指向:非常多

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

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

    1.call、apply ——临时的替换了函数this-借用
        语法:函数名.call(借用对象,实参)--单独传入每个参数
             函数名.apply(借用对象,arr)--只能传入一个实参,要求是数组,apply其实会悄悄的将数组打散
        强调:call、apply相当于立刻调用函数,立刻执行
    2.bind——永久的替换了函数中的this
        三个事件:
            1.创建了一个和原函数的功能完全相同的新函数
            2.将新函数的this永久绑定为了指定的对象
            3.可以将新函数的部分参数永远固定
        语法:
            var 新函数=函数名.bind(永久对象,永久实参....)--不是立刻执行,需要调用
        强调:
            bind绑定的新函数没办法被call、apply再次借走————推荐使用借
     3.三个固定套路:
         1.Math.max/min.apply(Math,arr)--支持数组参数、
         2.Objct.prototype.toString.call/apply(x)===[objct Array]--判断是不是一个数组,其他的也可以使用
         3.类数组转为普通数组
             1.接住=Array.prototype.slice.call/apply(类数组对象)
             2.接住=Array.from(类数组对象)

4.ES6

  1.学过了let const 等关键字,箭头函数
  2.模板字符串:
      可以直接识别变量,不再需要+运算去接住,而且实现了一个简单的js环境,甚至支持在里面写API
      例:我的名字叫${name}
          不需要+去拼接
  3.解构赋值——先解析结构,再进行赋值
      如果赋值符号左右两边的结构一样,就会悄悄的解开、再一一进行赋值
      语法:
          1.类似于数组的解构赋值:
              let[a,b,c]=[1,2,3]
              相当于a=1,b=2,c=3
          2.类似对象的解构赋值
              let{a,b,c}={c:3,a:1,b:6}
              相当于 a=1 b=6 c=3
              形参可以谁在默认值,如果自己传入,可以使用自己的
          3.调用函数时,传递实参的顺序无所谓
              function zwjs({name,age,hobby="女"}){
              return `我的名字叫${name},今年${age}岁,喜欢${hobby}岁`
              }
              console.log(zwjs({hobby:"学习"age:18},name:"六六"}))
              
          4.函数的返回结果可以有多个
              function f1(){
              var a=1;
              var b=2;
              return [a,b]
    }
    var [a,b]=f1()
    console.log(a,b)
          5.*set和map新的数据类型
            1.set:类似于数组的一种数据格式
                去重数组,然后再转回数组
                var s=new set(arr)
                ...s————三个点扩展运算符,可以脱去数组外衣
                一句话——[...new set(arr)]
             2.Map:类似于对象的一种数据格式
             var m=new Map()
             添加:m.set("键","值")
             获取:m.get("键")
             清空:m.clear()
             删除:m.delete("键")

5.新的循环:

       	for(var v of arr){
		v;
	}

	缺陷:
		1、没有提供过下标,意味着不能修改原数组
		2、只能遍历索引数组,不能遍历hash数组,意味着也不能遍历对象

注:只要以后见到——方法名{里面放着键值对,就是使用了es6的解构赋值}

第五天

1.正则表达式:定义字符串中字符的出现规则的表达方式:

如何使用: 切割 替换 [验证]

    语法:/正则表达式/
    1.最简单的正则就是关键字原文——"no"->/no/后缀
        后缀:g-全部——i-忽略大小写
    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}——前面的字符集必须nge
        2.无明确数量:
            字符集?——前面相邻的字符集可有可无,最多一个
            字符集*——前面的字符集可有可无,多了不限
            字符集+——前面的字符集,至少一个,多个不限
    5.选择和分组:
        选择:在两个规则中选择一个
            规则1|规则2
        分组:将多个字符集临时组成一组规则
            (规则1|规则26.指定匹配位置
        ^:开头 $:结尾 [^]:不为...
        特殊:两者同时使用,前加^,后加$,表示从头到尾要求完全匹配 - 只要你做【验证】

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(用户输入的);