Js是一门"单线程"语言

什么是"线程", 和"进程"有什么区别?

"进程"(process)是运行中的"程序"(program)实例, 一个"程序"可以拥有多个"进程".
进程之间彼此独立,有独立的内存空间.

Windows中的Chrome进程大军:
捕获.PNG

"线程"(thread)是操作系统分配CPU控制时间的基本单位, 一个"进程"可以拥有一个或多个"线程",这些"线程"共享进程内的资源.

单个进程内的线程数量:
2.PNG

移动端浏览器对audio标签的限制总结

往往在桌面写好的播放功能,到移动端各种出错.
这是因为在移动端,对于audio的使用有很多限制,特别是safari.
而且现在的各种框架, 极大加深了程序的复杂程度,使调试变得异常困难.

测试环境

本文测试环境为iPad ios12,没有条件进行iphone/桌面端safari环境下audio的表现

不支持autoplay/preload

大部分移动端浏览器都不允许网页自动播放/预加载音乐.
例如下面这个示例, 桌面浏览器可以自动播放,而移动浏览器没有任何反应.

1
<audio controls src="./music/1.mp3" autoplay></audio>

除非用户点了播放按钮/手动触发了某个事件(这个事件里调用了audio.play()方法)
为啥这么设计?据说是怕网页偷跑流量.

只有用户手动触发的事件能调用play/load

既然autoplay不能用,那能不能用play方法来自动播放呢? 很遗憾的是, 不行. 例如下面这样,在移动端没效果:

1
2
3
4
5
<audio controls src="./music/1.mp3"></audio>
<script>
const audioEl = document.querySelector('audio')
audioEl.play()
</script>

先来看看水果的文档:

In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.

iOS-Specific Considerations

也就是说,只有当用户手动触发某个事件时,audio.play才能被调用.

1
2
3
4
click由用户触发, 有效
<input type="button" value="Play" onclick="document.myMovie.play()">
onload事件不是用户触发的,无效
<body onload="document.myMovie.play()">

因此,可以给外层元素绑定一个click事件.
只要用户点了这个元素,就能播放音乐.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div>
<audio controls src="./music/1.mp3"></audio>
</div>

<script>
const audioEl = document.querySelector('audio')
const played = false
document.querySelector('div').addEventListener('click', ()=> {
if (!played) {
audioEl.play()
played = true
}
})
</script>

transform导致fixed失效

transform是个超级常用的属性, 需要居中/动画/开启cpu加速时经常会用到.
但这个属性也有很多副作用, 例如把后边的元素盖住了,或者是后代absolute元素被overflow:hidden剪裁.
除此之外还有个影响, 让拥有固定定位(fixed)属性的子元素变的像个绝对定位(absolute)元素.

1.PNG

如上图所示, 黑色子元素为固定定位元素(fixed), 由于黄色父元素transfrom属性的影响, 表现的像个绝对定位元素(absolute).

height百分比值不生效

有时候要给父元素定一个最小高度,然后让子元素与父元素等高.
往往第一反应是设置min-height和height: 100%,但这么作通常不会生效.

1.PNG
如上图所示,外层容器的高度为min-height: 100px,内部黄色子元素的高度为height: 50%.
可以观察到,子元素的height: 50%并未生效.

JSONP

JSONP(JSON with Padding)是在早期浏览器不允许跨域的背景下,诞生的 一种通信方式

什么是跨域

前端获取数据一般都通过XMLHttpRequest发送请求,但有一定的限制
在CORS之前, 浏览器不允许通过XMLHttpRequest向不同于当前域名/端口/协议的地址发送请求
另外,这种(向不同域名)发送请求的行为通常称为"跨域"

例如

当前域名 http://www.example.com/foo
允许 http://www.example.com
允许 http://www.example.com/api/foo
禁止 https://www.example.com
禁止 http://bar.example.com
禁止 https://www.example.com:4000

获取元素位置/尺寸的方法

clientWidth offsetWidth scrollWidth

  • clientWidth|clientHeight 元素内容可视部分的宽度/高度,不包括 滚动条 border margin
  • offsetWidth|offsetHeight 元素整体宽度/高度,包括滚动条和border,不包括margin
  • scrollWidth|scrollHeight 元素内容实际宽度/高度,包含被隐藏的部分

示例 50424091-e23a4980-0899-11e9-8b18-e8b210cbf876.png

如上所示,两容器元素的宽/高均为200px, border为1px,padding为10px. 背景颜色为黄色, padding无颜色
两容器内均有一斜线为背景的子元素,其宽/高均为300px
容器1的overflow属性值为auto(可滚动).滚动条宽度为17px,颜色为蓝色
容器2的overflow的属性值为static(默认值,无滚动条)
clientWidth长度的计算不包含滚动条.当容器有滚动条时,clientWidth值为203px(220px - 17px).没有滚动条时,clientWidth值为220px
在chrome中,padding-right不参与scrollWidth值的计算.而padding-bottom相反,参与scrollHeight值的计算.因此, 可滚动元素的scrollWidth为310px,scrollHeight为320px

scrolling box

当overflow为auto,且内部元素溢出时.元素沿padding edge向被内裁剪,在单侧显示滚动条
48303328-e7d70c80-e543-11e8-8347-f1f7a8d54797.png

一般来说, 元素会从右/下侧被裁剪,具体数值取决于滚动条宽度 206580fb.png

this

Es5 关于 this 的定义如下:
ECMAScript Language Specification - ECMA-262 Edition 5.1

The this keyword evaluates to the value of the ThisBinding of the current execution context.
关键字"this"指向当前所在 execution context(执行环境)的 ThisBinding

execution context(执行环境/执行上下文)

execution context 的说明在 10.3
ECMAScript Language Specification - ECMA-262 Edition 5.1
ES5 可执行代码与执行环境

When control is transferred to ECMAScript executable code, control is entering an execution context. Active execution contexts logically form a stack. The top execution context on this logical stack is the running execution context. A new execution context is created whenever control is transferred from the executable code associated with the currently running execution context to executable code that is not associated with that execution context. The newly created execution context is pushed onto the stack and becomes the running execution context.

当控制器进入 ECMAScript executable code(可执行代码)时, 控制器会进入一个 execution context(执行环境/执行上下文).所有活动的 execution context 在逻辑上组成一个栈结构,栈顶的 execution context 叫 running execution context.当控制器从当前的 executable code(与 running execution context 相关的)转移到另一个 executable code(与 running execution context 无关的)时,会创建一个新的 execution context.然后将这个新创建的 execution context 推入栈中,使其成为新的 running execution context.

vue-cli

安装

1 安装 vue-cli

1
2
3
npm install -g @vue/cli
//or
yarn global add @vue/cli

2 安装 node-gyp 所需编译工具

安装 Visual Studio Community 2017
安装 Python2.7(node-gyp 不支持 3.x)
打开 cmd, 执行如下命令

1
2
npm config set python python2.7
npm config set msvs_version 2017

3 修改镜像地址为阿里源

1
2
3
4
5
npm config set registry https://registry.npm.taobao.org/
yarn config set registry https://registry.npm.taobao.org/

// node-sass所需
npm config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/

编译 Chromium(Windows)

2019/7/13日注:
该文章内容已过时,部分配置及环境要求发生变动. 具体过程请参阅官方的编译指南.
https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md

系统环境 Windows 7 x64
编译版本 Chromium 69.0.3482.0

安装Visual Studio Community 2017

Visual Studio Community 的下载地址

安装时,勾选以下选项
如果已经安装了Visual Studio Community 2017, 可通过 工具 > 获取工具和功能 打开该页面

  • 工作负载
    • 使用 C++ 的桌面开发
      • 用于 x86 和 x64 的 Visual C++ ATL
      • 用于 x86 和 x64 的 Visual C++ MFC
  • 单个组件
    • SDK、库和框架
      • Windows 10 SDK (10.0.17134.0)
  • 语言包
    • 英语

注意不要更改默认的安装位置, 如果改了编译时可能会出错,提示找不到Visual Studio
C盘不够大的话可以更改下载缓存位置到其他硬盘分区

安装SDK Debugging Tools

1 安装Visual Studio后, 打开Control Panel → Programs → Programs and Features
2 右键 Windows Software Development Kit -> 点击Change
3 选择Change -> 点击 Next按钮 -> 勾选Debugging Tools For Windows -> 点击Change按钮