前端常见面试题(十四)@郝晨光


怎样添加、移除、复制、创建、查找节点

  1. 创建节点
document.createDocumentFragment(); // 创建一个空的虚拟节点,一个DOM片段
document.createEelement(TagName); // 创建指定的DOM节点
document.createTextNode(); // 创建一个文本节点
document.createAttribute(); // 创建一个属性节点
document.createComment(); // 创建一个注释节点
  1. 删除(移除)节点
parentNode.removeChild('需要删除的子节点'); // 删除,利用父元素节点删除子节点
element.remove(); // 删除自身,兼容性不好
  1. 添加节点
parentNode.appendChild('子节点'); // 给父元素节点添加子节点
parentNode.append('节点','节点','节点','···'); // 添加子节点,参数可以是多个节点,兼容性不好
parentNode.insertBefore('新节点', '旧节点'); // 将一个新节点插入到一个旧节点之前。
  1. 替换节点
parentNode.replaceChild('新节点', '旧节点'); // 调用父节点的方法,用一个新节点替换掉一个旧节点
  1. 复制节点
element.cloneNode('布尔值'); 
// 克隆节点。如果参数为true的话,会递归复制当前元素的所有子孙节点。否则的话只复制当前节点本身。
  1. 查找节点
    通过document查找。
document.getElementById(); // 通过ID查找DOM元素;
document.getElementsByTagName(); // 通过标签选择器查找DOM元素;可以是 '*',返回当前所有的DOM节点。
document.getElementsByClassName(); // 通过class类名查找DOM元素;返回一个NodeList伪数组。
document.getElementsByName(); // 通过name属性查找DOM元素;返回所有name符合的元素。
document.querySelector(); // HTML5新增,通过CSS选择器选择元素,返回匹配的第一个元素。
document.querySelectorAll(); // HTML5新增,通过CSS选择器选择元素,返回匹配的所有元素组成的NodeList。
document.forms;  // 返回当前文档中的所有form表单。
document.images; // 返回当前文档中的所有img图片。
document.scripts; // 返回当前文档中所有的script脚本。
document.activeElement; // 返回当前获取焦点的节点。
document.documentElement; // 返回当前文档的根节点。
document.body; // 返回当前文档的body节点。

通过element查找。

element.childNodes; // 返回当前节点的所有子节点(包括文本节点和空白节点)。
element.children; // 返回当前节点的所有子元素节点。
element.firstChild; // 返回当前节点的第一个子节点(包括空白节点,文本节点)。
element.firstElementChild; // 返回当前节点的第一个元素节点。
element.lastChild; // 返回当前元素的最后一个子节点(包括空白节点,文本节点)。
element.lastElementChild; // 返回当前节点的最后一个元素节点。
element.nextSibling; // 返回当前节点的下一个兄弟节点(包括空白节点,文本节点)。
element.nextElementSibling; // 返回当前节点的下一个兄弟元素节点。
element.previousSibling; // 返回当前节点的上一个兄弟节点(包括空白节点,文本节点)。
element.previousElementSibling; // 返回当前节点的上一个兄弟元素节点。
element.parentNode; // 返回当前节点的父节点。
element.parentElement; // 返回当前节点的父元素节点。 // IE9以下不兼容。


JQuery的事件委托on、live、delegate之间有什么区别

  1. live
    定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;
    语法:live(type, [data], fn);
    特点:

    1. live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。
    2. live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。
    3. 使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即("ul").live...可以,但(“ul”).live…可以,但(“body”).find(“ul”).live…不行;
  2. delegate
    定义和用法:将监听事件绑定在就近的父级元素上;
    语法:delegate(selector,type,[data],fn)
    特点:

    1. 选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。
    2. 更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。
  3. on
    定义和用法:将监听事件绑定到指定元素上。
    语法:on(type,[selector],[data],fn)
    参数的位置写法与delegate不一样。
    说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

  4. 它们三个之间的区别

live 把事件委托交给了document(根节点),document 向下去寻找符合条件的元素, 不用等待document加载结束也可以生效。
delegate可指定事件委托对象,相比于live性能更优,直接锁定指定选择器;
on事件委托对象选填,如果不填,即给对象自身注册事件,填了作用和delegate一致。
原生js面试题 - 刘悦Lau



描述一次完整的http请求过程(输入url敲回车发生了什么)

  1. 当我们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址

  2. 浏览器查找域名的 IP 地址。请求一旦发起,浏览器首先要做的事情就是解析这个域名,一般来说,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。如果在本地的 hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS(因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析))请求到本地DNS服务器 。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询。本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

image

  1. 浏览器向 web 服务器发送一个 HTTP 请求。在通过DNS域名解析后,获取到了服务器的IP地址,在获取到IP地址后,便会开始建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接:

    第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;

    第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

    第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

image

  1. 浏览器向服务器发送HTTP请求

  2. 服务器返回一个 HTTP 响应,浏览器接收响应

    服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,响应头,响应报文三个部分。

    状态码主要包括以下部分

    • 1xx:指示信息–表示请求已接收,继续处理。
    • 2xx:成功–表示请求已被成功接收、理解、接受。
    • 3xx:重定向–要完成请求必须进行更进一步的操作。
    • 4xx:客户端错误–请求有语法错误或请求无法实现。
    • 5xx:服务器端错误–服务器未能实现合法的请求。
    • 响应头主要由Cache-Control、 Connection、Date、Pragma等组成。
    • 响应体为服务器返回给浏览器的信息,主要由HTML,css,js,图片文件组成。
  3. 页面渲染。如果说响应的内容是HTML文档的话,就需要浏览器进行解析渲染呈现给用户。整个过程涉及两个方面:解析和渲染。在渲染页面之前,需要构建DOM树和CSSOM树。

image

image

在浏览器还没接收到完整的 HTML 文件时,它就开始渲染页面了,在遇到外部链入的脚本标签或样式标签或图片时,会再次发送 HTTP 请求重复上述的步骤。在收到 CSS 文件后会对已经渲染的页面重新渲染,加入它们应有的样式,图片文件加载完立刻显示在相应位置。在这一过程中可能会触发页面的重绘或重排。这里就涉及了两个重要概念:Reflow和Repaint。

Reflow,也称作Layout,中文叫回流,一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树,这个过程称为Reflow。

Repaint,中文重绘,意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就OK了,这个过程称为Repaint。

所以说Reflow的成本比Repaint的成本高得多的多。DOM树里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。

下面这些动作有很大可能会是成本比较高的:
1. 增加、删除、修改DOM结点时,会导致Reflow或Repaint
2. 移动DOM的位置,或是搞个动画的时候
3. 内容发生变化
4. 修改CSS样式的时候
5. Resize窗口的时候(移动端没有这个问题),或是滚动的时候
6. 修改网页的默认字体时
基本上来说,reflow有如下的几个原因:
1. Initial,网页初始化的时候
2. Incremental,一些js在操作DOM树时
3. Resize,其些元件的尺寸变了
4. StyleChange,如果CSS的属性发生变化了
5. Dirty,几个Incremental的reflow发生在同一个frame的子树上
7. 关闭TCP连接或继续保持连接
通过四次挥手关闭连接(FIN ACK, ACK, FIN ACK, ACK)。

image

第一次挥手是浏览器发完数据后,发送FIN请求断开连接。
第二次挥手是服务器发送ACK表示同意,如果在这一次服务器也发送FIN请求断开连接似乎也没有不妥,但考虑到服务器可能还有数据要发送,所以服务器发送FIN应该放在第三次挥手中。
这样浏览器需要返回ACK表示同意,也就是第四次挥手。
至此从浏览器地址栏输入URL到页面呈现到你面前的整个过程就分析完了!!!

本题原文链接:从输入url到页面展示到底发生了什么@小四 – 王云飞_小四_wyunfei



如果本文对您有帮助,可以看看本人的其他文章:
原生JS - 瀑布流布局@郝晨光
原生JS - 图片懒加载@郝晨光
Koa - Node.js框架学习@郝晨光

结言
感谢您的查阅,本文由郝晨光整理并总结,代码冗余或者有错误的地方望不吝赐教;菜鸟一枚,请多关照
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值