新兴的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");

神膘护体小月半
406 声望6 粉丝