Skip to content

Commit

Permalink
zh-cn: resolve the global functions clearInterval() and `setInterva…
Browse files Browse the repository at this point in the history
…l()`

ref: mdn/content#36042
  • Loading branch information
yin1999 committed Oct 5, 2024
1 parent 9d1cf02 commit a7303c2
Show file tree
Hide file tree
Showing 27 changed files with 272 additions and 159 deletions.
2 changes: 1 addition & 1 deletion files/zh-cn/games/anatomy/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ var tNow = window.performance.now();

一种常见的技术是以恒定的频率更新模拟,然后绘制尽可能多的(或尽可能少的)实际帧。更新方法可以继续循环,而不用考虑用户看到的内容。绘图方法可以查看最后的更新以及发生的时间。由于绘制知道何时表示,以及上次更新的模拟时间,它可以预测为用户绘制一个合理的框架。这是否比官方更新循环更频繁(甚至更不频繁)无关紧要。更新方法设置检查点,并且像系统允许的那样频繁地,渲染方法画出周围的时间。在 Web 标准中分离更新方法有很多种方法:

- 绘制 `requestAnimationFrame` 并更新 {{domxref("setInterval()")}} 或 {{domxref("setTimeout()")}}。
- `requestAnimationFrame()` 中绘制,并在 {{domxref("Window.setInterval", "setInterval()")}} 或 {{domxref("setTimeout()")}} 中更新

- 即使在未聚焦或最小化的情况下,使用处理器时间,也可能是主线程,并且可能是传统游戏循环的工件(但是很简单)。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ drawLives();

## 用 requestAnimationFrame() 优化渲染

现在让我们处理一些与游戏机制无关,但与画面渲染相关的东西。和我们目前使用{{domxref("windowTimers.setInterval()", "setInterval()")}} 实现的固定帧率渲染相比,{{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} 能让浏览器更好地渲染画面。让我们把下面这行代码:
现在让我们处理一些与游戏机制无关,但与画面渲染相关的东西。和我们目前使用 {{domxref("Window.setInterval", "setInterval()")}} 实现的固定帧率渲染相比,{{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} 能让浏览器更好地渲染画面。让我们把下面这行代码:

```js
var interval = setInterval(draw, 10);
interval = setInterval(draw, 10);
```

替换为:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball

从上一节中你已经知道如何去绘制一个球。现在让我们使它动起来。从技术上讲,我们将在画布上绘制一个球,之后让它消失,然后在一个稍微不用的位置上再绘制一个一样的球。就想电影里的每一帧动起来的感觉。

我们需要定义一个绘图函数,每次使用一组不同的变量改变球体的位置;循环调用以保持画布上每一帧不断更新。你可以使用 JavaScript 时间函数 {{domxref("WindowTimers.setInterval()", "setInterval()")}} 或者 {{domxref("window.requestAnimationFrame()")}}。
我们需要定义一个绘图函数,每次使用一组不同的变量改变球体的位置;循环调用以保持画布上每一帧不断更新。你可以使用 JavaScript 时间函数 {{domxref("Window.setInterval", "setInterval()")}} 或者 {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}}。

在你的 HTML 文件只保留前两行,删除其他所有的 JavaScript 代码并在 draw() 函数中添加以下内容保证每 10 毫秒执行一次 draw() 函数:

Expand Down
18 changes: 9 additions & 9 deletions files/zh-cn/learn/accessibility/wai-aria_basics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ slug: Learn/Accessibility/WAI-ARIA_basics

紧接上文继续,有时候,我们制作涉及非语义 HTML 和动态的 JavaScript 内容更新的复杂 UI 控件可能很困难。**WAI-ARIA** 是一项技术,它可以通过浏览器和一些辅助技术来帮助我们进一步地识别以及实现语义化,这样一来能帮助我们解决问题,也让用户可以了解发生了什么。接下来我们将展示如何运用它来优化无障碍体验:

<table class="learn-box standard-table">
<table>
<tbody>
<tr>
<th scope="row">前提要求:</th>
Expand Down Expand Up @@ -36,7 +36,7 @@ slug: Learn/Accessibility/WAI-ARIA_basics

当 Web 应用开始变得越来越复杂和动态化,一堆全新的无障碍访问问题和特性接踵而至。

例如,HTML5 提出了几种语义化标签用于定义常规页面的特性 (例如 nav, footer 等等) 。在这些标签可用之前,我们一般简单地用 div 带上 ID 抑或是 class 来解决问题,例如:`<div class="nav">`。但是这种实践是问题丛生的,因为没有简单的方法可以轻松地用可编程的方法找到特定页面功能,例如主导航。
例如,HTML5 提出了几种语义化标签用于定义常规页面的特性例如 navfooter 等等。在这些标签可用之前,我们一般简单地用 div 带上 ID 抑或是 class 来解决问题,例如:`<div class="nav">`。但是这种实践是问题丛生的,因为没有简单的方法可以轻松地用可编程的方法找到特定页面功能,例如主导航。

最早的解决方案是加一个或者多个隐藏的链接来跳转到我们想要的位置,例如(这里用导航举例):

Expand Down Expand Up @@ -214,20 +214,20 @@ WAI-ARIA 给浏览器增加了 [`role`](https://www.w3.org/TR/wai-aria-1.1/#role
</section>
```

我们的 JavaScript [`XMLHttpRequest`](/zh-CN/docs/Web/API/XMLHttpRequest) 加载一个 JSON 文件里头包含了一系列的名人名言,一旦完成我们就开始用一个 [`setInterval()`](/zh-CN/docs/Web/API/WindowTimers/setInterval) 循环以十秒一次的频率显示出来。
我们的 JavaScript 使用 {{domxref("Window.fetch", "fetch()")}} API 加载一个 JSON 文件(里头包含了一系列的名人名言),一旦完成我们就开始用一个 {{domxref("Window.setInterval", "setInterval()")}} 循环以十秒一次的频率显示出来。

```js
var intervalID = window.setInterval(showQuote, 10000);
const intervalID = setInterval(showQuote, 10000);
```

这当然是可行的,但是对于无障碍可不友善——这种内容变化是不会被屏幕阅读器察觉到的,所以用户不会发现发生了什么。这是一个简单的例子,但你可以想象一下:如果你开发的一个复杂 UI 而且内容频繁变化的应用,例如聊天室,或者一个策略游戏的界面,或者一个实时更新的购物车展示。如果没有某种方式提示用户有内容更新,那就不可能以任何有效的方式来使用应用。

幸运的是,WAI-ARIA 提供了一种有效的机制来发起提示——[`aria-live`](https://www.w3.org/TR/wai-aria-1.1/#aria-live)。将此应用于元素会让屏幕阅读器读出更新的内容。读取内容的紧急程度取决于属性值:

- `off`: 默认值,更新不会提醒。
- `polite`: 只有用户空闲的情况下提醒。
- `assertive`: 尽快提醒。
- `rude`: 会以打断用户操作的方式直接提醒。
- `off`默认值,更新不会提醒。
- `polite`只有用户空闲的情况下提醒。
- `assertive`尽快提醒。
- `rude`会以打断用户操作的方式直接提醒。

通常来说 `assertive` 设置足以让你的更新在显示时按时序读出,因此,如果改变多次,那么他只会念出最后一个改变。除非紧急程度高到需要覆盖其他的更新才选择使用 `rude`

Expand Down Expand Up @@ -333,7 +333,7 @@ var intervalID = window.setInterval(showQuote, 10000);

```js
function toggleMusician(bool) {
var instruItem = formItems[formItems.length - 1];
const instruItem = formItems[formItems.length - 1];
if (bool) {
instruItem.input.disabled = false;
instruItem.label.style.color = "#000";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ button:before {
1. 我们清除在快进功能上设置的所有类和时间间隔。这样做是因为如果我们在按下 `fwd`(快进)按钮后再按下 `rwd`(快退)按钮,就可以取消任何快进的功能并将其替换为快退功能。如果我们试图同时做到这两点,播放器就会暂停。
2. 使用 `if` 语句检查是否已在 `rwd` 按钮上设置了用来指示它已被按下的 `active` 类。{{domxref("classList")}} 是一个存在于每个元素上的非常方便的属性。它包含元素上设置的所有类的列表,以及添加/删除类的方法等。使用 `classList.contains()` 方法检查列表是否包含 `active` 类,将返回布尔值 `true`/`false` 结果。
3. 如果在 `rwd` 按钮上设置了 `active`,我们将使用 `classList.remove()` 删除它,清除第一次按下按钮时设置的时间间隔(参见下面的更多解释),并调用 {{domxref("HTMLMediaElement.play()")}} 取消快退并开始正常播放视频。
4. 如果尚未设置,使用 `classList.add()``active` 类添加到 `rwd` 按钮,调用 {{domxref("HTMLMediaElement.pause()")}} 暂停视频,然后设置 `intervalRwd` 变量为 {{domxref("setInterval()")}} 的调用结果。调用时,`setInterval()` 会创建一个时间间隔。这意味着它每隔 x 毫秒运行一个作为第一个参数给出的函数,其中 x 是第二个参数的值。所以这里我们每 200 毫秒运行一次 `windBackward()` 函数——我们将使用此函数不断快退视频。要停止 {{domxref("setInterval()")}} 运行,你必须调用 {{domxref("clearInterval()")}},并给出要清除的时间间隔的标识名,在本例中是变量名称 `intervalRwd`(请参阅函数中较早的一个 `clearInterval()` 调用)。
4. 如果尚未设置,使用 `classList.add()``active` 类添加到 `rwd` 按钮,调用 {{domxref("HTMLMediaElement.pause()")}} 暂停视频,然后设置 `intervalRwd` 变量为 {{domxref("Window.setInterval", "setInterval()")}} 的调用结果。调用时,`setInterval()` 会创建一个时间间隔。这意味着它每隔 x 毫秒运行一个作为第一个参数给出的函数,其中 x 是第二个参数的值。所以这里我们每 200 毫秒运行一次 `windBackward()` 函数——我们将使用此函数不断快退视频。要停止 {{domxref("Window.setInterval", "setInterval()")}} 运行,你必须调用 {{domxref("Window.clearInterval", "clearInterval()")}},并给出要清除的时间间隔的标识名,在本例中是变量名称 `intervalRwd`(请参阅函数中较早的一个 `clearInterval()` 调用)。

3. 最后,对于本节,定义在 `setInterval()` 调用中需要调用的 `windBackward()``windForward()` 函数。在以上两个函数下面添加以下内容:

Expand Down
2 changes: 1 addition & 1 deletion files/zh-cn/learn/performance/javascript/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ async function main() {

对于关键的 DOM 动画,建议尽可能使用 [CSS 动画](/zh-CN/docs/Web/CSS/CSS_animations/Using_CSS_animations),而不是 JavaScript 动画([Web 动画 API](/zh-CN/docs/Web/API/Web_Animations_API) 提供了一种通过 JavaScript 直接连接到 CSS 动画的方式)。直接使用浏览器执行 DOM 动画而不是使用 JavaScript 操纵内联样式表的效率更高。另请参阅 [CSS 性能优化 > 处理动画](/zh-CN/docs/Learn/Performance/CSS#处理动画)

对于无法在 JavaScript 中处理的动画,例如在 HTML {{htmlelement("canvas")}} 上创建动画,建议使用 {{domxref("Window.requestAnimationFrame()")}} 而不是旧的选项,例如 {{domxref("setInterval()")}}。`requestAnimationFrame()` 方法专门设计用于高效、一致地处理动画帧,以获得流畅的用户体验。基本模式如下所示:
对于无法在 JavaScript 中处理的动画,例如在 HTML {{htmlelement("canvas")}} 上创建动画,建议使用 {{domxref("Window.requestAnimationFrame()")}} 而不是旧的选项,例如 {{domxref("Window.setInterval()")}}。`requestAnimationFrame()` 方法专门设计用于高效、一致地处理动画帧,以获得流畅的用户体验。基本模式如下所示:

```js
function loop() {
Expand Down
4 changes: 2 additions & 2 deletions files/zh-cn/mozilla/add-ons/webextensions/api/alarms/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
title: alarms
slug: Mozilla/Add-ons/WebExtensions/API/alarms
l10n:
sourceCommit: eec174a08a5003da32f53e694c45eda3377b4d18
sourceCommit: b795bc99fc5c5d8a96c1b202a12750404085c28a
---

{{AddonSidebar}}

在未来一个特定的时间运行的计划任务代码。这很像 [`setTimeout()`](/zh-CN/docs/Web/API/WindowTimers/setTimeout)[`setInterval()`](/zh-CN/docs/Web/API/WindowTimers/setInterval),不过这些函数仅可以按需使用而不能在后台页面工作。
在未来一个特定的时间运行的计划任务代码。这很像 [`setTimeout()`](/zh-CN/docs/Web/API/WindowTimers/setTimeout)、{{domxref("Window.setInterval()")}}{{domxref("WorkerGlobalScope.setInterval()")}},不过这些函数仅可以按需使用而不能在后台页面工作。

闹钟不会在浏览器会话之间持续存在。它们在单个扩展的所有上下文中全局创建。例如,在后台脚本中创建的闹钟将在后台脚本、选项页面、弹出页面和扩展标签页中触发 [`onAlarm`](/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/alarms/onAlarm) 事件(反之亦然)。闹钟 API 在[内容脚本](/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#webextension_apis)中不可用。

Expand Down
39 changes: 21 additions & 18 deletions files/zh-cn/mozilla/add-ons/webextensions/content_scripts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -600,22 +600,25 @@ In page script, window.x: 1
In page script, window.y: undefined
```
上述内容同样适用于 [`setTimeout()`](/zh-CN/docs/Web/API/setTimeout), [`setInterval()`](/zh-CN/docs/Web/API/setInterval), and [`Function()`](/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function).
上述内容同样适用于 [`setTimeout()`](/zh-CN/docs/Web/API/setTimeout)、{{domxref("Window.setInterval", "setInterval()")}} 和 [`Function()`](/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function)
当在页面的上下文中运行代码时,适用于上面所提到的"[Sharing content script objects with page scripts](/zh-CN/Add-ons/WebExtensions/Content_scripts#Sharing_objects_with_page_scripts)" 这一部分的警告:页面的环境可能会被恶意的网页所控制,这可能会导致你所交互的对象会有意想不到的行为:
```js
// page.js redefines console.log

var original = console.log;

console.log = function () {
original(true);
};
```
```js
// content-script.js calls the redefined version

window.eval("console.log(false)");
```
> [!WARNING]
> 在页面的上下文中运行代码时要非常小心!
>
> 页面的环境由潜在的恶意网页控制,这些网页可以重新定义与你交互的对象,使其以意想不到的方式运行:
>
> ```js example-bad
> // page.js 重新定义 console.log
>
> let original = console.log;
>
> console.log = () => {
> original(true);
> };
> ```
>
> ```js example-bad
> // content-script.js 调用了重新定义的版本
>
> window.eval("console.log(false)");
> ```
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ slug: Web/API/Canvas_API/Tutorial/Basic_animations

### 有安排地更新画布

首先,可以用{{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}},和{{domxref("window.requestAnimationFrame()")}}来设定定期执行一个指定函数。
首先,可以用 {{domxref("Window.setInterval", "setInterval()")}}{{domxref("window.setTimeout()")}}{{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} 来设定定期执行一个指定函数。

- {{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}
- {{domxref("Window.setInterval", "setInterval()")}}
- : 当设定好间隔时间后,function 会定期执行。
- {{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}
- {{domxref("setTimeout()")}}
- : 在设定好的时间之后执行函数
- {{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}
- {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}}
- : 告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。

如果你并不需要与用户互动,你可以使用 setInterval() 方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上 setTimeout() 方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。
如果你并不需要与用户互动,你可以使用 `setInterval()` 方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上 `setTimeout()` 方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。

> [!NOTE]
> 下面的例子,采用 {{domxref("window.requestAnimationFrame()")}}实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行 60 次,也有可能会被降低。想要了解更多关于动画循环的信息,尤其是游戏,可以在[Game development zone](/zh-CN/docs/Games) 参考这篇文章 [Anatomy of a video game](/zh-CN/docs/Games/Anatomy)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ if (canvas.getContext) {
</html>
```

上面的脚本中包含一个叫做 draw() 的函数,当页面加载结束的时候就会执行这个函数。通过使用在文档上加载事件来完成。只要页面加载结束,这个函数,或者像是这个的,同样可以使用 {{domxref("WindowTimers.setTimeout", "window.setTimeout()")}}{{domxref("WindowTimers.setInterval", "window.setInterval()")}},或者其他任何事件处理程序来调用。
上面的脚本中包含一个叫做 draw() 的函数,当页面加载结束的时候就会执行这个函数。通过使用在文档上加载事件来完成。只要页面加载结束,这个函数,或者像是这个的,同样可以使用 {{domxref("WindowTimers.setTimeout", "window.setTimeout()")}}{{domxref("Window.setInterval", "setInterval()")}},或者其他任何事件处理程序来调用。

模板看起来会是这样。如这里所示,它最初是空白的。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ var ctx = canvas.getContext("2d", { alpha: false });
- 尽可能避免 {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}特性
- 尽可能避免[text rendering](/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_text)
- 尝试不同的方法来清除画布 ({{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} vs. {{domxref("CanvasRenderingContext2D.fillRect", "fillRect()")}} vs. 调整 canvas 大小)
- 有动画,请使用{{domxref("window.requestAnimationFrame()")}} 而非{{domxref("window.setInterval()")}}
- 有动画,请使用 {{domxref("Window.requestAnimationFrame()")}} 而非 {{domxref("Window.setInterval", "setInterval()")}}
- 请谨慎使用大型物理库

## 参见
Expand Down
18 changes: 8 additions & 10 deletions files/zh-cn/web/api/cleartimeout/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ slug: Web/API/clearTimeout

## 语法

```plain
scope.clearTimeout(timeoutID)
```js-nolint
clearTimeout(timeoutID)
```

### Parameters
### 参数

- `timeoutID`
- : 你要取消定时器的标识符。该 ID 由相应的`setTimeout()`调用返回。

值得注意的是,{{domxref("setTimeout()")}} 和 {{domxref("setInterval()")}} 使用共享的 ID 池,意味着在技术上可以混用 `clearTimeout()` 和 {{domxref("clearInterval()")}}。但是,为了清楚起见,你应该避免这样做。
值得注意的是,{{domxref("setTimeout()")}} 和 {{domxref("Window.setInterval", "setInterval()")}} 共享同一个 ID 池,意味着在技术上可以混用 `clearTimeout()` 和 {{domxref("Window.clearInterval", "clearInterval()")}}。但是,为了清楚起见,你应该避免这样做。

## 示例

Expand Down Expand Up @@ -67,10 +67,8 @@ window.onclick = function () {

{{Compat}}

## 更多
## 参见

- {{domxref("WindowTimers.setTimeout()")}}
- {{domxref("WindowTimers.setInterval()")}}
- {{domxref("WindowTimers.clearInterval()")}}
- {{domxref("Window.requestAnimationFrame()")}}
- [_Daemons_ management](/zh-CN/docs/JavaScript/Timers/Daemons)
- {{domxref("setTimeout()")}}
- {{domxref("Window.clearInterval()")}} 和 {{domxref("WorkerGlobalScope.clearInterval()")}}
- {{domxref("Window.cancelAnimationFrame()")}} 和 {{domxref("DedicatedWorkerGlobalScope.cancelAnimationFrame()")}}
Loading

0 comments on commit a7303c2

Please sign in to comment.