From e6dc271f0ddd54f83316bd24820b373e5088ca28 Mon Sep 17 00:00:00 2001 From: magical-l Date: Tue, 25 Sep 2018 12:28:30 +0800 Subject: [PATCH 001/300] Update prototype.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 字符串里多了个冒号 --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 7ed4a74..c91cc30 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -443,7 +443,7 @@ Object.assign(S.prototype, M2.prototype); S.prototype.constructor = S; var s = new S(); -s.hello // 'hello:' +s.hello // 'hello' s.world // 'world' ``` From 14215dff1a58cd87ff0c7999a593e9963d711c10 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 25 Sep 2018 12:35:24 +0800 Subject: [PATCH 002/300] docs(oop): fix prototype #48 --- docs/oop/prototype.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 7ed4a74..9c20673 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -2,7 +2,9 @@ 面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。 -大部分面向对象的编程语言,都是通过“类”(class)来实现对象的继承。JavaScript 语言的继承则是通过“原型对象”(prototype)。 +大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 + +ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准语法入门》一书的相关章节。 ## 原型对象概述 @@ -451,14 +453,10 @@ s.world // 'world' ## 模块 -随着网站逐渐变成"互联网应用程序",嵌入网页的 JavaScript 代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者必须使用软件工程的方法,管理网页的业务逻辑。 +随着网站逐渐变成“互联网应用程序”,嵌入网页的 JavaScript 代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等……开发者必须使用软件工程的方法,管理网页的业务逻辑。 JavaScript 模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。 - -:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。 - -为了解决上面的缺点,可以 但是,JavaScript 不是一种模块化编程语言,ES6 才开始支持“类”和“模块”。下面介绍传统的做法,如何利用对象实现模块的效果。 ### 基本的实现方法 From a54ff9b92bd737fbd7b7678dffec3a022914bb3d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 25 Sep 2018 12:52:34 +0800 Subject: [PATCH 003/300] docs(oop): fix oop/prototype --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index 140240f..ffc7b8d 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -4,7 +4,7 @@ 大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现,本章介绍 JavaScript 的原型链继承。 -ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准语法入门》一书的相关章节。 +ES6 引入了 class 语法,基于 class 的继承不在这个教程介绍,请参阅《ES6 标准入门》一书的相关章节。 ## 原型对象概述 From d953738c1d781f3569da9e11c7b6c3ed6c03980f Mon Sep 17 00:00:00 2001 From: magical-l Date: Tue, 25 Sep 2018 18:22:27 +0800 Subject: [PATCH 004/300] Update window.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 也许改正了错误的语序。要取决于原作者本来想表达的意思。 --- docs/bom/window.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index 33163b5..9f66a0e 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -344,7 +344,7 @@ var windowB = window.open('windowB.html', 'WindowB'); windowB.window.name // "WindowB" ``` -注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能窗口对象获取对方的内部属性。 +注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能获取对方窗口对象的内部属性。 下面是另一个例子。 From 059323e64a4588e93a4d755bcad414c6d0a94227 Mon Sep 17 00:00:00 2001 From: magical-l Date: Wed, 26 Sep 2018 11:02:29 +0800 Subject: [PATCH 005/300] Update webworker.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补漏词;优化文案。 --- docs/bom/webworker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/webworker.md b/docs/bom/webworker.md index 1c7d8f4..d4e7d60 100644 --- a/docs/bom/webworker.md +++ b/docs/bom/webworker.md @@ -4,7 +4,7 @@ JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力。 -Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。 +Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务可以交由 Worker 线程执行,主线程(通常负责 UI 交互)能够保持流畅,不会被阻塞或拖慢。 Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。 @@ -16,7 +16,7 @@ Web Worker 有以下几个使用注意点。 (2)**DOM 限制** -Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用`document`、`window`、`parent`这些对象。但是,Worker 线程可以`navigator`对象和`location`对象。 +Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用`document`、`window`、`parent`这些对象。但是,Worker 线程可以使用`navigator`对象和`location`对象。 (3)**全局对象限制** From 472248dbeb90e603839a06eec980fd0c97543e8e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 26 Sep 2018 16:54:32 +0800 Subject: [PATCH 006/300] docs(bom): fix location #52 --- docs/bom/location.md | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/bom/location.md b/docs/bom/location.md index 4f782da..78698a7 100644 --- a/docs/bom/location.md +++ b/docs/bom/location.md @@ -10,17 +10,17 @@ URL 是互联网的基础设施之一。浏览器提供了一些原生对象, `Location`对象提供以下属性。 -- Location.href:整个 URL。 -- Location.protocol:当前 URL 的协议,包括冒号(`:`)。 -- Location.host:主机,包括冒号(`:`)和端口(默认的80端口和443端口会省略)。 -- Location.hostname:主机名,不包括端口。 -- Location.port:端口号。 -- Location.pathname:URL 的路径部分,从根路径`/`开始。 -- Location.search:查询字符串部分,从问号`?`开始。 -- Location.hash:片段字符串部分,从`#`开始。 -- Location.username:域名前面的用户名。 -- Location.password:域名前面的密码。 -- Location.origin:URL 的协议、主机名和端口。 +- `Location.href`:整个 URL。 +- `Location.protocol`:当前 URL 的协议,包括冒号(`:`)。 +- `Location.host`:主机,包括冒号(`:`)和端口(默认的80端口和443端口会省略)。 +- `Location.hostname`:主机名,不包括端口。 +- `Location.port`:端口号。 +- `Location.pathname`:URL 的路径部分,从根路径`/`开始。 +- `Location.search`:查询字符串部分,从问号`?`开始。 +- `Location.hash`:片段字符串部分,从`#`开始。 +- `Location.username`:域名前面的用户名。 +- `Location.password`:域名前面的密码。 +- `Location.origin`:URL 的协议、主机名和端口。 ```javascript // 当前网址为 @@ -115,12 +115,14 @@ window.location.reload(true); ## URL 的编码和解码 -网页的 URL 只能包含合法的字符,这可以分成两类。 +网页的 URL 只能包含合法的字符。合法字符分成两类。 -- URL 元字符:分号(`;`),逗号(','),斜杠(`/`),问号(`?`),冒号(`:`),at(`@`),`&`,等号(`=`),加号(`+`),美元符号(`$`),井号(`#`) -- 语义字符:`a-z`,`A-Z`,`0-9`,连词号(`-`),下划线(`_`),点(`.`),感叹号(`!`),波浪线(`~`),星号(`*`),单引号(`\``),圆括号(`()`) +- URL 元字符:分号(`;`),逗号(`,`),斜杠(`/`),问号(`?`),冒号(`:`),at(`@`),`&`,等号(`=`),加号(`+`),美元符号(`$`),井号(`#`) +- 语义字符:`a-z`,`A-Z`,`0-9`,连词号(`-`),下划线(`_`),点(`.`),感叹号(`!`),波浪线(`~`),星号(`*`),单引号(`'`),圆括号(`()`) -除了以上字符,其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(`%`)加上两个大写的十六进制字母。比如,UTF-8 的操作系统上,`http://www.example.com/q=春节`这个 URL 之中,汉字“春节”不是 URL 的合法字符,所以被浏览器自动转成`http://www.example.com/q=%E6%98%A5%E8%8A%82`。其中,“春”转成了`%E6%98%A5`,“节”转成了“%E8%8A%82”。这是因为“春”和”节“的 UTF-8 编码分别是`E6 98 A5`和`E8 8A 82`,将每个字节前面加上百分号,就构成了 URL 编码。 +除了以上字符,其他字符出现在 URL 之中都必须转义,规则是根据操作系统的默认编码,将每个字节转为百分号(`%`)加上两个大写的十六进制字母。 + +比如,UTF-8 的操作系统上,`http://www.example.com/q=春节`这个 URL 之中,汉字“春节”不是 URL 的合法字符,所以被浏览器自动转成`http://www.example.com/q=%E6%98%A5%E8%8A%82`。其中,“春”转成了`%E6%98%A5`,“节”转成了`%E8%8A%82`。这是因为“春”和”节“的 UTF-8 编码分别是`E6 98 A5`和`E8 8A 82`,将每个字节前面加上百分号,就构成了 URL 编码。 JavaScript 提供四个 URL 的编码/解码方法。 From 55b4ec65574391da14844309a7e667b026c12f0e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 29 Sep 2018 10:42:56 +0800 Subject: [PATCH 007/300] docs(stdlib): fix array --- docs/stdlib/array.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index e267830..e4ef47a 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -774,11 +774,13 @@ users .filter(function (email) { return /^t/.test(email); }) -.forEach(console.log); +.forEach(function (email) { + console.log(email); +}); // "tom@example.com" ``` -上面代码中,先产生一个所有 Email 地址组成的数组,然后再过滤出以`t`开头的 Email 地址。 +上面代码中,先产生一个所有 Email 地址组成的数组,然后再过滤出以`t`开头的 Email 地址,最后将它打印出来。 ## 参考链接 From 2debcf742cd0f346f328cdbbef903809266d98d4 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 4 Oct 2018 11:17:39 +0800 Subject: [PATCH 008/300] docs(bom): edit cors/withCredentials --- docs/bom/cors.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/bom/cors.md b/docs/bom/cors.md index c990257..aa41f83 100644 --- a/docs/bom/cors.md +++ b/docs/bom/cors.md @@ -78,28 +78,28 @@ Content-Type: text/html; charset=utf-8 ### withCredentials 属性 -上面说到,CORS 请求默认不包含 Cookie 信息(以及 HTTP 认证信息等)。如果需要包含 Cookie 信息,一方面要服务器同意,指定`Access-Control-Allow-Credentials`字段。 +上面说到,CORS 请求默认不包含 Cookie 信息(以及 HTTP 认证信息等),这是为了降低 CSRF 攻击的风险。但是某些场合,服务器可能需要拿到 Cookie,这时需要服务器显式指定`Access-Control-Allow-Credentials`字段,告诉浏览器可以发送 Cookie。 ```http Access-Control-Allow-Credentials: true ``` -另一方面,开发者必须在 AJAX 请求中打开`withCredentials`属性。 +同时,开发者必须在 AJAX 请求中打开`withCredentials`属性。 ```javascript var xhr = new XMLHttpRequest(); xhr.withCredentials = true; ``` -否则,即使服务器同意发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。 +否则,即使服务器要求发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。 -但是,如果省略`withCredentials`设置,有的浏览器还是会一起发送 Cookie。这时,可以显式关闭`withCredentials`。 +但是,有的浏览器默认将`withCredentials`属性设为`true`。这导致如果省略`withCredentials`设置,这些浏览器可能还是会一起发送 Cookie。这时,可以显式关闭`withCredentials`。 ```javascript xhr.withCredentials = false; ``` -需要注意的是,如果要发送 Cookie,`Access-Control-Allow-Origin`就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传,且(跨域)原网页代码中的`document.cookie`也无法读取服务器域名下的 Cookie。 +需要注意的是,如果服务器要求浏览器发送 Cookie,`Access-Control-Allow-Origin`就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传,且(跨域)原网页代码中的`document.cookie`也无法读取服务器域名下的 Cookie。 ## 非简单请求 @@ -247,7 +247,7 @@ CORS 与 JSONP 的使用目的相同,但是比 JSONP 更强大。JSONP 只支 ## 参考链接 -- Monsur Hossain, [Using CORS](http://www.html5rocks.com/en/tutorials/cors/) -- MDN, [HTTP access control (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) -- Ryan Miller, [CORS](https://frontendian.co/cors) - +- [Using CORS](http://www.html5rocks.com/en/tutorials/cors/), Monsur Hossain +- [HTTP access control (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS), MDN +- [CORS](https://frontendian.co/cors), Ryan Miller +- [Do You Really Know CORS?](http://performantcode.com/web/do-you-really-know-cors), Grzegorz Mirek From 3f39bd7eabba584dfb6eaaeb07e71587693965b5 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 4 Oct 2018 19:31:22 +0800 Subject: [PATCH 009/300] docs(bom): edit window --- docs/async/timer.md | 2 + docs/bom/window.md | 85 +++++++++++++++++++++++++++++++++++++++++++ docs/events/common.md | 2 + 3 files changed, 89 insertions(+) diff --git a/docs/async/timer.md b/docs/async/timer.md index a339f8d..89b6421 100644 --- a/docs/async/timer.md +++ b/docs/async/timer.md @@ -288,6 +288,8 @@ console.log(2); 总之,`setTimeout(f, 0)`这种写法的目的是,尽可能早地执行`f`,但是并不能保证立刻就执行`f`。 +实际上,`setTimeout(f, 0)`不会真的在0毫秒之后运行,不同的浏览器有不同的实现。以 Edge 浏览器为例,会等到4毫秒之后运行。如果电脑正在使用电池供电,会等到16毫秒之后运行;如果网页不在当前 Tab 页,会推迟到1000毫秒(1秒)之后运行。这样是为了节省系统资源。 + ### 应用 `setTimeout(f, 0)`有几个非常重要的用途。它的一大应用是,可以调整事件的发生顺序。比如,网页开发中,某个事件先发生在子元素,然后冒泡到父元素,即子元素的事件回调函数,会早于父元素的事件回调函数触发。如果,想让父元素的事件回调函数先发生,就要用到`setTimeout(f, 0)`。 diff --git a/docs/bom/window.md b/docs/bom/window.md index 9f66a0e..c813fc3 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -529,6 +529,91 @@ var selectedText = selObj.toString(); `window.matchMedia()`方法用来检查 CSS 的`mediaQuery`语句,详见《CSS 操作》一章。 +### window.requestAnimationFrame() + +`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,即在下一次重绘之前执行。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 + +如果某个函数会改变网页的布局,一般就放在`window.requestAnimationFrame()`里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。 + +该方法接受一个回调函数作为参数。 + +```javascript +window.requestAnimationFrame(callback) +``` + +上面代码中,`callback`是一个回调函数。`callback`执行时,它的参数就是系统传入的一个高精度时间戳(`performance.now()`的返回值),单位是毫秒,表示距离网页加载的时间。 + +`window.requestAnimationFrame()`的返回值是一个整数,这个整数可以传入`window.cancelAnimationFrame()`,用来取消回调函数的执行。 + +下面是一个`window.requestAnimationFrame()`执行网页动画的例子。 + +```javascript +var element = document.getElementById('animate'); +element.style.position = 'absolute'; + +var start = null; + +function step(timestamp) { + if (!start) start = timestamp; + var progress = timestamp - start; + // 元素不断向左移,最大不超过200像素 + element.style.left = Math.min(progress / 10, 200) + 'px'; + // 如果距离第一次执行不超过 2000 毫秒, + // 就继续执行动画 + if (progress < 2000) { + window.requestAnimationFrame(step); + } +} + +window.requestAnimationFrame(step); +``` + +上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。 + +### window.requestIdleCallback() + +`window.requestIdleCallback()`跟`setTimeout`类似,也是将某个函数推迟执行,但是它保证将回调函数推迟到系统资源空闲时执行。也就是说,如果某个任务不是很关键,就可以使用`window.requestIdleCallback()`将其推迟执行,以保证网页性能。 + +它跟`window.requestAnimationFrame()`的区别在于,后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不一定能保证在16毫秒之内完成;`window.requestIdleCallback()`可以保证回调函数在系统资源空闲时执行。 + +该方法接受一个回调函数和一个配置对象作为参数。配置对象可以指定一个推迟执行的最长时间,如果过了这个时间,回调函数不管系统资源有无空虚,都会执行。 + +```javascript +window.requestIdleCallback(callback[, options]) +``` + +`callback`参数是一个回调函数。该回调函数执行时,系统会传入一个`IdleDeadline`对象作为参数。`IdleDeadline`对象有一个`didTimeout`属性(布尔值,表示是否为超时调用)和一个`timeRemaining()`方法(返回该空闲时段剩余的毫秒数)。 + +`options`参数是一个配置对象,目前只有`timeout`一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。 + +`window.requestAnimationFrame()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 + +下面是一个例子。 + +```javascript +requestIdleCallback(myNonEssentialWork); + +function myNonEssentialWork(deadline) { + while (deadline.timeRemaining() > 0) { + doWorkIfNeeded(); + } +} +``` + +上面代码中,`requestIdleCallback()`用来执行非关键任务`myNonEssentialWork`。该任务先确认本次空闲时段有剩余时间,然后才真正开始执行任务。 + +下面是指定`timeout`的例子。 + +```javascript +requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 }); +``` + +上面代码指定,`processPendingAnalyticsEvents`必须在未来2秒之内执行。 + +如果由于超时导致回调函数执行,则`deadline.timeRemaining()`返回`0`,`deadline.didTimeout`返回`true`。 + +如果多次执行`window.requestAnimationFrame()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 + ## 事件 `window`对象可以接收以下事件。 diff --git a/docs/events/common.md b/docs/events/common.md index 3f67ec8..804ad06 100644 --- a/docs/events/common.md +++ b/docs/events/common.md @@ -259,6 +259,8 @@ window.addEventListener('scroll', throttle(callback, 1000)); window.addEventListener('scroll', _.throttle(callback, 1000)); ``` +本书前面介绍过`debounce`的概念,`throttle`与它区别在于,`throttle`是“节流”,确保一段时间内只执行一次,而`debounce`是“防抖”,要连续操作结束后再执行。以网页滚动为例,`debounce`要等到用户停止滚动后才执行,`throttle`则是如果用户一直在滚动网页,那么在滚动过程中还是会执行。 + ### resize 事件 `resize`事件在改变浏览器窗口大小时触发,主要发生在`window`对象上面。 From 2b0815e401188c003e0a161f4b358523bec50f36 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 7 Oct 2018 21:59:41 +0800 Subject: [PATCH 010/300] docs(operator): fix typo #55 --- docs/operators/comparison.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operators/comparison.md b/docs/operators/comparison.md index 828a06f..9699670 100644 --- a/docs/operators/comparison.md +++ b/docs/operators/comparison.md @@ -52,7 +52,7 @@ JavaScript 引擎内部首先比较首字符的 Unicode 码点。如果相等, ## 非相等运算符:非字符串的比较 -如果两个运算子都不是字符串,分成以下三种情况。 +如果两个运算子都不是字符串,分成以下两种情况。 **(1)原始类型值** From 864ad8edc6fd034b9a5c8a833cd08ffb7f0ba0ba Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 7 Oct 2018 22:53:52 +0800 Subject: [PATCH 011/300] docs: edit README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 193c114..55703f1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -本教程全面介绍 JavaScript 核心语法,从最简单的开始讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 +本教程全面介绍 JavaScript 核心语法,从最简单的讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 本教程适合初学者当作 JavaScript 语言的入门教程,也适合当作日常使用的参考手册。 From 44f6a5167dcc03e6fc4ed18a363704d5930bfe83 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 8 Oct 2018 20:56:29 +0800 Subject: [PATCH 012/300] docs(async): fix promise typo #57 --- docs/async/promise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/async/promise.md b/docs/async/promise.md index fe69b28..f909c7d 100644 --- a/docs/async/promise.md +++ b/docs/async/promise.md @@ -114,7 +114,7 @@ timeout(100) Promise 实例的`then`方法,用来添加回调函数。 -`then`方法可以接受两个回调函数,第一个是异步操作成功时(变为`fulfilled`状态)时的回调函数,第二个是异步操作失败(变为`rejected`)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。 +`then`方法可以接受两个回调函数,第一个是异步操作成功时(变为`fulfilled`状态)的回调函数,第二个是异步操作失败(变为`rejected`)时的回调函数(该参数可以省略)。一旦状态改变,就调用相应的回调函数。 ```javascript var p1 = new Promise(function (resolve, reject) { From 5cd2003208c14bb0cef436637d5b5743177689fe Mon Sep 17 00:00:00 2001 From: ruanyf Date: Wed, 10 Oct 2018 15:28:21 +0800 Subject: [PATCH 013/300] docs(bom): edit window/requestAnimationFrame --- docs/bom/window.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index c813fc3..e87131b 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -531,7 +531,7 @@ var selectedText = selObj.toString(); ### window.requestAnimationFrame() -`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,即在下一次重绘之前执行。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 +`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。 如果某个函数会改变网页的布局,一般就放在`window.requestAnimationFrame()`里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。 @@ -586,7 +586,7 @@ window.requestIdleCallback(callback[, options]) `options`参数是一个配置对象,目前只有`timeout`一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。 -`window.requestAnimationFrame()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 +`window.requestIdelCallback()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。 下面是一个例子。 @@ -612,7 +612,7 @@ requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 }); 如果由于超时导致回调函数执行,则`deadline.timeRemaining()`返回`0`,`deadline.didTimeout`返回`true`。 -如果多次执行`window.requestAnimationFrame()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 +如果多次执行`window.requestIdelCallback()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。 ## 事件 From 9f0f31707daaeb4fbb736ee838c169272dd8fed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=8C=E4=B9=85?= Date: Fri, 12 Oct 2018 11:21:28 +0800 Subject: [PATCH 014/300] typo rt --- docs/elements/video.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/elements/video.md b/docs/elements/video.md index 799e679..879fdb3 100644 --- a/docs/elements/video.md +++ b/docs/elements/video.md @@ -35,7 +35,7 @@ - HTMLMediaElement.audioTracks:返回一个类似数组的对象,表示媒体文件包含的音轨。 - HTMLMediaElement.autoplay:布尔值,表示媒体文件是否自动播放,对应 HTML 属性`autoplay`。 - HTMLMediaElement.buffered:返回一个 TimeRanges 对象,表示浏览器缓冲的内容。该对象的`length`属性返回缓存里面有多少段内容,`start(rangeId)`方法返回指定的某段内容(从0开始)开始的时间点,`end()`返回指定的某段内容结束的时间点。该属性只读。 -- HTMLMediaElement.controls:布尔值,表示是否显示媒体文件的控制栏,对应 HTML 属性`autoplay`。 +- HTMLMediaElement.controls:布尔值,表示是否显示媒体文件的控制栏,对应 HTML 属性`controls`。 - HTMLMediaElement.controlsList:返回一个类似数组的对象,表示是否显示控制栏的某些控件。该对象包含三个可能的值:`nodownload`、`nofullscreen`和`noremoteplayback`。该属性只读。 - HTMLMediaElement.crossOrigin:字符串,表示跨域请求时是否附带用户信息(比如 Cookie),对应 HTML 属性`crossorigin`。该属性只有两个可能的值:`anonymous`和`use-credentials`。 - HTMLMediaElement.currentSrc:字符串,表示当前正在播放的媒体文件的绝对路径。该属性只读。 From 9b78af10405c1651ae5813186c3766c3d26b297f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 14 Oct 2018 22:08:45 +0800 Subject: [PATCH 015/300] docs(bom): edit ArrayBuffer --- docs/bom/arraybuffer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index acd35ac..a93cac2 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -2,7 +2,7 @@ ## ArrayBuffer 对象 -ArrayBuffer 对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。 +ArrayBuffer 对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。这个对象可以看作内存数据的表达。 这个对象是 ES6 才写入标准的,普通的网页编程用不到它,为了教程体系的完整,下面只提供一个简略的介绍,详细介绍请看《ES6 标准入门》里面的章节。 @@ -33,7 +33,7 @@ var buf2 = buf1.slice(0); ## Blob 对象 -Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件。 +Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件。它与 ArrayBuffer 的区别在于,它用于操作二进制文件,而 ArrayBuffer 用于操作内存。 浏览器原生提供`Blob()`构造函数,用来生成实例对象。 From ae88ca9875c8838ee04bbf5d26f37e716d771035 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 19 Oct 2018 16:39:19 +0800 Subject: [PATCH 016/300] docs(bom): fix arrayBuffer #61 --- docs/bom/arraybuffer.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index a93cac2..f1116e1 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -14,12 +14,11 @@ var buffer = new ArrayBuffer(8); 上面代码中,实例对象`buffer`占用8个字节。 -ArrayBuffer 对象有实例属性`length`和`byteLength`,都表示当前实例占用的内存长度(单位字节)。 +ArrayBuffer 对象有实例属性`byteLength`,表示当前实例占用的内存长度(单位字节)。 ```javascript var buffer = new ArrayBuffer(8); -buffer.length // 8 -buffer.length // 8 +buffer.byteLength // 8 ``` ArrayBuffer 对象有实例方法`slice()`,用来复制一部分内存。它接受两个整数参数,分别表示复制的开始位置(从0开始)和结束位置(复制时不包括结束位置),如果省略第二个参数,则表示一直复制到结束。 From f4982f934e209cc5c5b7b46eba9ccf257e81dbb1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sat, 20 Oct 2018 14:39:33 +0800 Subject: [PATCH 017/300] docs(dom): fix node/nodeValue #62 --- docs/dom/node.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dom/node.md b/docs/dom/node.md index 6ed7d65..bffcb0d 100644 --- a/docs/dom/node.md +++ b/docs/dom/node.md @@ -68,7 +68,7 @@ div.nodeName // "DIV" `nodeValue`属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。 -只有文本节点(text)和注释节点(comment)有文本值,因此这两类节点的`nodeValue`可以返回结果,其他类型的节点一律返回`null`。同样的,也只有这两类节点可以设置`nodeValue`属性的值,其他类型的节点设置无效。 +只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的`nodeValue`可以返回结果,其他类型的节点一律返回`null`。同样的,也只有这三类节点可以设置`nodeValue`属性的值,其他类型的节点设置无效。 ```javascript // HTML 代码如下 @@ -102,7 +102,7 @@ document.getElementById('foo').textContent = '

GoodBye!

'; 上面代码在插入文本时,会将`

`标签解释为文本,而不会当作标签处理。 -对于文本节点(text)和注释节点(comment),`textContent`属性的值与`nodeValue`属性相同。对于其他类型的节点,该属性会将每个子节点的内容连接在一起返回,但是不包括注释节点。如果一个节点没有子节点,则返回空字符串。 +对于文本节点(text)、注释节点(comment)和属性节点(attr),`textContent`属性的值与`nodeValue`属性相同。对于其他类型的节点,该属性会将每个子节点(不包括注释节点)的内容连接在一起返回。如果一个节点没有子节点,则返回空字符串。 文档节点(document)和文档类型节点(doctype)的`textContent`属性为`null`。如果要读取整个文档的内容,可以使用`document.documentElement.textContent`。 From 0a9f7d0713f4524e99216f281d730d75d948576c Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 23 Oct 2018 16:04:42 +0800 Subject: [PATCH 018/300] docs: edit events/common --- docs/events/common.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/events/common.md b/docs/events/common.md index 804ad06..94cf8fe 100644 --- a/docs/events/common.md +++ b/docs/events/common.md @@ -9,7 +9,7 @@ 如果该事件对象的`returnValue`属性是一个非空字符串,那么浏览器就会弹出一个对话框,询问用户是否要卸载该资源。但是,用户指定的字符串可能无法显示,浏览器会展示预定义的字符串。如果用户点击“取消”按钮,资源就不会卸载。 ```javascript -window.addEventListener('beforeunload', function(event) { +window.addEventListener('beforeunload', function (event) { event.returnValue = '你确定离开吗?'; }); ``` @@ -19,7 +19,7 @@ window.addEventListener('beforeunload', function(event) { 浏览器对这个事件的行为很不一致,有的浏览器调用`event.preventDefault()`,也会弹出对话框。IE 浏览器需要显式返回一个非空的字符串,才会弹出对话框。而且,大多数浏览器在对话框中不显示指定文本,只显示默认文本。因此,可以采用下面的写法,取得最大的兼容性。 ```javascript -window.addEventListener('beforeunload', function(e) { +window.addEventListener('beforeunload', function (e) { var confirmationMessage = '确认关闭窗口?'; e.returnValue = confirmationMessage; @@ -27,9 +27,9 @@ window.addEventListener('beforeunload', function(e) { }); ``` -注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。 +注意,许多手机浏览器默认忽略这个事件,桌面浏览器也有办法忽略这个事件。所以,它可能根本不会生效,不能依赖它来阻止用户关闭窗口。另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页。因为执行了这个事件以后,缓存页面就没意义了。 -另外,一旦使用了`beforeunload`事件,浏览器就不会缓存当前网页。因为执行了这个事件以后,缓存页面就没意义了。 +基本上,只有一种场合可以监听`unload`事件,其他情况都不应该监听:用户修改了表单,还没有保存就要离开。 ### unload 事件 @@ -43,7 +43,7 @@ window.addEventListener('unload', function(event) { }); ``` -跟`beforeunload`事件一样,一旦使用了`unload`事件,浏览器就不会缓存当前网页,理由同上。 +手机上,浏览器或系统可能会直接丢弃网页,这时该事件根本不会发生。而且跟`beforeunload`事件一样,一旦使用了`unload`事件,浏览器就不会缓存当前网页,理由同上。因此,任何情况下都不应该依赖这个事件,指定网页卸载时要执行的代码,可以考虑完全不使用这个事件。 ### load 事件,error 事件 @@ -91,6 +91,8 @@ window.addEventListener('pageshow', function(event){ 如果页面包含``或`` | 发送 Cookie | 不发送 | +| AJAX | `$.get("...")` | 发送 Cookie | 不发送 | +| Image | `` | 发送 Cookie | 不发送 | + +设置了`Strict`或`Lax`以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。 + +**(3)None** + +Chrome 计划将`Lax`变为默认设置。这时,网站可以选择显式关闭`SameSite`属性,将其设为`None`。不过,前提是必须同时设置`Secure`属性(Cookie 只能通过 HTTPS 协议发送),否则无效。 + +下面的设置无效。 + +```text +Set-Cookie: widget_session=abc123; SameSite=None +``` + +下面的设置有效。 + +```text +Set-Cookie: widget_session=abc123; SameSite=None; Secure +``` + ## document.cookie `document.cookie`属性用于读写当前网页的 Cookie。 @@ -259,3 +346,8 @@ document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT'; ## 参考链接 - [HTTP cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies), by MDN +- [Using the Same-Site Cookie Attribute to Prevent CSRF Attacks](https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/) +- [SameSite cookies explained](https://web.dev/samesite-cookies-explained) +- [Tough Cookies](https://scotthelme.co.uk/tough-cookies/), Scott Helme +- [Cross-Site Request Forgery is dead!](https://scotthelme.co.uk/csrf-is-dead/), Scott Helme + From ecef95529e3720f1f951d691160ebd104a7652e2 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 10 Sep 2019 15:36:58 +0800 Subject: [PATCH 126/300] docs(dom): edit CSS --- docs/dom/css.md | 9 +++++++-- package.json | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/dom/css.md b/docs/dom/css.md index eaa28cd..d6d01db 100644 --- a/docs/dom/css.md +++ b/docs/dom/css.md @@ -1,10 +1,10 @@ # CSS 操作 -CSS 与 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本节介绍如何通过 JavaScript 操作 CSS。 +CSS 与 JavaScript 是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本章介绍如何通过 JavaScript 操作 CSS。 ## HTML 元素的 style 属性 -操作 CSS 样式最简单的方法,就是使用网页元素节点的`getAttribute`方法、`setAttribute`方法和`removeAttribute`方法,直接读写或删除网页元素的`style`属性。 +操作 CSS 样式最简单的方法,就是使用网页元素节点的`getAttribute()`方法、`setAttribute()`方法和`removeAttribute()`方法,直接读写或删除网页元素的`style`属性。 ```javascript div.setAttribute( @@ -756,6 +756,8 @@ var mdl = window.matchMedia('(min-width: 400px)'); mdl instanceof MediaQueryList // true ``` +上面代码中,变量`mdl`就是 mediaQueryList 的实例。 + 注意,如果参数不是有效的`MediaQuery`条件语句,`window.matchMedia`不会报错,依然返回一个 MediaQueryList 实例。 ```javascript @@ -841,3 +843,6 @@ function mqCallback(e) { } } ``` + +注意,`MediaQueryList.removeListener()`方法不能撤销`MediaQueryList.onchange`属性指定的监听函数。 + diff --git a/package.json b/package.json index 7328981..a7eeda3 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { "gh-pages": "latest", - "husky": "3.x", + "husky": "^3.0.5", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From ad6049aa962adedb2442dc4cd9eba8bd87753b5a Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 12 Sep 2019 17:05:06 +0800 Subject: [PATCH 127/300] docs(dom): edit mutationobserver --- docs/dom/mutationobserver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dom/mutationobserver.md b/docs/dom/mutationobserver.md index c638f15..e44f9a1 100644 --- a/docs/dom/mutationobserver.md +++ b/docs/dom/mutationobserver.md @@ -81,7 +81,7 @@ mutationObserver.observe(document.documentElement, { }); ``` -对一个节点添加观察器,就像使用`addEventListener`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。但是,如果指定不同的`options`对象,就会被当作两个不同的观察器。 +对一个节点添加观察器,就像使用`addEventListener`方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。如果指定不同的`options`对象,以后面添加的那个为准,类似覆盖。 下面的例子是观察新增的子节点。 From 11d71b0b11d2b4b699abbf13758ed5ff46c17161 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 12 Sep 2019 17:08:19 +0800 Subject: [PATCH 128/300] docs(bom): edit form --- docs/bom/form.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/form.md b/docs/bom/form.md index 855724a..6773acd 100644 --- a/docs/bom/form.md +++ b/docs/bom/form.md @@ -42,7 +42,7 @@ Content-Length: 74 user_name=张三&user_passwd=123&submit_button=提交 ``` -注意,实际提交的时候,只要键值不是 URL 的合法字符(比如汉字“张三”和“确定”),浏览器会自动对其进行编码。 +注意,实际提交的时候,只要键值不是 URL 的合法字符(比如汉字“张三”和“提交”),浏览器会自动对其进行编码。 点击`submit`控件,就可以提交表单。 From dcd00fe32b3c4626809baf300888c12c383cba53 Mon Sep 17 00:00:00 2001 From: Vincent Hy Date: Tue, 17 Sep 2019 16:01:37 +0800 Subject: [PATCH 129/300] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=20'instanceOf'=20?= =?UTF-8?q?=E6=8B=BC=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/oop/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oop/prototype.md b/docs/oop/prototype.md index e463e57..f01c701 100644 --- a/docs/oop/prototype.md +++ b/docs/oop/prototype.md @@ -323,7 +323,7 @@ s instanceof String // false 上面代码中,字符串不是`String`对象的实例(因为字符串不是对象),所以返回`false`。 -此外,对于`undefined`和`null`,`instanceOf`运算符总是返回`false`。 +此外,对于`undefined`和`null`,`instanceof`运算符总是返回`false`。 ```javascript undefined instanceof Object // false From 727c26c72b49cba68d353a8fdd14354e93b325e1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 30 Sep 2019 17:25:14 +0800 Subject: [PATCH 130/300] docs(bom): edit form --- docs/bom/form.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/docs/bom/form.md b/docs/bom/form.md index 6773acd..c4bb42b 100644 --- a/docs/bom/form.md +++ b/docs/bom/form.md @@ -214,6 +214,16 @@ for (var pair of formData) { 如果一个控件通过验证,它就会匹配`:valid`的 CSS 伪类,浏览器会继续进行表单提交的流程。如果没有通过验证,该控件就会匹配`:invalid`的 CSS 伪类,浏览器会终止表单提交,并显示一个错误信息。 +```css +input:invalid { + border-color: red; +} +input, +input:valid { + border-color: #ccc; +} +``` + ### checkValidity() 除了提交表单的时候,浏览器自动校验表单,还可以手动触发表单的校验。表单元素和表单控件都有`checkValidity()`方法,用于手动触发校验。 @@ -279,7 +289,33 @@ if (!myInput.checkValidity()) { 控件元素的`setCustomValidity()`方法用来定制校验失败时的报错信息。它接受一个字符串作为参数,该字符串就是定制的报错信息。如果参数为空字符串,则上次设置的报错信息被清除。 -如果调用这个方法,并且参数不为空字符串,浏览器就会认为控件没有通过校验,就会立刻显示该方法设置的报错信息。 +这个方法可以替换浏览器内置的表单验证报错信息,参数就是要显示的报错信息。 + +```html +

+ + +
+``` + +上面的表单输入框,要求只能输入小写字母,且不得超过15个字符。如果输入不符合要求(比如输入“ABC”),提交表单的时候,Chrome 浏览器会弹出报错信息“Please match the requested format.”,禁止表单提交。下面使用`setCustomValidity()`方法替换掉报错信息。 + +```javascript +var input = document.getElementById('username'); +input.oninvalid = function (event) { + event.target.setCustomValidity( + '用户名必须是小写字母,不能为空,最长不超过15个字符' + ); +} +``` + +上面代码中,`setCustomValidity()`方法是在`invalid`事件的监听函数里面调用。该方法也可以直接调用,这时如果参数不为空字符串,浏览器就会认为该控件没有通过校验,就会立刻显示该方法设置的报错信息。 ```javascript /* HTML 代码如下 @@ -345,6 +381,37 @@ if (document.getElementById('myInput').validity.rangeOverflow) { document.getElementById('prompt').innerHTML = txt; ``` +如果想禁止浏览器弹出表单验证的报错信息,可以监听`invalid`事件。 + +```javascript +var input = document.getElementById('username'); +var form = document.getElementById('form'); + +var elem = document.createElement('div'); +elem.id = 'notify'; +elem.style.display = 'none'; +form.appendChild(elem); + +input.addEventListener('invalid', function (event) { + event.preventDefault(); + if (!event.target.validity.valid) { + elem.textContent = '用户名必须是小写字母'; + elem.className = 'error'; + elem.style.display = 'block'; + input.className = 'invalid animated shake'; + } +}); + +input.addEventListener('input', function(event){ + if ( 'block' === elem.style.display ) { + input.className = ''; + elem.style.display = 'none'; + } +}); +``` + +上面代码中,一旦发生`invalid`事件(表单验证失败),`event.preventDefault()`用来禁止浏览器弹出默认的验证失败提示,然后设置定制的报错提示框。 + ### 表单的 novalidate 属性 表单元素的 HTML 属性`novalidate`,可以关闭浏览器的自动校验。 @@ -553,3 +620,7 @@ xhr.open('POST', 'myserver/uploads'); xhr.setRequestHeader('Content-Type', file.type); xhr.send(file); ``` + +## 参考链接 + +- [HTML5 Form Validation With the “pattern” Attribute](https://webdesign.tutsplus.com/tutorials/html5-form-validation-with-the-pattern-attribute--cms-25145), Thoriq Firdaus From 486addf67169806ce731003a112183c29082d323 Mon Sep 17 00:00:00 2001 From: harriet247 <50596251+harriet247@users.noreply.github.com> Date: Thu, 3 Oct 2019 10:45:40 -0700 Subject: [PATCH 131/300] Update arraybuffer.md --- docs/bom/arraybuffer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bom/arraybuffer.md b/docs/bom/arraybuffer.md index fea14b8..1ad0e2b 100644 --- a/docs/bom/arraybuffer.md +++ b/docs/bom/arraybuffer.md @@ -73,7 +73,7 @@ myBlob.type // "text/html" `Blob`具有一个实例方法`slice`,用来拷贝原来的数据,返回的也是一个`Blob`实例。 ```javascript -myBlob.slice(start,end, contentType) +myBlob.slice(start, end, contentType) ``` `slice`方法有三个参数,都是可选的。它们依次是起始的字节位置(默认为0)、结束的字节位置(默认为`size`属性的值,该位置本身将不包含在拷贝的数据之中)、新实例的数据类型(默认为空字符串)。 From cbf8fcf2b7d2bdc99d11a80d22cd4fd96111b859 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 6 Oct 2019 10:12:56 +0800 Subject: [PATCH 132/300] docs(stdlib): edit array/sort --- docs/stdlib/array.md | 14 +++++++++++++- package.json | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/stdlib/array.md b/docs/stdlib/array.md index b8736d4..97912f2 100644 --- a/docs/stdlib/array.md +++ b/docs/stdlib/array.md @@ -402,7 +402,7 @@ a // [1, 2] // [10111, 1101, 111] ``` -上面代码的最后两个例子,需要特殊注意。`sort`方法不是按照大小排序,而是按照字典顺序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以`101`排在`11`的前面。 +上面代码的最后两个例子,需要特殊注意。`sort()`方法不是按照大小排序,而是按照字典顺序。也就是说,数值会被先转成字符串,再按照字典顺序进行比较,所以`101`排在`11`的前面。 如果想让`sort`方法按照自定义方式排序,可以传入一个函数作为参数。 @@ -430,6 +430,18 @@ a // [1, 2] // ] ``` +注意,自定义的排序函数应该返回数值,否则不同的浏览器可能有不同的实现,不能保证结果都一致。 + +```javascript +// bad +[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a > b) + +// good +[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a - b) +``` + +上面代码中,前一种排序算法返回的是布尔值,这是不推荐使用的。后一种是数值,才是更好的写法。 + ### map() `map`方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。 diff --git a/package.json b/package.json index a7eeda3..bceaca7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { "gh-pages": "latest", - "husky": "^3.0.5", + "husky": "^3.0.7", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From ae4e9cfb4b77f85a0d38234b1e3d7c0417f74fa1 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Sun, 6 Oct 2019 10:18:22 +0800 Subject: [PATCH 133/300] docs(stdlib): edit array/sort --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bceaca7..66e3f26 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/wangdoc/javascript-tutorial", "dependencies": { "gh-pages": "latest", - "husky": "^3.0.7", + "husky": "^3.0.8", "loppo": "latest", "loppo-theme-wangdoc": "latest" } From b8523bcffed334a1acbdbb7b9c14b5663a50d980 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 7 Oct 2019 00:05:25 +0800 Subject: [PATCH 134/300] docs(stdlib): edit Number/toLocalString() --- docs/stdlib/number.md | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/number.md b/docs/stdlib/number.md index d585fff..dc5dcbc 100644 --- a/docs/stdlib/number.md +++ b/docs/stdlib/number.md @@ -144,7 +144,7 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 ### Number.prototype.toPrecision() -`toPrecision`方法用于将一个数转为指定位数的有效数字。 +`Number.prototype.toPrecision()`方法用于将一个数转为指定位数的有效数字。 ```javascript (12.34).toPrecision(1) // "1e+1" @@ -154,9 +154,9 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 (12.34).toPrecision(5) // "12.340" ``` -`toPrecision`方法的参数为有效数字的位数,范围是1到21,超出这个范围会抛出 RangeError 错误。 +该方法的参数为有效数字的位数,范围是1到21,超出这个范围会抛出 RangeError 错误。 -`toPrecision`方法用于四舍五入时不太可靠,跟浮点数不是精确储存有关。 +该方法用于四舍五入时不太可靠,跟浮点数不是精确储存有关。 ```javascript (12.35).toPrecision(3) // "12.3" @@ -165,6 +165,41 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 (12.45).toPrecision(3) // "12.4" ``` +### Number.prototype.toLocaleString() + +`Number.prototype.toLocaleString()`方法接受一个地区码作为参数,返回一个字符串,表示当前数字在该地区的当地书写形式。 + +```javascript +(123).toLocaleString('zh-Hans-CN-u-nu-hanidec') +// "一二三" +``` + +该方法还可以接受第二个参数配置对象,用来定制指定用途的返回字符串。该对象的`style`属性指定输出样式,默认值是`decimal`,表示输出十进制形式。如果值为`percent`,表示输出百分数。 + +```javascript +(123).toLocaleString('zh-Hans-CN', { style: 'persent' }) +// "12,300%" +``` + +如果`style`属性的值为`currency`,则可以搭配`currency`属性,输出指定格式的货币字符串形式。 + +```javascript +(123).toLocaleString('zh-Hans-CN', { style: 'currency', currency: 'CNY' }) +// "¥123.00" + +(123).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' }) +// "123,00 €" + +(123).toLocaleString('en-US', { style: 'currency', currency: 'USD' }) +// "$123.00" +``` + +如果`Number.prototype.toLocaleString()`省略了参数,则由浏览器自行决定如何处理,通常会使用操作系统的地区设定。注意,该方法如果使用浏览器不认识的地区码,会抛出一个错误。 + +```javascript +(123).toLocaleString('123') // 出错 +``` + ## 自定义方法 与其他对象一样,`Number.prototype`对象上面可以自定义方法,被`Number`的实例继承。 From 23e3bcb59f4279f7b756cb76bd1bffcb0aba8fff Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 31 Oct 2019 00:03:34 +0800 Subject: [PATCH 135/300] docs(bom): fix #154 --- docs/bom/location.md | 54 +++++++++++++------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/docs/bom/location.md b/docs/bom/location.md index 3cec254..4ea667e 100644 --- a/docs/bom/location.md +++ b/docs/bom/location.md @@ -171,27 +171,13 @@ decodeURIComponent('%E6%98%A5%E8%8A%82') // "春节" ``` -## URL 对象 +## URL 接口 -`URL`对象是浏览器的原生对象,可以用来构造、解析和编码 URL。一般情况下,通过`window.URL`可以拿到这个对象。 - -``元素和``元素都部署了这个接口。这就是说,它们的 DOM 节点对象可以使用 URL 的实例属性和方法。 - -```javascript -var a = document.createElement('a'); -a.href = 'http://example.com/?foo=1'; - -a.hostname // "example.com" -a.search // "?foo=1" -``` - -上面代码中,`a`是``元素的 DOM 节点对象。可以在这个对象上使用 URL 的实例属性,比如`hostname`和`search`。 +`URL`接口是一个构造函数,浏览器原生提供,可以用来构造、解析和编码 URL。一般情况下,通过`window.URL`可以拿到这个构造函数。 ### 构造函数 -`URL`对象本身是一个构造函数,可以生成 URL 实例。 - -它接受一个表示 URL 的字符串作为参数。如果参数不是合法的 URL,会报错。 +`URL`作为构造函数,可以生成 URL 实例。它接受一个表示 URL 的字符串作为参数。如果参数不是合法的 URL,会报错。 ```javascript var url = new URL('http://www.example.com/index.html'); @@ -283,7 +269,7 @@ url.href // "http://example.com/index2.html#part2" **(1)URL.createObjectURL()** -`URL.createObjectURL`方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了`File`对象或`Blob`对象的 URL。 +`URL.createObjectURL()`方法用来为上传/下载的文件、流媒体文件生成一个 URL 字符串。这个字符串代表了`File`对象或`Blob`对象的 URL。 ```javascript // HTML 代码如下 @@ -306,7 +292,7 @@ function handleFiles(files) { } ``` -上面代码中,`URL.createObjectURL`方法用来为上传的文件生成一个 URL 字符串,作为``元素的图片来源。 +上面代码中,`URL.createObjectURL()`方法用来为上传的文件生成一个 URL 字符串,作为``元素的图片来源。 该方法生成的 URL 就像下面的样子。 @@ -314,11 +300,11 @@ function handleFiles(files) { blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1 ``` -注意,每次使用`URL.createObjectURL`方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用`URL.revokeObjectURL()`方法释放这个实例。 +注意,每次使用`URL.createObjectURL()`方法,都会在内存里面生成一个 URL 实例。如果不再需要该方法生成的 URL 字符串,为了节省内存,可以使用`URL.revokeObjectURL()`方法释放这个实例。 **(2)URL.revokeObjectURL()** -`URL.revokeObjectURL`方法用来释放`URL.createObjectURL`方法生成的 URL 实例。它的参数就是`URL.createObjectURL`方法返回的 URL 字符串。 +`URL.revokeObjectURL()`方法用来释放`URL.createObjectURL()`方法生成的 URL 实例。它的参数就是`URL.createObjectURL()`方法返回的 URL 字符串。 下面为上一段的示例加上`URL.revokeObjectURL()`。 @@ -337,7 +323,7 @@ function handleFiles(files) { } ``` -上面代码中,一旦图片加载成功以后,为本地文件生成的 URL 字符串就没用了,于是可以在`img.onload`回调函数里面,通过`URL.revokeObjectURL`方法卸载这个 URL 实例。 +上面代码中,一旦图片加载成功以后,为本地文件生成的 URL 字符串就没用了,于是可以在`img.onload`回调函数里面,通过`URL.revokeObjectURL()`方法卸载这个 URL 实例。 ## URLSearchParams 对象 @@ -390,14 +376,6 @@ var foo = url.searchParams.get('foo') || 'somedefault'; 上面代码中,URL 实例的`searchParams`属性就是一个`URLSearchParams`实例,所以可以使用`URLSearchParams`接口的`get`方法。 -DOM 的`a`元素节点的`searchParams`属性,就是一个`URLSearchParams`实例。 - -```javascript -var a = document.createElement('a'); -a.href = 'https://example.com?filter=api'; -a.searchParams.get('filter') // "api" -``` - `URLSearchParams`实例有遍历器接口,可以用`for...of`循环遍历(详见《ES6 标准入门》的《Iterator》一章)。 ```javascript @@ -434,7 +412,7 @@ window.location.href = location.pathname + '?' + params; ### URLSearchParams.append() -`append`方法用来追加一个查询参数。它接受两个参数,第一个为键名,第二个为键值,没有返回值。 +`append()`方法用来追加一个查询参数。它接受两个参数,第一个为键名,第二个为键值,没有返回值。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -442,7 +420,7 @@ params.append('baz', 3); params.toString() // "foo=1&bar=2&baz=3" ``` -`append`方法不会识别是否键名已经存在。 +`append()`方法不会识别是否键名已经存在。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -454,7 +432,7 @@ params.toString() // "foo=1&bar=2&foo=3" ### URLSearchParams.delete() -`delete`方法用来删除指定的查询参数。它接受键名作为参数。 +`delete()`方法用来删除指定的查询参数。它接受键名作为参数。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -464,7 +442,7 @@ params.toString() // "foo=1" ### URLSearchParams.has() -`has`方法返回一个布尔值,表示查询字符串是否包含指定的键名。 +`has()`方法返回一个布尔值,表示查询字符串是否包含指定的键名。 ```javascript var params = new URLSearchParams({'foo': 1 , 'bar': 2}); @@ -474,7 +452,7 @@ params.has('baz') // false ### URLSearchParams.set() -`set`方法用来设置查询字符串的键值。 +`set()`方法用来设置查询字符串的键值。 它接受两个参数,第一个是键名,第二个是键值。如果是已经存在的键,键值会被改写,否则会被追加。 @@ -509,7 +487,7 @@ window.history.replaceState({}, '', location.pathname + `?` + params); ### URLSearchParams.get(),URLSearchParams.getAll() -`get`方法用来读取查询字符串里面的指定键。它接受键名作为参数。 +`get()`方法用来读取查询字符串里面的指定键。它接受键名作为参数。 ```javascript var params = new URLSearchParams('?foo=1'); @@ -528,7 +506,7 @@ params.get('foo') // "3" 上面代码中,查询字符串有三个`foo`键,`get`方法返回最前面的键值`3`。 -`getAll`方法返回一个数组,成员是指定键的所有键值。它接受键名作为参数。 +`getAll()`方法返回一个数组,成员是指定键的所有键值。它接受键名作为参数。 ```javascript var params = new URLSearchParams('?foo=1&foo=2'); @@ -539,7 +517,7 @@ params.getAll('foo') // ["1", "2"] ### URLSearchParams.sort() -`sort`方法对查询字符串里面的键进行排序,规则是按照 Unicode 码点从小到大排列。 +`sort()`方法对查询字符串里面的键进行排序,规则是按照 Unicode 码点从小到大排列。 该方法没有返回值,或者说返回值是`undefined`。 From ff74e42925763ae85fb1f6ea509fc69849357c8f Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 31 Oct 2019 00:16:01 +0800 Subject: [PATCH 136/300] refactor: upgrade node.js --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ead9a81..6304e69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: -- '8' +- '10' branches: only: From 786148c7b0363871eafc1327001623dfa4eaaf1b Mon Sep 17 00:00:00 2001 From: ruanyf Date: Mon, 4 Nov 2019 18:44:07 +0800 Subject: [PATCH 137/300] docs: fix #155 --- docs/stdlib/number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/number.md b/docs/stdlib/number.md index dc5dcbc..e0c2158 100644 --- a/docs/stdlib/number.md +++ b/docs/stdlib/number.md @@ -177,7 +177,7 @@ Number.MIN_SAFE_INTEGER // -9007199254740991 该方法还可以接受第二个参数配置对象,用来定制指定用途的返回字符串。该对象的`style`属性指定输出样式,默认值是`decimal`,表示输出十进制形式。如果值为`percent`,表示输出百分数。 ```javascript -(123).toLocaleString('zh-Hans-CN', { style: 'persent' }) +(123).toLocaleString('zh-Hans-CN', { style: 'percent' }) // "12,300%" ``` From 19d0628816dd19f6395e1f762c988d1ee1a85780 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Tue, 12 Nov 2019 05:38:48 +0800 Subject: [PATCH 138/300] docs(stdlib): fix Date.setDate --- docs/stdlib/date.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/date.md b/docs/stdlib/date.md index 357913c..503c3b1 100644 --- a/docs/stdlib/date.md +++ b/docs/stdlib/date.md @@ -480,7 +480,7 @@ d.setDate(9) // 1357660800000 d // Wed Jan 09 2013 00:00:00 GMT+0800 (CST) ``` -`set*`方法的参数都会自动折算。以`setDate`为例,如果参数超过当月的最大天数,则向下一个月顺延,如果参数是负数,表示从上个月的最后一天开始减去的天数。 +`set*`方法的参数都会自动折算。以`setDate()`为例,如果参数超过当月的最大天数,则向下一个月顺延,如果参数是负数,表示从上个月的最后一天开始减去的天数。 ```javascript var d1 = new Date('January 6, 2013'); @@ -490,10 +490,12 @@ d1 // Fri Feb 01 2013 00:00:00 GMT+0800 (CST) var d2 = new Date ('January 6, 2013'); -d.setDate(-1) // 1356796800000 -d // Sun Dec 30 2012 00:00:00 GMT+0800 (CST) +d2.setDate(-1) // 1356796800000 +d2 // Sun Dec 30 2012 00:00:00 GMT+0800 (CST) ``` +上面代码中,`d1.setDate(32)`将日期设为1月份的32号,因为1月份只有31号,所以自动折算为2月1日。`d2.setDate(-1)`表示设为上个月的倒数第二天,即12月30日。 + `set`类方法和`get`类方法,可以结合使用,得到相对时间。 ```javascript From d3e17b1373c3fbb4f3ff6a5eef61532755e081f8 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 15 Nov 2019 01:12:31 +0800 Subject: [PATCH 139/300] docs(bom): edit window --- docs/bom/window.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/bom/window.md b/docs/bom/window.md index 4b75320..f5eea3b 100644 --- a/docs/bom/window.md +++ b/docs/bom/window.md @@ -416,7 +416,7 @@ window.moveTo(100, 200) 上面代码将窗口移动到屏幕`(100, 200)`的位置。 -`window.moveBy`方法将窗口移动到一个相对位置。它接受两个参数,分布是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。 +`window.moveBy()`方法将窗口移动到一个相对位置。它接受两个参数,分别是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。 ```javascript window.moveBy(25, 50) @@ -424,7 +424,7 @@ window.moveBy(25, 50) 上面代码将窗口向右移动25像素、向下移动50像素。 -为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种情况,浏览器允许用脚本移动窗口:该窗口是用`window.open`方法新建的,并且它所在的 Tab 页是当前窗口里面唯一的。除此以外的情况,使用上面两个方法都是无效的。 +为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种情况,浏览器允许用脚本移动窗口:该窗口是用`window.open()`方法新建的,并且窗口里只有它一个 Tab 页。除此以外的情况,使用上面两个方法都是无效的。 ### window.resizeTo(),window.resizeBy() From 4e1e7ddeb86a5d942e0fed698f62673af7c1ba8c Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 22 Nov 2019 18:56:54 +0800 Subject: [PATCH 140/300] docs: fix #157 --- docs/dom/document.md | 2 +- docs/dom/parentnode.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dom/document.md b/docs/dom/document.md index 7f4b8ed..4a5315c 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -11,7 +11,7 @@ - Ajax 操作返回的文档,使用`XMLHttpRequest`对象的`responseXML`属性。 - 内部节点的`ownerDocument`属性。 -`document`对象继承了`EventTarget`接口、`Node`接口、`ParentNode`接口。这意味着,这些接口的方法都可以在`document`对象上调用。除此之外,`document`对象还有很多自己的属性和方法。 +`document`对象继承了`EventTarget`接口和`Node`接口,并且混入(mixin)了`ParentNode`接口。这意味着,这些接口的方法都可以在`document`对象上调用。除此之外,`document`对象还有很多自己的属性和方法。 ## 属性 diff --git a/docs/dom/parentnode.md b/docs/dom/parentnode.md index f440ff1..1aa2d0c 100644 --- a/docs/dom/parentnode.md +++ b/docs/dom/parentnode.md @@ -1,10 +1,10 @@ # ParentNode 接口,ChildNode 接口 -节点对象除了继承 Node 接口以外,还会继承其他接口。`ParentNode`接口表示当前节点是一个父节点,提供一些处理子节点的方法。`ChildNode`接口表示当前节点是一个子节点,提供一些相关方法。 +节点对象除了继承 Node 接口以外,还拥有其他接口。`ParentNode`接口表示当前节点是一个父节点,提供一些处理子节点的方法。`ChildNode`接口表示当前节点是一个子节点,提供一些相关方法。 ## ParentNode 接口 -如果当前节点是父节点,就会继承`ParentNode`接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会继承`ParentNode`接口。 +如果当前节点是父节点,就会混入了(mixin)`ParentNode`接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会拥有`ParentNode`接口。 ### ParentNode.children @@ -84,7 +84,7 @@ parent.append('Hello', p); ## ChildNode 接口 -如果一个节点有父节点,那么该节点就继承了`ChildNode`接口。 +如果一个节点有父节点,那么该节点就拥有了`ChildNode`接口。 ### ChildNode.remove() From 7f65d8b0e5873eead0d4ea91848c4b81a7c5d15e Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 28 Nov 2019 17:26:39 +0800 Subject: [PATCH 141/300] docs: fix #158 --- docs/features/error.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/error.md b/docs/features/error.md index c0b8ebb..17c33cd 100644 --- a/docs/features/error.md +++ b/docs/features/error.md @@ -406,7 +406,7 @@ result 上面代码中,`catch`代码块结束执行之前,会先执行`finally`代码块。 -`catch`代码块之中,触发转入`finally`代码快的标志,不仅有`return`语句,还有`throw`语句。 +`catch`代码块之中,触发转入`finally`代码块的标志,不仅有`return`语句,还有`throw`语句。 ```javascript function f() { From 173611cb7b46fd4a355e765566621355e594485e Mon Sep 17 00:00:00 2001 From: atimidguy <49008464+atimidguy@users.noreply.github.com> Date: Tue, 24 Dec 2019 12:16:23 +0800 Subject: [PATCH 142/300] fixed typo --- docs/stdlib/regexp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index 3ba5f86..b253cbb 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -298,7 +298,7 @@ str.replace(search, replacement) 'aaa'.replace(/a/g, 'b') // "bbb" ``` -上面代码中,最后一个正则表达式使用了`g`修饰符,导致所有的`b`都被替换掉了。 +上面代码中,最后一个正则表达式使用了`g`修饰符,导致所有的`a`都被替换掉了。 `replace`方法的一个应用,就是消除字符串首尾两端的空格。 From 5312a09ac73b5db5464756959b9bc118a5b658bd Mon Sep 17 00:00:00 2001 From: Jacty Date: Tue, 7 Jan 2020 02:22:23 +0800 Subject: [PATCH 143/300] typo fixed a typo --- docs/stdlib/wrapper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stdlib/wrapper.md b/docs/stdlib/wrapper.md index 7c3367b..7e89bf3 100644 --- a/docs/stdlib/wrapper.md +++ b/docs/stdlib/wrapper.md @@ -124,5 +124,5 @@ Number.prototype.double = function () { (123).double() // 246 ``` -上面代码在`String`和`Number`这两个对象的原型上面,分别自定义了一个方法,从而可以在所有实例对象上调用。注意,最后一张的`123`外面必须要加上圆括号,否则后面的点运算符(`.`)会被解释成小数点。 +上面代码在`String`和`Number`这两个对象的原型上面,分别自定义了一个方法,从而可以在所有实例对象上调用。注意,最后一行的`123`外面必须要加上圆括号,否则后面的点运算符(`.`)会被解释成小数点。 From f71489d048ec352c95e5be304ce7c3616e4bf8df Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 13 Feb 2020 13:55:20 +0800 Subject: [PATCH 144/300] docs(stdlib): edit regexp/exec() --- docs/stdlib/regexp.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/stdlib/regexp.md b/docs/stdlib/regexp.md index b253cbb..0d41c43 100644 --- a/docs/stdlib/regexp.md +++ b/docs/stdlib/regexp.md @@ -137,7 +137,7 @@ new RegExp('').test('abc') ### RegExp.prototype.exec() -正则实例对象的`exec`方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回`null`。 +正则实例对象的`exec()`方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回`null`。 ```javascript var s = '_x_x'; @@ -159,12 +159,12 @@ var r = /_(x)/; r.exec(s) // ["_x", "x"] ``` -上面代码的`exec`方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。 +上面代码的`exec()`方法,返回一个数组。第一个成员是整个匹配的结果,第二个成员是圆括号匹配的结果。 -`exec`方法的返回数组还包含以下两个属性: +`exec()`方法的返回数组还包含以下两个属性: - `input`:整个原字符串。 -- `index`:整个模式匹配成功的开始位置(从0开始计数)。 +- `index`:模式匹配成功的开始位置(从0开始计数)。 ```javascript var r = /a(b+)a/; @@ -178,7 +178,7 @@ arr.input // "_abbba_aba_" 上面代码中的`index`属性等于1,是因为从原字符串的第二个位置开始匹配成功。 -如果正则表达式加上`g`修饰符,则可以使用多次`exec`方法,下一次搜索的位置从上一次匹配成功结束的位置开始。 +如果正则表达式加上`g`修饰符,则可以使用多次`exec()`方法,下一次搜索的位置从上一次匹配成功结束的位置开始。 ```javascript var reg = /a/g; @@ -204,7 +204,7 @@ r4 // null reg.lastIndex // 0 ``` -上面代码连续用了四次`exec`方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,匹配结果返回`null`,正则实例对象的`lastIndex`属性也重置为`0`,意味着第四次匹配将从头开始。 +上面代码连续用了四次`exec()`方法,前三次都是从上一次匹配结束的位置向后匹配。当第三次匹配结束以后,整个字符串已经到达尾部,匹配结果返回`null`,正则实例对象的`lastIndex`属性也重置为`0`,意味着第四次匹配将从头开始。 利用`g`修饰符允许多次匹配的特点,可以用一个循环完成全部匹配。 @@ -222,7 +222,7 @@ while(true) { // #8:a ``` -上面代码中,只要`exec`方法不返回`null`,就会一直循环下去,每次输出匹配的位置和匹配的文本。 +上面代码中,只要`exec()`方法不返回`null`,就会一直循环下去,每次输出匹配的位置和匹配的文本。 正则实例对象的`lastIndex`属性不仅可读,还可写。设置了`g`修饰符的时候,只要手动设置了`lastIndex`的值,就会从指定位置开始匹配。 From 23b342aad96e264d5f35a5191783f7741b980589 Mon Sep 17 00:00:00 2001 From: ruanyf Date: Fri, 21 Feb 2020 19:01:49 +0800 Subject: [PATCH 145/300] docs(dom): add document.currentScript --- docs/dom/document.md | 14 ++++++++++++++ docs/stdlib/date.md | 27 +++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/docs/dom/document.md b/docs/dom/document.md index 4a5315c..8e08982 100644 --- a/docs/dom/document.md +++ b/docs/dom/document.md @@ -327,6 +327,20 @@ var editor = document.getElementById('editor'); editor.contentDocument.designMode = 'on'; ``` +### document.currentScript + +`document.currentScript`属性只用在` +``` + +上面代码中,`document.currentScript`就是`