前端面试题总结之Js部分
·说说前端中的事件流
什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。
事件捕获阶段
处于目标阶段
事件冒泡阶段
addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
IE只支持事件冒泡。
·如何让事件先冒泡再捕获
根据w3c标准,应先捕获再冒泡。若要实现先冒泡后捕获,给一个元素绑定两个addEventListener,其中一个第三个参数设置为false(即冒泡),另一个第三个参数设置为true(即捕获),调整它们的代码顺序,将设置为false的监听事件放在设置为true的监听事件前面即可。
·什么是事件委托
举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。
好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。
【ev.currentTarget:返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口 ,ev.target:返回触发此事件的元素】
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge" /> 8 <title>Document</title> 9 <script> 10 11 window.onload = function () { 12 var oUl = document.getElementById("ul1"); 13 oUl.onclick = function (ev) { //将事件绑定到li节点的父节点ul上 14 var e = ev || window.event; //兼容IE浏览器事件对象 15 var target = e.target || window.event.srcElement; 16 if (target.nodeName.toLowerCase() == "li") { //判断触发事件的元素名称是否li 17 target.style.backgroundColor = 'red'; 18 } 19 } 20 var oBtn = document.getElementById("btn1"); 21 var i = 6; 22 oBtn.onclick = function () { 23 var newNode = document.createElement("li"); 24 newNode.innerHTML = i++ * 1111; 25 oUl.appendChild(newNode); 26 } 27 } 28 </script> 29 </head> 30 31 <body> 32 <button id='btn1'>新增节点</button> 33 <ul id='ul1'> 34 <li>1111</li> 35 <li>2222</li> 36 <li>3333</li> 37 <li>4444</li> 38 <li>5555</li> 39 </ul> 40 </body> 41 42 </html>
·说一下图片的懒加载和预加载
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。
懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
·mouseover和mouseenter的区别
mouseenter:当鼠标移入元素本身(不包含元素的子元素)会触发事件,也就是不会冒泡,对应的移除事件是mouseleave
·js的new操作符做了哪些事情
new操作符新建了一个空对象,这个对象原型指向构造函数的prototype,执行构造函数后返回这个对象
·改变函数内部this指针的指向函数(bind,apply,call的区别)
在js中,每个函数的原型都指向Function.prototype对象(js基于原型链的继承)。因此,每个函数都会有apply,call,和bind方法,这些方法继承于Function。
它们的作用是一样的,都是用来改变函数中this的指向。
都是改变函数this指向的,第一个参数都是this要指向的对象。
apply的参数是数组形式的:func.apply(obj,[x,y,z]),call的参数是arg1,arg2,···形式的,如func.call(obj,x,y,z);这两种方法的函数会立即调用;
bind的参数也是一个个传入的,和call一样,不同的是,bind绑定的函数不会立即执行,需要调用才会执行。