21.3 进度事件

优质
小牛编辑
115浏览
2023-12-01

Progress Events 规范是W3C 的一个工作草案,定义了与客户端服务器通信有关的事件。这些事件最早其实只针对XHR 操作,但目前也被其他API 借鉴。有以下6 个进度事件。

  • loadstart:在接收到响应数据的第一个字节时触发。
  • progress:在接收响应期间持续不断地触发。
  • error:在请求发生错误时触发。
  • abort:在因为调用abort()方法而终止连接时触发。
  • load:在接收到完整的响应数据时触发。
  • loadend:在通信完成或者触发error、abort 或load 事件后触发。

每个请求都从触发loadstart 事件开始,接下来是一或多个progress 事件,然后触发error、abort 或load 事件中的一个,最后以触发loadend 事件结束。支持前5 个事件的浏览器有Firefox 3.5+、Safari 4+、Chrome、iOS 版Safari 和Android 版WebKit。
Opera(从第11 版开始)、IE 8+只支持load 事件。目前还没有浏览器支持loadend 事件。这些事件大都很直观,但其中两个事件有一些细节需要注意。

21.3.1 load事件

Firefox 在实现XHR 对象的某个版本时,曾致力于简化异步交互模型。最终,Firefox 实现中引入了load 事件,用以替代readystatechange 事件。响应接收完毕后将触发load 事件,因此也就没有必要去检查readyState 属性了。而onload 事件处理程序会接收到一个event 对象,其target 属性就指向XHR 对象实例,因而可以访问到XHR 对象的所有方法和属性。然而,并非所有浏览器都为这个事件实现了适当的事件对象。结果,开发人员还是要像下面这样被迫使用XHR 对象变量。

var xhr = createXHR();
xhr.onload = function() {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);
} else {alert("Request was unsuccessful: " + xhr.status);
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);

运行一下
只要浏览器接收到服务器的响应,不管其状态如何,都会触发load 事件。而这意味着你必须要检查status 属性,才能确定数据是否真的已经可用了。Firefox、Opera、Chrome 和Safari 都支持load事件。

21.3.2 progress事件

Mozilla 对XHR 的另一个革新是添加了progress 事件,这个事件会在浏览器接收新数据期间周期性地触发。而onprogress 事件处理程序会接收到一个event 对象,其target 属性是XHR 对象,但包含着三个额外的属性:lengthComputable、position 和totalSize。其中,lengthComputable是一个表示进度信息是否可用的布尔值,position 表示已经接收的字节数,totalSize 表示根据Content-Length 响应头部确定的预期字节数。有了这些信息,我们就可以为用户创建一个进度指示器了。下面展示了为用户创建进度指示器的一个示例。

var xhr = createXHR();
xhr.onload = function(event) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);
} else {alert("Request was unsuccessful: " + xhr.status);
}
};
xhr.onprogress = function(event) {
var divStatus = document.getElementById("status");
if (event.lengthComputable) {divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize + " bytes";
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);

运行一下
为确保正常执行,必须在调用open()方法之前添加onprogress 事件处理程序。在前面的例子中,每次触发progress 事件,都会以新的状态信息更新HTML 元素的内容。如果响应头部中包含Content-Length 字段,那么也可以利用此信息来计算从响应中已经接收到的数据的百分比。