原文链接:https://developer.chrome.com/native-client/devguide/coding/progress-events
注意:已针对ChromeOS以外的平台公布了此处所述技术的弃用。
请访问我们的 迁移指南 了解详情。
进程事件
开发人员可以在Native Client中响应五种类型的事件:进度,消息,视图更改,焦点和输入事件(每个事件在下面的术语表中描述)。本节介绍如何监视进度事件(在加载和执行Native Client模块期间发生的事件)。本节假定您熟悉技术概述中提供的材料 。
load_progress示例说明了进度事件处理。您可以/pepper_<version>/examples/tutorial/load_progress/
在Native Client SDK下载的目录中找到此代码。
模块加载和进度事件
Native Client运行时通过DOM进度事件在模块加载过程中报告一组状态更改。这组事件是建议的W3C Progress Events标准的直接端口(除了作为crash
W3C标准的扩展的事件)。下表列出了Native Client运行时报告的事件类型:
事件 | 时间触发了 | 触发时 | 你可能会如何回应 |
---|---|---|---|
Native Client已开始加载Native Client模块。 |
一旦 | 实例化并初始化Native Client模块之后的第一个progress事件。 | 显示状态消息,例如“正在加载...” |
部分模块已加载。 |
零或更多 | 之后 loadstart 被派遣了。 |
显示进度条。 |
Native Client模块无法开始执行(包括模块初始化之前或期间的任何错误)。该 |
零或一次 | 在progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 |
通知用户应用程序无法加载。 |
用户中止了NativeClient模块的加载。 |
零或一次 | 在progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 |
你不太可能想要回应这个事件。 |
Native Client模块已成功加载,并已开始执行。(模块已成功初始化。) |
零或一次 | 在progress 调度最后一个 事件之后,或者在loadstart 没有progress 调度事件之后 。 |
删除进度条。 |
加载Native Client模块已停止。加载成功( |
一旦 | 在发送了一个error ,abort 或者 load 事件之后 。 |
表示加载结束(无论是否失败)。 |
成功加载后,Native Client模块没有响应(在 |
零或一次 | 过了一会儿loadend 。 |
通知用户该模块执行了非法操作。 |
成功加载模块的事件顺序如下:
事件已发送 | ...然后尝试执行此任务 |
---|---|
loadstart |
加载清单文件 |
progress (第一次) |
加载模块 |
progress (后续) |
|
load |
开始执行模块 |
loadend |
加载期间发生的错误会记录到Google Chrome中的JavaScript控制台(选择菜单图标>工具> JavaScript控制台)。
处理进度事件
您应该在<script>
元素中添加事件侦听器,以便在<embed>
解析元素之前侦听这些事件。例如,以下代码将load
事件的侦听器添加到<div>
也包含Native Client <embed>
元素的父元素。首先,听众是附上的。然后,当侦听器<div>
收到load
事件时,将moduleDidLoad()
调用JavaScript 函数。以下代码摘自以下示例getting_started/part1/
:
<!--
Load the published pexe.
Note: Since this module does not use any real-estate in the browser, its
width and height are set to 0.
Note: The <embed> element is wrapped inside a <div>, which has both a 'load'
and a 'message' event listener attached. This wrapping method is used
instead of attaching the event listeners directly to the <embed> element to
ensure that the listeners are active before the NaCl module 'load' event
fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
pp::Instance.PostMessage() (in C++) from within the initialization code in
your module.
-->
<div id="listener">
<script type="text/javascript">
var listener = document.getElementById('listener');
listener.addEventListener('load', moduleDidLoad, true);
listener.addEventListener('message', handleMessage, true);
</script>
<embed id="hello_tutorial"
width=0 height=0
src="hello_tutorial.nmf"
type="application/x-pnacl" />
</div>
可以将事件侦听器添加到任何DOM对象。由于设置在最外层范围的侦听器捕获其包含元素的事件,因此可以在外部元素(包括<body>
元素)上设置侦听器以处理来自内部元素的事件。有关更多信息,请参阅事件流捕获和 事件侦听器注册的W3规范。
显示负载状态
对进度事件的一个常见响应是显示已加载的模块的百分比。在load_progress示例中,当progress
触发事件时,将moduleLoadProgress
调用该函数。此函数使用事件的lengthComputable
,, loaded
和total
属性(在建议的W3C Progress Events 标准中描述)来计算已加载模块的百分比。
function moduleLoadProgress(event) {
var loadPercent = 0.0;
var loadPercentString;
if (event.lengthComputable && event.total > 0) {
loadPercent = event.loaded / event.total * 100.0;
loadPercentString = loadPercent + '%';
common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
' (' + event.loaded + ' of ' + event.total + ' bytes)');
} else {
// The total length is not yet known.
common.logMessage('progress: Computing...');
}
}
该lastError
属性
所述<embed>
元件具有lastError
每当加载失败(一个被设置为一个信息串属性error
或abort
事件)时。
以下代码在<embed>
元素之前添加事件侦听器,以捕获并处理加载Native Client模块时的错误。该 handleError()
函数侦听error
事件。发生错误时,此函数将lastError
属性(embed_element.lastError
)的内容作为警报打印。
function domContentLoaded(name, tc, config, width, height) {
var listener = document.getElementById('listener');
...
listener.addEventListener('error', moduleLoadError, true);
...
common.createNaClModule(name, tc, config, width, height);
}
function moduleLoadError() {
common.logMessage('error: ' + common.naclModule.lastError);
}
该readyState
属性
您可以使用该readyState
属性来监视加载过程。如果您不关心单个进度事件的详细信息,或者您希望在不注册侦听器的情况下轮询当前加载状态,则此属性特别有用。readyState
成功加载的进度值如下:
事件 | readyState 值 |
---|---|
(在任何事件之前) | undefined |
loadstart |
1 |
progress |
3 |
load |
4 |
loadend |
4 |
以下代码演示了如何使用该readyState
属性监视加载过程 。和以前一样,添加事件侦听器的脚本在<embed>
元素之前,以便在生成progress事件之前事件侦听器就位。
<html>
...
<body id="body">
<div id="status_div">
</div>
<div id="listener_div">
<script type="text/javascript">
var stat = document.getElementById('status_div');
function handleEvent(e) {
var embed_element = document.getElementById('my_embed');
stat.innerHTML +=
'<br>' + e.type + ': readyState = ' + embed_element.readyState;
}
var listener_element = document.getElementById('listener_div');
listener_element.addEventListener('loadstart', handleEvent, true);
listener_element.addEventListener('progress', handleEvent, true);
listener_element.addEventListener('load', handleEvent, true);
listener_element.addEventListener('loadend', handleEvent, true);
</script>
<embed
name="naclModule"
id="my_embed"
width=0 height=0
src="my_example.nmf"
type="application/x-pnacl" />
</div>
</body>
</html>
该exitStatus
属性
如果应用程序调用,或崩溃exit(n)
, 则设置此只读属性abort()
。由于NaCl模块是事件处理程序,因此无需exit(n)
在正常执行中调用。如果模块退出或崩溃,crash
则发出progress事件,该exitStatus
属性将包含退出状态的数值:
- 在显式调用的情况下
exit(n)
,数值将是n
(在0到255之间)。 - 在崩溃和调用的情况下
abort()
,数值将不为零,但确切的值将取决于所选的libc和目标体系结构,并且将来可能会更改。exitStatus
在这些情况下,应用程序不应该依赖于稳定的值,但是该值可能对临时调试很有用。
CC-By 3.0许可下提供的内容