不常用却很有妙用的事件及方法

1 visibilitychange事件 触发条件:浏览器标签页被隐藏或显示的时候会触发visibilitychange事件. 使用场景:当标签页显示或者隐藏时,触发一些业务逻辑 document.addEventListener("visibilitychange", function() { console.log( document.visibilityState ); }); 2 storage事件 触发条件:使用localStorage or sessionStorage存储或者修改某个本地存储时 使用场景:标签页间通信 // AB页面同源 // 在A 页面 window.addEventListener('storage', (e) => {console.log(e)}) // 在B 页面,向120打个电话 localStorage.setItem('makeCall','120') // 然后可以在A页面间有输出, 可以看出A页面 收到了B页面的通知 ...key: "makeCall", oldValue: "119", newValue: "120", ... 3 beforeunload事件 触发条件:当页面的资源将要卸载(及刷新或者关闭标签页前). 当页面依然可见,并且该事件可以被取消只时 使用场景:关闭或者刷新页面时弹窗确认,关闭页面时向后端发送报告等 window.addEventListener("beforeunload", function (e) { var confirmationMessage = "\o/"; e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+ return confirmationMessage; // Gecko, WebKit, Chrome <34 }); 4 navigator....

2018-02-11 14:34:17 · 1 min · Eddie Wang

mac vscode 更新失败 Permission denied解决办法

0. 现象 Could not create temporary directory: Permission denied 1. 问题起因 在 /Users/username/Library/Caches/目录下,有以下两个文件, 可以看到,他们两个的用户是不一样的,一个是root一个username, 一般来说,我是以username来使用我的mac的。就是因为这两个文件的用户不一样,导致了更新失败。 drwxr-xr-x 6 username staff 204B Jan 17 20:33 com.microsoft.VSCode drwxr--r-- 2 root staff 68B Dec 17 13:51 com.microsoft.VSCode.ShipIt 2. 解决方法 注意: 先把vscode 完全关闭 // 1. 这一步是需要输入密码的 sudo chown $USER ~/Library/Caches/com.microsoft.VSCode.ShipIt/ // 2. 这一步是不需要输入密码的, 如果不进行第一步,第二步会报错 sudo chown $USER ~/Library/Caches/com.microsoft.VSCode.ShipIt/* // 3. 更新xattr xattr -dr com.apple.quarantine /Applications/Visual\ Studio\ Code.app 3. 打开vscode Code > Check for Updates, 点击之后,你会发现Check for Updates已经变成灰色了,那么你需要稍等片刻,马上就可以更新,之后会跳出提示,让你重启vscode, 然后重启一下vscode, 就ok了。...

2018-02-11 14:20:01 · 1 min · Eddie Wang

IE11 0x2ee4 bug 以及类似问题解决方法

一千个IE浏览器访问同一个页面,可能报一千种错误。前端激进派对IE恨得牙痒痒,但是无论你爱,或者不爱,IE就在那里,不来不去。 一些银行,以及政府部门,往往都是指定必须使用IE浏览器。所以,一些仅在IE浏览器上出现的问题。总结起来问题的原因很简单:IE的配置不正确 下面就将一个我曾经遇到的问题: IE11 0x2ee4, 以及其他的问题的解决方案 1. IE11 SCRIPT7002: XMLHttpRequest: 网络错误 0x2ee4 背景介绍:在一个HTTPS域向另外一个HTTPS域发送跨域POTST请求时 这个问题在浏览器的输出内容如下,怪异的是,并不是所有IE11都会报这个错误。 SCRIPT7002: XMLHttpRequest: 网络错误 0x2ee4, 由于出现错误 00002ee4 而导致此项操作无法完成 stackoverflow上有个答案,它的思路是:在post请求发送之前,先进行一次get操作 这个方式我试过,是可行的。但是深层次的原因我不是很明白。 然而真相总有大白的一天,其实深层次的原因是,IE11的配置。 去掉检查证书吊销的的检查,解决0x2ee4的问题 解决方法 去掉check for server certificate revocation*, 也有可能你那边是中文翻译的:叫检查服务器证书是否已吊销 去掉检查发型商证书是否已吊销 点击确定 重启计算机 2 其他常规设置 2.1 去掉兼容模式, 使用Edge文档模式 下图中红色框里的按钮也要取消勾选 2.2 有些使用activeX,还是需要检查是否启用的 2.3 允许跨域 如果你的接口跨域了,还要检查浏览器是否允许跨域,否则浏览器可能默认就禁止跨域的 设置方法 internet选项 安全 自定义级别 启用通过跨域访问数据源 启用跨域浏览窗口和框架 确定 然后重启电脑

2018-02-11 14:12:19 · 1 min · Eddie Wang

Vue+ElementUI 手把手教你做一个audio组件

1. 简介 1.1. 相关技术 Vue Vue-cli ElementUI yarn (之前我用npm, 并使用cnpm的源,但是用了yarn之后,我发现它比cnpm的速度还快,功能更好,我就毫不犹豫选择yarn了) Audio相关API和事件 1.2. 从本教程你会学到什么? Vue单文件组件开发知识 Element UI基本用法 Audio原生API及Audio相关事件 音频播放器的基本原理 音频的播放暂停控制 更新音频显示时间 音频进度条控制与跳转 音频音量控制 音频播放速度控制 音频静音控制 音频下载控制 个性化配置与排他性播放 一点点ES6语法 2. 学前准备 基本上不需要什么准备,但是如果你能先看一下Aduio相关API和事件将会更好 Audio: 如果你愿意一层一层剥开我的心 使用 HTML5 音频和视频 3. 在线demon 没有在线demo的教程都是耍流氓 查看在线demon 项目地址 4. 开始编码 5. 项目初始化 ➜ test vue init webpack element-audio A newer version of vue-cli is available. latest: 2.9.2 installed: 2.9.1 ? Project name element-audio ? Project description A Vue.js project ?...

2018-02-09 13:44:13 · 7 min · Eddie Wang

你不知道的JSON.stringify()妙用

1. 语法 JSON.stringify(value[, replacer[, space]]) 一般用法: var user = {name: 'andy', isDead: false, age: 11, addr: 'shanghai'}; JSON.stringify(user); "{"name":"andy","isDead":false,"age":11,"addr":"shanghai"}" 2. 扩展用法 2.1. replacer replacer可以是函数或者是数组。 功能1: 改变属性值 将isDead属性的值翻译成0或1,0对应false,1对应true var user = {name: 'andy', isDead: false, age: 11, addr: 'shanghai'}; JSON.stringify(user, function(key, value){ if(key === 'isDead'){ return value === true ? 1 : 0; } return value; }); "{"name":"andy","isDead":0,"age":11,"addr":"shanghai"}" 功能2:删除某个属性 将isDead属性删除,如果replacer的返回值是undefined,那么该属性会被删除。 var user = {name: 'andy', isDead: false, age: 11, addr: 'shanghai'}; JSON....

2018-02-09 13:27:15 · 1 min · Eddie Wang

ECharts 轮流高亮中国地图各个省份

1. 小栗子 最早我是想通过dispatchAction方法去改变选中的省份,但是没有起作用,如果你知道这个方法怎么实现,麻烦你可以告诉我。 我实现的方法是另外一种。 dispatchAction({ type: 'geoSelect', // 可选,系列 index,可以是一个数组指定多个系列 seriesIndex?: number|Array, // 可选,系列名称,可以是一个数组指定多个系列 seriesName?: string|Array, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据 dataIndex?: number, // 可选,数据名称,在有 dataIndex 的时候忽略 name?: string }) 后来我改变了一个方法。这个方法的核心思路是定时获取图标的配置,然后更新配置,最后在设置配置。 var myChart = echarts.init(document.getElementById('china-map')); var COLORS = ["#070093", "#1c3fbf", "#1482e5", "#70b4eb", "#b4e0f3", "#ffffff"]; // 指定图表的配置项和数据 var option = { tooltip: { trigger: 'item', formatter: '{b}' }, series: [ { name: '中国', type: 'map', mapType: 'china', selectedMode : 'single', label: { normal: { show: true }, emphasis: { show: true } }, data:[ // 默认高亮安徽省 {name:'安徽', selected:true} ], itemStyle: { normal: { areaColor: 'rgba(255,255,255,0....

2018-02-09 13:16:53 · 1 min · Eddie Wang

一行命令搭建简易静态文件http服务器

简易服务器:在命令执行的所在路径启动一个http服务器,然后你可以通过浏览器访问该路径下的所有文件。 在局域网内传文件,或者自己测试使用都是非常方便的。 1. 基于python 1.1. 基于Python2 python -m SimpleHTTPServer port > python -m SimpleHTTPServer 8099 Serving HTTP on 0.0.0.0 port 8099 ... 127.0.0.1 - - [24/Oct/2017 11:07:56] "GET / HTTP/1.1" 200 - 1.2. 基于python3 python3 -m http.server port > python3 -m http.server 8099 Serving HTTP on 0.0.0.0 port 8099 (http://0.0.0.0:8099/) ... 127.0.0.1 - - [24/Oct/2017 11:05:06] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [24/Oct/2017 11:05:06] code 404, message File not found 127....

2018-02-09 13:01:14 · 1 min · Eddie Wang

120行代码实现 浏览器WebRTC视频聊天

本例子是参考webrtc-tutorial-simple-video-chat做的。 这个教程应该主要是去宣传ScaleDrone的sdk, 他们的服务是收费的,但是免费的也可以用,就是有些次数限制。 本栗子的地址 本栗子的pages地址 因为使用的是ScaleDrone的js sdk, 后期很可能服务不稳定之类的 1. 准备 使用最新版谷歌浏览器(62版) 视频聊天中 一个是windows, 一个是mac stun服务器使用谷歌的,trun使用ScaleDrone的sdk,这样我就不用管服务端了。 2. 先上效果图 3. 再上在线例子点击此处 4. 源码分析 // 产生随机数 if (!location.hash) { location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16); } // 获取房间号 var roomHash = location.hash.substring(1); // 放置你自己的频道id, 这是我注册了ScaleDrone 官网后,创建的channel // 你也可以自己创建 var drone = new ScaleDrone('87fYv4ncOoa0Cjne'); // 房间名必须以 'observable-'开头 var roomName = 'observable-' + roomHash; var configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' // 使用谷歌的stun服务 }] }; var room; var pc; function onSuccess() {} function onError(error) { console....

2018-02-09 12:56:12 · 2 min · Eddie Wang

如何写好技术文档?

本文来自于公司内部的一个分享。 在文档方面,对内的一些接口文档主要是用swagger来写的。虽然可以在线测试,比较方便。但是也存在着一些更新不及时,swgger文档无法导出成文件的问题。 在对外提供的文档方面:我主要负责做一个浏览器端的一个js sdk。文档还算可以github地址,所以想把一些写文档的心得分享给大家。 1. 衡量好文档的唯一标准是什么? Martin(Bob大叔)曾在《代码整洁之道》一书打趣地说:当你的代码在做 Code Review 时,审查者要是愤怒地吼道: “What the fuck is this shit?” “Dude, What the fuck!” 等言辞激烈的词语时,那说明你写的代码是 Bad Code,如果审查者只是漫不经心的吐出几个 “What the fuck?”, 那说明你写的是 Good Code。衡量代码质量的唯一标准就是每分钟骂出“WTF” 的频率。 衡量文档的标准也是如此。 2. 好文档的特点 简洁:一句话可以说完的事情,就不要分两句话来说。并不是文档越厚越好,太厚的文档大多没人看。 准确: 字段类型,默认值,备注,是否必填等属性说明。 逻辑性: 文档如何划分? 利于查看。 demo胜千言: 好的demo胜过各种字段说明,可以复制下来直接使用。 读者心: 从读者的角度考虑, 方法尽量简洁。可以传递一个参数搞定的事情,绝对不要让用户去传两个参数。 及时更新: 不更新的文档比bug更严重。 向后兼容: 不要随意废弃已有的接口或者某个字段,除非你考虑到这样做的后果。 建立文档词汇表:每个概念只有一个名字,不要随意起名字,名不正则言不顺。 格式统一:例如时间格式。我曾见过2017-09-12 09:32:23, 或2017.09.12 09:32:23或2017.09.12 09:32:23。变量名user_name, userName。 使用专业词语:不要过于口语化 3. 总结: 写出好文档要有以下四点 逻辑性:便于查找 专业性: 值得信赖,质量保证 责任心:及时更新,准确性,向后兼容 读者心:你了解的东西,别人可能并不清楚。从读者的角度去考虑,他们需要什么,而不是一味去强调你能提供什么。 4. 写文档的工具 markdown: 方便快捷,可以导出各种格式的文件 swagger: 功能强大,需要部署,不方便传递文件 5....

2018-02-09 12:52:57 · 1 min · Eddie Wang

哑代理 - TCP链接高Recv-Q,内存泄露的罪魁祸首

1. 问题现象 使用netstat -ntp命令时发现,Recv-Q 1692012 异常偏高(正常情况下,该值应该是0),导致应用占用过多的内存。 tcp 1692012 0 172.17.72.4:48444 10.254.149.149:58080 ESTABLISHED 27/node 问题原因:代理的转发时,没有删除逐跳首部 2. 什么是Hop-by-hop 逐跳首部? http首部可以分为两种 端到端首部 End-to-end: 端到端首部代理在转发时必须携带的 逐跳首部 Hop-by-hop: 逐跳首部只对单次转发有效,代理在转发时,必须删除这些首部 逐跳首部有以下几个, 这些首部在代理进行转发前必须删除 Connetion Keep-Alive Proxy-Authenticate Proxy-Authortization Trailer TE Transfer-Encodeing Upgrade 3. 什么是哑代理? 很多老的或简单的代理都是盲中继(blind relay),它们只是将字节从一个连接转发到另一个连接中去,不对Connection首部进行特殊的处理。 (1)在图4-15a中 Web客户端向代理发送了一条报文,其中包含了Connection:Keep-Alive首部,如果可能的话请求建立一条keep-alive连接。客户端等待响应,以确定对方是否认可它对keep-alive信道的请求。 (2) 哑代理收到了这条HTTP请求,但它并不理解 Connection首部(只是将其作为一个扩展首部对待)。代理不知道keep-alive是什么意思,因此只是沿着转发链路将报文一字不漏地发送给服务器(图4-15b)。但Connection首部是个逐跳首部,只适用于单条传输链路,不应该沿着传输链路向下传输。接下来,就要发生一些很糟糕的事情了。 (3) 在图4-15b中,经过中继的HTTP请求抵达了Web服务器。当Web服务器收到经过代理转发的Connection: Keep-Alive首部时,会误以为代理(对服务器来说,这个代理看起来就和所有其他客户端一样)希望进行keep-alive对话!对Web服务器来说这没什么问题——它同意进行keep-alive对话,并在图4-15c中回送了一个Connection: Keep-Alive响应首部。所以,此时W eb服务器认为它在与代理进行keep-alive对话,会遵循keep-alive的规则。但代理却对keep-alive一无所知。不妙。 (4) 在图4-15d中,哑代理将Web服务器的响应报文回送给客户端,并将来自Web服务器的Connection: Keep-Alive首部一起传送过去。客户端看到这个首部,就会认为代理同意进行keep-alive对话。所以,此时客户端和服务器都认为它们在进行keep-alive对话,但与它们进行对话的代理却对keep-alive一无所知。 (5) 由于代理对keep-alive一无所知,所以会将收到的所有数据都回送给客户端,然后等待源端服务器关闭连接。但源端服务器会认为代理已经显式地请求它将连接保持在打开状态了,所以不会去关闭连接。这样,代理就会挂在那里等待连接的关闭。 (6) 客户端在图4-15d中收到了回送的响应报文时,会立即转向下一条请求,在keep-alive连接上向代理发送另一条请求(参见图4-15e)。而代理并不认为同一条连接上会有其他请求到来,请求被忽略,浏览器就在这里转圈,不会有任何进展了。 (7) 这种错误的通信方式会使浏览器一直处于挂起状态,直到客户端或服务器将连接超时,并将其关闭为止。 –《HTTP权威指南》 这是HTTP权威指南中,关于HTTP哑代理的描述。这里这里说了哑代理会造成的一个问题。 这种错误的通信方式会使浏览器一直处于挂起状态,直到客户端或服务器将连接超时,并将其关闭为止。 实际上,我认为哑代理还是造成以下问题的原因 TCP链接高Recv-Q tcp链接不断开,导致服务器内存过高,内存泄露 节点iowait高 在我们自己的代理的代码中,我有发现,在代理进行转发时,只删除了headers.host, 并没有删除headers.Connection等逐跳首部的字段 delete req.headers.host var option = { url: url, headers: req....

2018-02-08 21:58:31 · 1 min · Eddie Wang