说一下js的事件冒泡、事件捕获、事件委托
js可以通过 addEventListener
为元素绑定事件, 一共有三个参数
第一个参数是 event
,绑定的事件,比如click
,mounseover
等
第二个参数是 事件触发时执行的回调函数,函数的参数是e
,事件对象,上面有很多元素的属性
第三个参数是 useCapture
,是个布尔值,默认是false
,false
表示在冒泡阶段执行, true
表示在捕获阶段执行。
冒泡是从里向外,捕获是从外向里,如果同时存在,会先触发捕获,后触发冒泡。
可以使用 e.stopPropagation()
阻止冒泡。
事件委托是利用冒泡机制,在父元素上绑定事件 操作子元素的一种技术,原先需要在所有子元素上绑定事件,只需要绑定在共同的父元素上,就可以实现同样的操作。
有两个属性需要特殊记一下。
e.target
实际点击的dom e.currentTarget
绑定事件的dom
说下 js 的事件循环
js是的可以异步编程就是因为有事件循环,js代码执行顺序
js有调用栈、微任务队列,宏任务队列,都是先进先出。
调用栈为空后,先执行微任务队列,再执行宏任务队列,每执行一个宏任务后,都需要再次查看微任务队列是否为空,不为空 继续先执行微任务。
因为执行宏任务的过程中可能产生微任务。
常见的宏任务有,setTimeout、setInterval、用户交互事件,requestAnimationFrame
常见的微任务有,promise.then.catch,mutationObserver
说下浏览器的缓存策略,强缓存、协商缓存
浏览器有两种缓存策略,强缓存和协商缓存,都是为了优化性能的,默认先走强缓存,没有强缓存再走协商缓存,都没有就直接请求。都是通过响应头控制的。
强缓存有两个
expires 和 catch-control。expires是http1.0有的,比较古老
expires后端会设置一个过期时间,浏览器会通过本地时间和过期时间比对,未超出,就从缓存中读取,超出就从服务器重新获取。
catch-control是http1.1的,比较新,更推荐。它有五个值。no-catch 不走强缓存,走协商。no-store 啥缓存都不走。max-age 设置过期时间,单位秒。 public 资源可以被浏览器缓存,也可以被代理服务器缓存。private 资源只可以被浏览器缓存。
如果expires和catch-control同时出现,优先catch-control。
协商缓存有两个,是成对出现的
last-modify : if-modify-since
etag : if-none-match
last-modify 是判断文件的最后修改时间控制缓存,etag是判断文件内容,返回值是个hash。
第一次访问,设置响应头,last-modify,给个文件最后修改时间,第二次访问 浏览器请求头上会带上 if-modify-since 值是上次 last-modify 的值, 服务器端就会比对,如果文件未修改,状态码设为304,结束,浏览器发现状态码是304,从缓存读取,如果修改,状态码200,返回新的资源,更新 last-modify
etag是一样的,设置etag,是一串hash值,下次访问,浏览器带上if-none-match 一致,返回304,不一致,更新。
last-modify 的精度只能到秒,一秒内多次修改,就有问题了。
etag需要计算hash,会增加服务器负担,各有利弊。