浏览器地址栏输入URL敲回车之后发生了哪些事

判断输入的是 URL 还是搜索的关键字 转换非 ASCII 的 Unicode 字符 比如:中文、空格 检查HSTS 列表 浏览器检查自带的“预加载 HSTS(HTTP严格传输安全)”列表,这个列表里包含了那些请求浏览器只使用HTTPS进行连接的 URL,如果这个 URL在列表里,则默认使用 HTTPS 协议而不是 HTTP 协议 查找域名的 IP 地址 查找浏览器的 DNS 缓存,没找到则执行下一步 查找操作系统中的 DNS 缓存,没找到则执行下一步 查找 OS 中的 hosts 文件,没找到则执行下一步 在 OS 的 LDNS 中查找域名对应的 IP(这一步可能会遇到 DNS 污染,解决方案为:1. 切换 DNS 服务器;2. 清空 DNS 缓存;3. 修改系统 hosts 文件,将域名与对应的 IP 地址绑定写死),没找到则发起一个迭代 DNS 解析请求 LDNS 向 根域名服务器 发起请求,RDNS 返回 一级域名 对应的 IP 地址 LDNS 向 一级域名服务器 发起请求,得到 二级域名 对应的 IP 地址 LDNS 向 二级域名服务器 发起请求,得到 三级域名 对应的 IP 地址 LDNS 将得到的 IP 地址返回给 OS,并且将这个 IP 地址缓存起来 OS 将 IP 地址返回给浏览器,并且将这个 IP 地址缓存起来 浏览器得到域名对应的 IP 地址,并且将这个 IP 地址缓存起来 建立 TCP 连接 ...

November 18, 2019 · 3 min · Zink

Call & Apply & Bind实现

call && apply && bind 的作用 call、apply、bind的作用都是改变函数的 this 指向 call:call 的第一个参数就是对函数绑定的 this,为一个对象,后面的参数是函数调用时所需要的参数 apply:apply 只接受两个参数,第一个与 call 相同,第二个参数是为数组,内容是函数调用所需要的参数 bind:bind 与 call作用相同,不过 bind 会返回一个新的函数,第一个参数之后的参数将绑定原函数的参数。 实现 call 先来看看原生call的使用方法 let obj = { a: 1 } function fn(){ console.log(this.a) } fn() // undefined fn.call(obj) // 1 call 是如何将 this 绑定到 obj 上的呢? 我们换一种思路,先看下面的代码 let obj = { a: 1, fn(){ console.log(this.a) } } obj.fn() // 1 这段代码大家都能理解对吧,接下来,让我们打开脑洞。 如果 call 只是将调用函数绑定到了第一个参数身上呢?似乎一切就说得通了 function fn(){ console.log(this.a) } Function.prototype.myCall = function(context){ context = context || window //首先判断是否传入第一个参数,如果没传,那么 this 就默认绑定到 window context.callFn = this let result = context.callFn() delete context.callFn return result } let obj = { a: 1 } fn.myCall(obj) // 1 ok,初步绑定 this 的工作我们已经完成,接下来思考如何将剩下的参数传给调用函数。 ...

September 24, 2019 · 2 min · Zink

Input中如何处理中文输入防抖

防抖 函数防抖和节流,都是控制事件触发频率的方法。具体实现可以看我的这篇文章 input 如何处理中文输入 如果只是单纯的使用 input 事件来监听 input 值的改变,那么每次敲击键盘,输入一个字母都会触发 input 事件,其实我们想要的是获取用户输入的中文再进行后续操作。 我们可以假象一下,输入中文时的字母都是预输入,只有当选择候选词之后,input得到的值才是我们想要的。 现在,向大家介绍两个新的 DOM 事件:compositionstart、compositionend compositionstart:compositionstart 事件触发于一段文字的输入之前 compositionend:当文本段落的组成完成或取消时, compositionend 事件将被触发 <input type="text"> let inputElement = document.querySelector('input') let canRun = true inputElement.addEventListener('compositionstart', function(){ console.log('start') canRun = false }) inputElement.addEventListener('compositionend', function(){ console.log('end') canRun = true }) inputElement.addEventListener('input', debounce(fn)) function debounce(fn) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments) }, 500) }; } function fn(e){ if(canRun){ console.log(e.target.value) } } 当我们切换到中文输入法输入时开始在 input 中输入时,compositionstart 的回调函数被调用,将 canRun 状态切换为 false,半秒后执行 fn 时,canRun 状态为 false,不进行任何操作,当中文输入结束后,compositionend 的回调函数被调用,将 canRun 变为 true,此时 input 的回调函数调用,就可以执行后续的操作了,其实就是利用了 compositionstart 和 compositionend 来切换状态机的状态

September 23, 2019 · 1 min · Zink

这一次,我一定会搞定 This !

迫于 迫于在写 React 事件处理中的 this 时,写到 this 突然卡壳了,一顿冷静分析之后发现自己对于 this 的理解又忘了一些,于是痛定思痛,重新读了 《You-Dont-Know-JS》中关于 this 的文章。 函数的执行环境 首先上一段代码 function fn(){ console.log(this.a) } let obj = { a: 1, fn: fn } var a = 'window' fn() //window obj.fn() //1 首先我们要明确一点 ,this 不是编写代码时就绑定的,而是运行时绑定的。 比如 fn() 在调用时,所处的环境是 global,所以他的 this 就是 window 而 obj.fn() 在调用时,所处的环境是在对象 obj 内,所以他的 this 指向 obj 对象 当一个函数被调用时,会建立一个称为执行环境的活动记录。这个记录包含函数是从何处(调用栈 —— call-stack)被调用的,函数是 如何 被调用的,被传递了什么参数等信息。这个记录的属性之一,就是在函数执行期间将被使用的 this 引用。 所以,this是根据调用点(函数如何被调用)来为每次函数调用建立的绑定 调用点的规则 默认绑定: 首先是独立函数调用。在这种倾向下,this 规则是在没有其他规则适用时的默认规则。 function fn(){ console.log(this) } fn() //window fn() 被独立调用,此时的 this 是默认绑定,所以 this 指向了 window ...

September 16, 2019 · 2 min · Zink

防抖和节流

什么是防抖?如何实现? 动作绑定事件,动作发生后一定时间后触发事件,在这段时间内,如果该动作又发生,则重新等待一定时间再触发事件。 实现:每次触发事件时都取消之前的延时调用方法。 function debounce(fn) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, arguments) }, 500) }; } 什么是节流?如何实现? 动作发生后一段时间后触发事件,在这段时间内,如果动作又发生,则无视该动作,直到事件执行完后,才能重新触发。 实现:每次触发事件时都判断当前是否有等待执行的延时函数,如果有,则无视该次动作。 function throttle(fn) { let canRun = true; return function() { if (!canRun) return; canRun = false; setTimeout(() => { fn.apply(this, arguments); canRun = true; }, 500); }; } 区别 防抖和节流的区别在于: 防抖的思路是:指定事件触发的函数在一定时间后执行,如果在这段时间内再次触发该事件,那么便取消上一次的执行。 节流的思路是:指定事件触发的函数在一定时间后执行,如果在这段时间内再次触发该事件,那么便无视该次事件动作。

August 6, 2019 · 1 min · Zink