新兴的API
requestAnimationFrame()
早期动画循环
-
基本动画循环
(function(){ function updateAnimations(){ doAnimation1(); doAnimation2(); //其他动画 } setInterval(updateAnimations, 100); })();
循环间隔问题
-
几个浏览器的计时器精度
- IE8 及更早版本的计时器精度为 15.625ms。
- IE9 及更晚版本的计时器精度为 4ms。
- Firefox 和 Safari 的计时器精度大约为 10ms。
- Chrome 的计时器精度为 4ms。
mozRequestAnimationFrame()
-
mozRequestAnimationFrame() 方法接收一个参数,即在重绘屏幕前调用的一个函数。这个函数负责改变下一次重绘时的 DOM样式。为了创建动画循环,可以像以前使用 setTimeout() 一样,把多个对mozRequestAnimationFrame() 的调用连缀起来
function updateProgress(){ var div = document.getElementById("status"); div.style.width = (parseInt(div.style.width, 10) + 5) + "%"; if (div.style.left != "100%"){ mozRequestAnimationFrame(updateProgress); } } mozRequestAnimationFrame(updateProgress);
webkitRequestAnimationFrame()与msRequestAnimationFrame()
(function(){
function draw(timestamp){
//计算两次重绘的时间间隔
var drawStart = (timestamp || Date.now()),
diff = drawStart - startTime;
//使用 diff 确定下一步的绘制时间
//把 startTime 重写为这一次的绘制时间
startTime = drawStart;
//重绘 UI
requestAnimationFrame(draw);
}
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame,
startTime = window.mozAnimationStartTime || Date.now();
requestAnimationFrame(draw);
})();
Page Visibility API
-
三部分组成
- document.hidden,表示页面是否隐藏的布尔值。页面隐藏包括页面在后台标签页中或者浏览器最小化。
-
document.visibilityState,表示下列 4 个可能状态的值。
- 页面在后台标签页中或浏览器最小化。
- 页面在前台标签页中。
- 实际的页面已经隐藏,但用户可以看到页面的预览(就像在 Windows 7 中,用户把鼠标移动到任务栏的图标上,就可以显示浏览器中当前页面的预览)。
- 页面在屏幕外执行预渲染处理。
- visibilitychange 事件,当文档从可见变为不可见或从不可见变为可见时,触发该事件
function handleVisibilityChange(){ var output = document.getElementById("output"), msg; if (document.hidden || document.msHidden || document.webkitHidden){ msg = "Page is now hidden. " + (new Date()) + "<br>"; } else { msg = "Page is now visible. " + (new Date()) + "<br>"; } output.innerHTML += msg; } //要为两个事件都指定事件处理程序 EventUtil.addHandler(document, "msvisibilitychange", handleVisibilityChange); EventUtil.addHandler(document, "webkitvisibilitychange", handleVisibilityChange);
Geolocation API
-
navigator.geolocation对象包含3个方法
-
getCurrentPosition(),接收3个参数:成功回调函数、可选的失败回调函数、可选的选项对象。
-
成功回调函数,有两个属性:coords和timestamp。其中coords包含相关信息
- latitude,以十进制度数表示的纬度。
- longitude,以十进制度数表示的经度。
- accuracy,经、纬度坐标的精度,以米为单位。
- altitude,以米为单位的海拔高度,如果没有相关数据则值为 null 。
- altitudeAccuracy,海拔高度的精度,以米为单位,数值越大越不精确。
- heading,指南针的方向,0°表示正北,值为 NaN 表示没有检测到数据。
- speed,速度,即每秒移动多少米,如果没有相关数据则值为 null
-
失败回调函数,在被调用的时候接收一个参数,这个参数是一个对象,包含两个属性:message和code。其中message属性中包含文本信息,解释为什么会出错,code中保存着一个值,表示错误的类型:用户拒绝共享1、位置无效2、超时3
navigator.geolocation.getCurrentPosition(function(position){ drawMapCenteredAt(position.coords.latitude, positions.coords.longitude); }, function(error){ console.log("Error code: " + error.code); console.log("Error message: " + error.message); })
-
选项对象,用于设定信息的类型。可以设置的选项有三个:enableHightAccurancy是一个布尔值,表示必须尽可能使用最准确的位置信息;timeout是以毫秒数表示的等待位置信息的最长时间;maximumAge表示上一次取得坐标信息的有效时间,毫秒表示
navigator.geolocation.getCurrentPosition(function(position){ drawMapCenteredAt(position.coords.latitude, positions.coords.longitude); }, function(error){ console.log("Error code: " + error.code); console.log("Error message: " + error.message); }, { enableHighAccuracy: true, timeout: 5000, maximumAge: 25000 })
-
- 另一个方法是watchPosition()这个方法接收的参数与上一个方法一样
-
File API
-
每个File对象都有下列只读属性
- name,本地文件系统中的文件名。
- size,文件的字节大小。
- type,字符串,文件的 MIME 类型。
- lastModifiedDate,字符串,文件上一次被修改的时间
FileReader类型
-
为了读取文件中的数据,FileReader提供的方法
- readAsText(file,encoding),以纯文本形式读取文件,将读取到的文本保存在 result 属性中。第二个参数用于指定编码类型,是可选的。
- readAsDataURL(file),读取文件并将文件以数据 URI 的形式保存在 result 属性中。
- readAsBinaryString(file),读取文件并将一个字符串保存在 result 属性中,字符串中的每个字符表示一字节。
- readAsArrayBuffer(file),读取文件并将一个包含文件内容的 ArrayBuffer 保存在result 属性中
var filesList = document.getElementById("files-list"); EventUtil.addHandler(filesList, "change", function(event){ var info = "", output = document.getElementById("output"), progress = document.getElementById("progress"), files = EventUtil.getTarget(event).files, type = "default", reader = new FileReader(); if (/image/.test(files[0].type)){ reader.readAsDataURL(files[0]); type = "image"; } else { reader.readAsText(files[0]); type = "text"; } reader.onerror = function(){ output.innerHTML = "Could not read file, error code is " + reader.error.code; }; reader.onprogress = function(event){ if (event.lengthComputable){ progress.innerHTML = event.loaded + "/" + event.total; } }; reader.onload = function(){ var html = ""; switch(type){ case "image": html = "<img src=\"" + reader.result + "\">"; break; case "text": html = reader.result; break; } output.innerHTML = html; }; });
读取部分内容
-
File对象还支持slice()方法,这个方法接收两个参数:起始的字节及要读取的字节数
function blobSlice(blob, startByte, length){ if (blob.slice){ return blob.slice(startByte, length); } else if (blob.webkitSlice){ return blob.webkitSlice(startByte, length); } else if (blob.mozSlice){ return blob.mozSlice(startByte, length); } else { return null; } }
-
Blob类型有一个size属性和一个type属性,支持slice()方法,以便进一步切割数据
var filesList = document.getElementById("files-list"); EventUtil.addHandler(filesList, "change", function(event){ var info = "", output = document.getElementById("output"), progress = document.getElementById("progress"), files = EventUtil.getTarget(event).files, reader = new FileReader(), blob = blobSlice(files[0], 0, 32); if (blob){ reader.readAsText(blob); reader.onerror = function(){ output.innerHTML = "Could not read file, error code is " + reader.error.code; }; reader.onload = function(){ output.innerHTML = reader.result; }; } else { alert("Your browser doesn' t support slice()."); } });
对象URL
-
使用对象URL的好处是可以不必把文件内容读取到JavaScript中而直接使用文件内容,为此只要在需要文件内容的地方提供对象URL即可,要创建对象URL,可以使用window.URL.createObjectURL()方法,并传入File或Blob对象
var filesList = document.getElementById("files-list"); EventUtil.addHandler(filesList, "change", function(event){ var info = "", output = document.getElementById("output"), progress = document.getElementById("progress"), files = EventUtil.getTarget(event).files, reader = new FileReader(), url = createObjectURL(files[0]); if (url){ if (/image/.test(files[0].type)){ output.innerHTML = "<img src=\"" + url + "\">"; } else { output.innerHTML = "Not an image."; } } else { output.innerHTML = "Your browser doesn't support object URLs."; } });
读取拖放的文件
var droptarget = document.getElementById( "droptarget");
function handleEvent(event){
var info = "",
output = document.getElementById("output"),
files, i, len;
EventUtil.preventDefault(event);
if (event.type == "drop"){
files = event.dataTransfer.files;
i = 0;
len = files.length;
while (i < len){
info += files[i].name + " (" + files[i].type + ", " + files[i].size +
" bytes)<br>";
i++;
}
output.innerHTML = info;
}
}
EventUtil.addHandler(droptarget, "dragenter", handleEvent);
EventUtil.addHandler(droptarget, "dragover", handleEvent);
EventUtil.addHandler(droptarget, "drop", handleEvent);
使用XHR上传文件
var droptarget = document.getElementById("droptarget");
function handleEvent(event){
var info = "",
output = document.getElementById("output"),
data, xhr,
files, i, len;
EventUtil.preventDefault(event);
if (event.type == "drop"){
data = new FormData();
files = event.dataTransfer.files;
i = 0;
len = files.length;
while (i < len){
data.append("file" + i, files[i]);
i++;
}
xhr = new XMLHttpRequest();
xhr.open("post", "FileAPIExample06Upload.php", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
alert(xhr.responseText);
}
};
xhr.send(data);
}
}
EventUtil.addHandler(droptarget, "dragenter", handleEvent);
EventUtil.addHandler(droptarget, "dragover", handleEvent);
EventUtil.addHandler(droptarget, "drop", handleEvent);
Web计时
- navigationStart,开始导航到当前页面的时间。
- unloadEventStart,前一个页面的 unload 事件开始的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0。
- unloadEventEnd,前一个页面的 unload 事件结束的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为 0。
- redirectStart,到当前页面的重定向开始的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0。
- redirectEnd,到当前页面的重定向结束的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为 0。
- fetchStart,开始通过 HTTP GET 取得页面的时间。
- domainLookupStart,开始查询当前页面 DNS 的时间。
- domainLookupEnd,查询当前页面 DNS 结束的时间。
- connectStart,浏览器尝试连接服务器的时间。
- connectEnd,浏览器成功连接到服务器的时间。
- secureConnectionStart,浏览器尝试以 SSL 方式连接服务器的时间。不使用 SSL 方式连接时,这个属性的值为 0。
- requestStart,浏览器开始请求页面的时间。
- responseStart,浏览器接收到页面第一字节的时间。
- responseEnd,浏览器接收到页面所有内容的时间。
- domLoading,document.readyState 变为 "loading" 的时间。
- domInteractive,document.readyState 变为 "interactive" 的时间。
- domContentLoadedEventStart,发生 DOMContentLoaded 事件的时间。
- domContentLoadedEventEnd,DOMContentLoaded 事件已经发生且执行完所有事件处理程序的时间。
- domComplete,document.readyState 变为 "complete" 的时间。
- loadEventStart,发生 load 事件的时间。
- loadEventEnd,load 事件已经发生且执行完所有事件处理程序的时间。
Web Workers
使用Worker
-
只有Worker接收到消息才会实际执行文件汇总的代码。要给Worker传递消息,可以使用postMessage()方法,消息内容可以是任何能够被序列化的值
worker.postMessage(“start! ");
Worker全局作用域
- Worker执行的JavaScript代码完全在另一个作用域中,与当前网页中的代码不共享作用域
-
Web Worker本身也是一个最小化的运行环境
- 最小化的 navigator 对象,包括 onLine 、 appName 、 appVersion 、 userAgent 和 platform属性;
- 只读的 location 对象;
- setTimeout() 、 setInterval() 、 clearTimeout() 和 clearInterval() 方法;
- XMLHttpRequest 构造函数。
包含其他脚本
-
Worker的全局作用域提供这个功能,可以调用importScripts()方法,这个方法接收一个或多个指向JavaScript文件的URL,每个加载过程都是异步进行的。因此所有脚本加载之后,importScripts()才会执行
//Web Worker 内部的代码 importScripts("file1.js", "file2.js");
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。