JS学习第五期

事件委托

1.就是把我要做的事情委托给别人来做
2.因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
3.所以我们就可以把子元素的事件委托给父元素来做

target

1.target 这个属性是事件对象里面的属性,表示你点击的目标
2.当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
3.这个 target 也不兼容,在IE 下要使用 srcElement

<ul id="list">
	<li>
		111
		<button>add</button>
	</li>
</ul>

<script>
	list.onclick = function(evt){
		console.log(evt.target)
	}
</script>

如上我们就绑定一个,其中evt.target可以获取对应标签,就如上面的点击事件,点击哪个标签就输出哪个标签。
其好处有:
1.减少多个函数的绑定的性能损耗
2.动态添加li,也会有事件处理

初识正则表达式

JS复杂类型

字面量

var reg = /abc/

如上就是检测内容是否包含abc

内置构造函数

var reg = new RegExp("abc")

效果和上面一样
如果我们使用input来获取内容呢,那么我们应该怎么判断

var reg = new RegExp("abc")
//mytext为input的id名
mytext.onblur = function(){
	console.log(reg.test(mytext.value))
}

如上我们就判断了输入的内容中有没有abc
其中test()方法就是判断

元字符

基本元字符

\d 一位数字(0-9)

var reg = /\d/

字符串中必须包含一个数字

\D 一位非数字

var reg = /\D/

必须包含一个非数字

\s 一位空白内容(空格 缩进 换行)

\S 一位非空白内容

\w 一位字母/数字/下划线_

\W 非字母/数字/下划线_

. 任意内容(不包含换行)

.\ 转义字符

var reg =/\d\.\d/

如上就是表示输入内容为小数

边界符

var reg = /^\d/
^ //表示开头必须是什么
var reg = /\d$/
$ //结尾必须是什么

^$
这就表示了从开头到结尾就是限定住的
/^a\dc$/
表示了开头是a中间是数字,结尾是c

限定符

* 0~多次

var reg = /\d*/

+ 1~多次

var reg = /\d+/

包含一个到多个数字

? 0~1

{n} 指定次数

{n,m} n~m次

特殊符号

() 整体

| 或

var reg = /(abc|def)/

要不然包含abc
要不然包含def
其中括号是可以去掉的

[] 一个

var reg = /[abcdef]/

有一个就算的

var reg = /[abcdef]{3,5}/

最少三个最多五个其中的

[a-z]
代表小写字母中任意一个
如果有规律就是加-
[0-9]
表示0到9
var reg = /[^abc]/

有一个不在abc内的

正则表达式

捕获方法exec

捕获片段

var reg = /\d/

console.log(reg.exec("aa123aa"))
//如上就输出1
//如果reg改为/\d{3}/则输出123
如果获取到的如下
var day = " day is 2023-01-01"
如果想要输出2023/01/01如何
var reg = /\d{4}-\d{1,2}-\d{1,2}/
var newday = reg.exec(day)
console.log(newday[0].split("-").join("/"))

如上有一个问题,只能捕获遇到的第一个
如果是一个范围则失效了
这样我们就要引入新东西了
标识符
g和i

var day = " day is  from 2023-01-01 to 2034-01-01"
var reg = /\d{4}-\d{1,2}-\d{1,2}/g
var newday1 = reg.exec(day)
var newday2 = reg.exec(day)
console.log(newday1[0].split("-").join("/"))
console.log(newday2[0].split("-").join("/"))

如果我们在reg里加()会怎么样呢
var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g
除了行使原有职责,之后还会单独提取
效果
i

var reg = /[a-z]/i
加了i就忽略大小写了
console.log(reg.test("AA"))
返回true
即忽略大小写也返回全局则为ig

正则表达式两大特性

1.懒惰,解决方案使用全局标识符g
2.贪婪

var reg = /\d{1,4}/

console.log(reg.exec("a123456bb"))

如上就会输出1234,他会按照最大的捕获
3.非贪婪

var reg = /\d{1,4}?/

console.log(reg.exec("a123456bb"))

如上就会输出1,这里他会越少越好

正则和字符串方法

replace

var str = "aderaffa"

var newstr = str.replace(/a/g,"*")

如上就成功替换所有的a为*
记得加g

search

var str = "aderaffa"
使用search找a则只会返回0,它只会返回遇到的第一个

match
捕获内容

var day = " day is  from 2023-01-01 to 2034-01-01"
console.log(day.match(/\d{4}-\d{1,2}-\d{1,2}/g))

案例:密码强度

需求
只有数字或者字母则显示弱
有数字和字母和特殊符号中两种混杂则显示中
数字、字母、特殊符号混杂则显示强

label
input type="text"
label

p
span弱
span中
span强
p

如上就是一个案例html概览
下面写JS

var oinput = document.querySelector("input")
var ospan = document.querySelectorAll("span")
var reg1 = /\d/
var reg2 = /[a-z]/i
var reg3 = /[!@#$%^&*()]/

oinput.oninput = function(){
   console.log(this.value)
   var level = 0 //必须在里面,如果在外边则会累加,在里面,每重输入则清除重来

   if(reg1.test(this.value)) level++
   if(reg2.test(this.value)) level++
   if(reg3.test(this.value)) level++

   for(i=0;i<ospan.length;i++){
   	ospan[i].classList.remove("active")//记得加上,要不然会回不去的
   	if(i<level){
   	ospan[i].classList.add("active")
   	}
   }
}

this

关键字
谁调用指向谁

this指向

事件绑定中的this
div id=“box”

box.onclick = function(){
	console.log(this)
}

这里就拿到了div节点

改变this指向

var obj1= {
	name:"obj1",
	getName:function(){
		console.log("getName1",this.name)
	}
}
var obj2= {
	name:"obj2",
	getName:function(){
		console.log("getName2",this.name)
	}
}

call 执行函数冰改变this执行为函数的第一个参数
obj1.getName.call(obj2)
obj1.getName.call(obj2,1,2,3)

apply
obj1.getName.apply(obj2)
obj1.getName.apply(obj2,[1,2,3])

bind
改变this指向为函数的第一个参数,不会自动执行函数
var fun1 = obj1.getName.bind(obj2)
console.log(fun1)

ES6

定义变量

let

let a = 100

与var区别
1.必须先定义后使用
2.变量重名
3.块级作用域

if(true){
	let i=100
	console.log(i)
}

console.log(i)

在这里我们就会报错

const

const给常量
let是变量

箭头函数

var test = function(){
	console.log("111")
}

var test2 = () =>{
	console.log(222)
}

上面两者是等价的
1.()可以省略:只有一个形参的时候
2.{}可以省略:只有一句代码,只有返回值时
3.没有arguments
4.this,箭头函数this时父级作用域的

解构赋值

快速从对象和数组中获取里面的成员

var arr = ["asc","scd","swfa"]

let[x] = arr

console.log(x)
//输出asc
let[x,y,z] = arr
console.log(x,y,z)
//输出三个
var obj ={
	name:"kes",
	age:23,
	location:"sl"
}
let {name,age,location} = obj
这样就可以快速获对象值

展开运算符


合并数组

var a = [1,2,3]
var b = [4,5,6]

var c = [...a,...b]
var test = (...arr) =>{
	console.log(arr)
}
test(1,2,3)

对象

var obj1 = {
	name:"kew",
	age:10
}
var obj2 ={
	location:"da"
}
var obj = {
	...obj1,
	...obj2
}

模块化语法

模块化

导出

export{
 fun1,
 fun2
 }

导入

<script type = "module">
	import{fun1,fun2} from"./文件"
</script>

重名解决

<script type = "module">
	import{fun1,fun2,test as A_test} from"./文件"
	import{funa,funb,test as B_test} from"./文件"
</script>

面向对象

首先,我们要明确,面向对象不是语法,是一个思想,是一种编程模式
面向: 面(脸),向 (朝着)
面向过程: 脸朝着过程 =》 关注着过程的编程模式
面向对象: 脸朝着对象=》 关注着对象的编程模式实现一个效果
1.在面向过程的时候,我们要关注每一个元素,每一个元素之间的关系,顺序,。。。
2.在面向过程的时候,我们要关注的就是找到一个对象来帮我做这个事情,我等待结果0
我们以前的编程思想是,每一个功能,都按照需求一步一步的逐步完成。

创建对象的方式

工厂函数

function createObj(){
	var obj = {}
	obj.name = "ss"
	obj.material = []
	return obj
}
var obj1 = createObj()

自定义构造函数

function createObj(name){
	this.name = name
	this.material = []
	this.cook = function(){
	}
}

var obj1 = new createObj()

Tips:
1.首字母大写
2.构造函数不写return
3.构造函数能当成普通函数用

原型

<div class="box1">
    <h1></h1>
    <ul></ul>
</div>

<div class="box2">
    <h1></h1>
</div>
<script>
    var data = {
        title:"体育"
        list:["PE1","PE2","PE3"]
    }
    function CreateList(select,data){
        this.ele = document.querySelector(select)
        this.title = title,
        this.list = list

        this.render = function(){
            var h1 = this.ele.querySelector("h1")
            var ul = this.ele.querySelector("ul")

            h1.innerHTML = this.title
            ul.innerHTML = this.list.map(item =>'<li>${item}</li>').join
        }
    }
    var obj1 = new CreateList(data.title,data.list)
    obj1.render()
</script>

class

function CreateObj(name){
    this.name =name
}
CreateObj.prototype.say = function(){
    console.log(this.name,"hello")
}
//构造器函数
class CreateObj {
    constructor(name){
        this.name = name
    }
}

var obj = new CreateObj("KS")

继承

构造函数继承 --继承属性
原型继承===继承原型上方法
组合继承 ==构造函数继承+原型继承

//父类
class Person{
    constructor(name,age){
        this.name =name
        this.age = age
    }
    say(){
        console.log(this.name,"hew")
    }
}
//子类
//extends 原型继承
class Student extends Person{
    constructor(name,age,grade){
        super(name,age) //Person.call(this,name,age)
        this.grade = grade
    }
}

var obj =new Student()

ajax

创建XHR

var xhr = new XMLHttpRequest()

配置 open(请求方式,请求地址,是否异步)
send

xhr.send()

接受数据注册事件

xhr.onreadystatechange = function(){
    
}

状态码

ajax 状态码-xhr.readystate

是用来表示一个 ajax 请求的全部过程中的某一个状态
readyState === 0 :表示未初始化完成,也就是 open 方法还没有执行
readystate === 1 表示配置信息已经完成,也就是执行完 open 之后
readyState === 2 表示 send 方法已经执行完成
readystate === 3:表示正在解析响应内容
readystate === 4: 表示响应内容已经解析完毕,可以在客户端使用了

这个时候我们就会发现,当一个ajax 请求的全部过程中,只有当 readystate === 4 的时候,我们才可以正常使用服务端给我们的数据

所以,配合 http 状态码为 200 - 299
一个ajax对象中有一个成员叫做 xhr.status
这个成员就是记录本次请求的 http 状态码的

两个条件都满足的时候,才是本次请求正常完成

readyStateChange

在ajax 对象中有一个事件,叫readystatechange事件
这个事件是专门用来监听 ajax 对象的 readystate 值改变的的行为
也就是说只要 readystate 的值发生变化了,那么就会触发该事件
所以我们就在这个事件中来监听 ajax 的 readystate 是不是到4了

异步同步

var xhr = new XMLHttpRequest()
xhr.open("GET","1.json",true)
// true表示异步请求
// false表示同步请求
xhr.send()
xhr.onload = function(){
    if(xhr.status === 200){
        console.log(xhr.responseText)
    }
}
console.log("111")

如上的true则先打印111后打印上面的
如果为false则打印111后面不打印

请求方式

get 偏向获取数据
post 偏向提交数据
put 偏向更新
delete 偏向删除信息
patch 偏向部分修改
header
options
connect

回调地狱

当一个回调函数嵌套一个回调函数的时候
就会出现一个嵌套结构
当嵌套的多了就会出现回调地狱的情况
比如我们发送三个 ajax 请求
第一个正常发送
第二个请求需要第一个请求的结果中的某一个值作为参数
第三个请求需要第二个请求的结果中的某一个值作为参数

Promise

语法

promise 是一个ES6 的语法
承诺的意思,是一个专门用来解决异步 回调地狱 的问题

var q = new Promise(function(){

})
q.then(function(){
    //兑现承诺,执行
}).catch(function(){
    //拒绝承诺,执行
})
var q = new Promise(function(resolve,reject){
    //异步
    setTimeout(() => {
        resolve()
    }, 2000);
})
q.then(function(){
    //兑现承诺,执行
    console.log("OK")
}).catch(function(){
    //拒绝承诺,执行
    console.log("NO")
})

封装Ajax

function pajax(options){
    return new Promise((resolve,reject)=>{
        ajax({
            ...options,
            success(res){
                resolve(res)
            },
            error(err){
                reject(err)
            }
        })
    })
}

ASYNC/AWAIT

async/await 是一个es7的语法
这个语法是回调地狱的终极解决方案
语法:

async function fn(){
    const res = await Promise对象
}

这个是一个特殊的函数方式
可以await 一个 promise 对象
可以把异步代码写的看起来像同步代码
只要是一个 promiser 对象,那么我们就可以使用 async/await 来书写

function pajax(options){
    return new Promise((resolve,reject)=>{
        ajax({
            ...options,
            success(res){
                resolve(res)
            },
            error(err){
                reject(err)
            }
        })
    })
}

import {pajax} from './..js'
async function test(){
    //await 同步代码/Promise对象
    var res = await pajax({
        URL:"http://localhost:3000/news",
        data:{
            author:"KS"
        }
    })
    console.log(res)
    console.log(222)
}
test()

fetch

XMLHttpRequest 是一个设计粗的AP),配置和调用方式非常混乱,而且基于事件的异步模型写起来不友好。

fetch("http://localhost:3000/users").then(res=>{
    return res.json()//promise对象
}).then(res=>{
    console.log(res)
})

//简化
fetch("http://localhost:3000/users").then(res=>res.json()).then(res=>{
    console.log(res)
})
var username = "SL"
fetch("http://localhost:3000/users?username=${username}").then(res=>{
    console.log(res)
    if(res.ok){
        return res.json()
    }else{
        //拒绝
        return Promise.reject
    }
}
).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log("error",err)
})

POST

fetch("http://localhost:3000/users",{
    method:"POST",
    headers:{
        "content-type":"application/json"
    },
    body:JSON.stringify({
        username:"KS",
        // password:"234"
    })
})
.then(res=>res.json())
.then(res=>{
    console.log(res)
})

PATCH只需把上面的POST改一下就行了

cookie

存cookie

BigInt.onclick = function(){
    document.cookie = "username=ks"
}

过期时间

function(){
    document.cookie = "age=18"
    //过期时间设置
    var date = new Date()
    date.setMinutes(date.getMinutes()+1)
    document.cookie = 'username = kks;expires = ${date.toUTCString}'
}

获取cookie

function getCookie(key){
    var str = document.cookie
    var arr = str.split(";")
    console.log(arr)
    return
}

jsonp

Jsonp(JSON with Padding)是 son 的一种”使用模式”,可以让网页从别的域名 (网站)那获取资料,即跨域读取数据。
为什么我们从不同的域(网站) 访问数据需要一个特殊的技术(JSONP)呢? 这是因为同源策略。

同源策略:同域名 同端口号 同协议
不符合同源策略,浏览器为了安全,会阻止请求

解决
1.cors 由后端设置,Access-Control-Allow-Origin
2.jsonp:前后端协作

jsonp原理:动态创建script标签,src属性指向没有跨域限制
指向一个接口,接口返回的格式一定是 ****() 函数表达式

function test(obj){
    console.log(obj)
}

BigInt.onclick = function(){
    var oscript = document.createElement("script")
    oscript.src=""//未来地址
    document.body.appendChild(oscript)
}

Tips:
1.后端接口形式必须** (),需要后端配合
2.jsonp 缺点
(1) onload 删除sciprt标签
(2) 只能get请求,不能post、put、delete

闭包

函数内部返回函数,被外界引用,这个内部函数就不会被销毁回收
内部函数所用到的外部函数变量也不会被销毁

function outer(){
    var name = "ks"
    var age = 100
    return function(){
        return name+"111"
    }
}

var func = outer()

优点:让临时变量永驻内存
缺点:内存泄露

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值