Skip to content

Commit 3f39bd7

Browse files
committed
docs(bom): edit window
1 parent 2debcf7 commit 3f39bd7

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

docs/async/timer.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ console.log(2);
288288

289289
总之,`setTimeout(f, 0)`这种写法的目的是,尽可能早地执行`f`,但是并不能保证立刻就执行`f`
290290

291+
实际上,`setTimeout(f, 0)`不会真的在0毫秒之后运行,不同的浏览器有不同的实现。以 Edge 浏览器为例,会等到4毫秒之后运行。如果电脑正在使用电池供电,会等到16毫秒之后运行;如果网页不在当前 Tab 页,会推迟到1000毫秒(1秒)之后运行。这样是为了节省系统资源。
292+
291293
### 应用
292294

293295
`setTimeout(f, 0)`有几个非常重要的用途。它的一大应用是,可以调整事件的发生顺序。比如,网页开发中,某个事件先发生在子元素,然后冒泡到父元素,即子元素的事件回调函数,会早于父元素的事件回调函数触发。如果,想让父元素的事件回调函数先发生,就要用到`setTimeout(f, 0)`

docs/bom/window.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,91 @@ var selectedText = selObj.toString();
529529

530530
`window.matchMedia()`方法用来检查 CSS 的`mediaQuery`语句,详见《CSS 操作》一章。
531531

532+
### window.requestAnimationFrame()
533+
534+
`window.requestAnimationFrame()`方法跟`setTimeout`类似,都是推迟某个函数的执行。不同之处在于,`setTimeout`必须指定推迟的时间,`window.requestAnimationFrame()`则是推迟到浏览器下一次重流时执行,即在下一次重绘之前执行。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,`requestAnimationFrame()`会暂停执行。
535+
536+
如果某个函数会改变网页的布局,一般就放在`window.requestAnimationFrame()`里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。
537+
538+
该方法接受一个回调函数作为参数。
539+
540+
```javascript
541+
window.requestAnimationFrame(callback)
542+
```
543+
544+
上面代码中,`callback`是一个回调函数。`callback`执行时,它的参数就是系统传入的一个高精度时间戳(`performance.now()`的返回值),单位是毫秒,表示距离网页加载的时间。
545+
546+
`window.requestAnimationFrame()`的返回值是一个整数,这个整数可以传入`window.cancelAnimationFrame()`,用来取消回调函数的执行。
547+
548+
下面是一个`window.requestAnimationFrame()`执行网页动画的例子。
549+
550+
```javascript
551+
var element = document.getElementById('animate');
552+
element.style.position = 'absolute';
553+
554+
var start = null;
555+
556+
function step(timestamp) {
557+
if (!start) start = timestamp;
558+
var progress = timestamp - start;
559+
// 元素不断向左移,最大不超过200像素
560+
element.style.left = Math.min(progress / 10, 200) + 'px';
561+
// 如果距离第一次执行不超过 2000 毫秒,
562+
// 就继续执行动画
563+
if (progress < 2000) {
564+
window.requestAnimationFrame(step);
565+
}
566+
}
567+
568+
window.requestAnimationFrame(step);
569+
```
570+
571+
上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。
572+
573+
### window.requestIdleCallback()
574+
575+
`window.requestIdleCallback()``setTimeout`类似,也是将某个函数推迟执行,但是它保证将回调函数推迟到系统资源空闲时执行。也就是说,如果某个任务不是很关键,就可以使用`window.requestIdleCallback()`将其推迟执行,以保证网页性能。
576+
577+
它跟`window.requestAnimationFrame()`的区别在于,后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不一定能保证在16毫秒之内完成;`window.requestIdleCallback()`可以保证回调函数在系统资源空闲时执行。
578+
579+
该方法接受一个回调函数和一个配置对象作为参数。配置对象可以指定一个推迟执行的最长时间,如果过了这个时间,回调函数不管系统资源有无空虚,都会执行。
580+
581+
```javascript
582+
window.requestIdleCallback(callback[, options])
583+
```
584+
585+
`callback`参数是一个回调函数。该回调函数执行时,系统会传入一个`IdleDeadline`对象作为参数。`IdleDeadline`对象有一个`didTimeout`属性(布尔值,表示是否为超时调用)和一个`timeRemaining()`方法(返回该空闲时段剩余的毫秒数)。
586+
587+
`options`参数是一个配置对象,目前只有`timeout`一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。
588+
589+
`window.requestAnimationFrame()`方法返回一个整数。该整数可以传入`window.cancelIdleCallback()`取消回调函数。
590+
591+
下面是一个例子。
592+
593+
```javascript
594+
requestIdleCallback(myNonEssentialWork);
595+
596+
function myNonEssentialWork(deadline) {
597+
while (deadline.timeRemaining() > 0) {
598+
doWorkIfNeeded();
599+
}
600+
}
601+
```
602+
603+
上面代码中,`requestIdleCallback()`用来执行非关键任务`myNonEssentialWork`。该任务先确认本次空闲时段有剩余时间,然后才真正开始执行任务。
604+
605+
下面是指定`timeout`的例子。
606+
607+
```javascript
608+
requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });
609+
```
610+
611+
上面代码指定,`processPendingAnalyticsEvents`必须在未来2秒之内执行。
612+
613+
如果由于超时导致回调函数执行,则`deadline.timeRemaining()`返回`0``deadline.didTimeout`返回`true`
614+
615+
如果多次执行`window.requestAnimationFrame()`,指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。
616+
532617
## 事件
533618

534619
`window`对象可以接收以下事件。

docs/events/common.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ window.addEventListener('scroll', throttle(callback, 1000));
259259
window.addEventListener('scroll', _.throttle(callback, 1000));
260260
```
261261

262+
本书前面介绍过`debounce`的概念,`throttle`与它区别在于,`throttle`是“节流”,确保一段时间内只执行一次,而`debounce`是“防抖”,要连续操作结束后再执行。以网页滚动为例,`debounce`要等到用户停止滚动后才执行,`throttle`则是如果用户一直在滚动网页,那么在滚动过程中还是会执行。
263+
262264
### resize 事件
263265

264266
`resize`事件在改变浏览器窗口大小时触发,主要发生在`window`对象上面。

0 commit comments

Comments
 (0)