BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

预览IE10支持的HTML5特性

| 作者 崔康 关注 1 他的粉丝 发布于 2011年8月18日. 估计阅读时间: 34 分钟 | CNUTCon 了解国内外一线大厂50+智能运维最新实践案例。

从IE8开始,微软就逐步在浏览器中增加对HTML5的部分支持,如今IE10已经推出了几个预览版,Web开发人员关心的是在IE10中,哪些HTML5特性获得了支持,由此会影响到技术选型和职业发展等重要问题。在本文中,我们根据微软发布的相关特性梳理一下IE10对HTML5的支持情况。

目前,IE10预览版支持的HTML5特性可以概括为以下几点:

下面我们来详细了解一下各个HTML5特性的支持情况。

异步脚本执行

随着Web 2.0技术的发展,浏览器端脚本承载了越来越多的计算任务,这对于传统上单线程运行的浏览器来说,遭遇了性能的瓶颈。用户在碰到类似的网页时,经常会看到类似“脚本运行缓慢,是否继续运行”的提示框。为此,HTML5考虑到了Web开发人员的需求,提供了一些解决方案。其中我认为最重要的两个分别是async属性和Web Workers(稍后提到)。

script元素的async属性允许相关的脚本与页面的其他部分异步加载和执行。也就是说,脚本可以在后台加载和运行,而不影响页面的解析工作。对于包含密集处理脚本的页面来说,async属性能够显著提高页面加载的性能。

async属性是W3C HTML5标准的一部分,设计的应用场景是:不依赖于某个脚本,但是该脚本仍然需要尽快执行。在微软的文章中举了这样一个需要async属性的例子:

Lilah的个人博客使用了大量基于脚本的小组件。这些组件用于增强访问者的体验,但是她的页面在不加载这些组件的情况下也能正常运行(支持禁用脚本的浏览器用户)。目前,她在HTML文件的顶部加载所有小组件,但是读者抱怨说页面加载时间太长,因为脚本执行的缘故。她尝试把脚本移到页面的底部来提高速度,但是由于小组件内容太多,这种修改过程太繁琐。她真正想做的是让这些组件尽可能快的加载,但是不要阻碍页面上的其他内容。经过快速搜索后,她发现HTML5的async属性符合自己的需求。通过把所有基于脚本的小组件放在一个外部文件中,她可以在基于脚本的功能增强和性能之间取得更好的平衡:
<head>
    <title>Lilah's Blog</title>
    <script async src="widgets.js"></script>
</head>

IE10的预览版支持script元素的async和defer属性。defer属性在早期的IE中就被引入,那么这两个属性在用法上有什么区别吗?微软给出了四种可能的组合(无论是async还是defer属性,都必须在src属性存在的情况下才起作用),请读者仔细地体会async和defer之间的细微差别:

<script src="widgets.js"></script> 脚本立即执行,页面等待脚本完成之后再继续解析。这种方式会显著降低页面加载性能。
<script async src="widgets.js"></script>

脚本下载与页面解析异步进行。脚本在下载完成后执行。

<script defer src="widgets.js"></script> 页面完成解析后脚本再执行。
<script async defer src="widgets.js"></script> async优先,忽略defer属性。这种方式可以帮助开发人员在支持async属性的浏览器中使用async,在不支持async的浏览器中退化为支持defer。

HTML5拖放(Drag and Drop)

拖放功能在桌面客户端软件中应用十分普遍。HTML5标准对拖放做了规定,IE和之前的版本支持dataTransfer对象和拖放图片、超链接、文本的事件。IE10预览版对所有元素增加了draggable属性,并且支持把一个或多个文件从桌面拖放到网页上。draggable属性支持你将任意HTML元素设为页面可拖放的。它提供了如下状态:

draggable = 'true' 该元素可拖放。
draggable = 'false' 该元素不可拖放。
draggable = 'auto' 该元素遵循默认的浏览器行为(文本、超链接和图片可拖放,其他元素不能)。

例如,下列代码支持用户拖放元素。

<button id="mybutton" draggable="true">Drag me</button>
<img src="photo.png" draggable="true" />
<div id="mydiv" draggable="true">Moveable text</div>

当用户拖动一个可拖放的元素时,IE10预览版随着拖动的光标移动显示一个元素的虚影。draggable属性是不可继承的,因此元素的子元素不会自动变成可拖放的。

除此之外,dataTransfer对象的files属性支持你把文件从桌面的文件夹中拖放到网页上。这种方式能够减少一些应用,如邮件客户端,把附件拖放进邮件内容中,或者在图库页面中添加照片。这种从桌面端到Web端的无缝交互无疑是Web开发的一大亮点。

下面的事件监听器和dropHandler函数展示了如何创建一个网页区域让用户拖放文件上去。其中的“dropspot”可以是div、image,或者其他元素。dragover和drop事件调用了doNothing() 函数避免默认的事件处理和冒泡,否则可能会导致不可预知的结果。

// this function runs when the page loads to set up the drop area
function init()
{
 // Set the drop-event handlers
 var dropArea = document.getElementById("dropspot");
 dropArea.addEventListener("drop", dropHandler, false);
 dropArea.addEventListener("dragover", doNothing, false);
}
function dropHandler(event)
{
 // use our doNothing() function to prevent default processing
 doNothing(event);
 // get the file(s) that are dropped
 var filelist =  event.dataTransfer.files;
 if (!filelist) return;  // if null, exit now
 var filecount = filelist.length;  // get number of dropped files
 if (filecount > 0)
 {
   // Do something with the files.       
 }
}
// Prevents the event from continuing so our handlers can process the event.
function doNothing(event)
{
 event.stopPropagation();
 event.preventDefault();
}

File API

IE10预览版引入了对File API的支持。File API来自于w3c的草案,表示web应用中的文件对象,并且可以编程选取它们并访问数据。File API目前正在被W3C Web应用工作组标准化。通过该API,web开发人员可以在客户端机器上以安全地方式访问本地文件,而无需扩展或者插件。

File API支持浏览器在用户授权的情况下读取和处理文件。此外,File API在无插件的情况下支持更流畅的文件上传体验,包括上传进度的状态反馈等。

在下面的W3C File API示例中,不同的代码片段分别处理进展、错误和成功条件:

function startRead() {
// Obtain input element through DOM.

var file = document.getElementById('file').files[0];
if(file) {
  getAsText(file);
}
}

function getAsText(readFile) {

var reader = new FileReader();

// Read file into memory as UTF-16    
reader.readAsText(readFile, "UTF-16");

// Handle progress, success, and errors
reader.onprogress = updateProgress;
reader.onload = loaded;
reader.onerror = errorHandler;
}

function updateProgress(evt) {
if (evt.lengthComputable) {
  // evt.loaded and evt.total are ProgressEvent properties.
  var loaded = (evt.loaded / evt.total);

  if (loaded < 1) {
    // Increase the progress bar length.
    // style.width = (loaded * 200) + "px";
  }
}
}

function loaded(evt) {
// Obtain the read file data.  
var fileString = evt.target.result;

// Handle UTF-16 file dump
if(utils.regexp.isChinese(fileString)) {
  //Chinese Characters + name validation.
}
else {
  // Run other charset test.
}
// xhr.send(fileString)   
}

function errorHandler(evt) {
if(evt.target.error.code == evt.target.error.NOT_READABLE_ERR) {
  // The file could not be read.
}
}

其他文件相关的改进包括带有文件类型过滤的多文件上传。在下例中,多个GIF或者JPEG文件可以被用户选择:

<input type="file" name="pic" multiple accept="image/gif, image/jpeg" />

HTML5 表单和输入验证 

IE10预览版增加了对新HTML5 输入类型和属性的支持。这些支持帮助开发人员可以通过很少的脚本来快速、简便的提供用户提示和输入验证。在HTML5的输入类型和属性出现之前,检查手机号码没有包含字母,或者验证邮件地址正确输入,都需要开发人员编写额外的代码。HTML5客户端表单和输入验证帮会组开放人员关注其他任务而不是构建验证函数。

新URL和email输入类型

新HTML5输入类型支持提供了内建的URL和email输入类型。URL输入元素接受完全合格的地址,例如http://www.contoso.com。同样,email输入类型接受标准的email格式,如joe@contoso.com。在下面的例子中,如果用户不正确地输入了URL或者email地址,IE就会显示错误信息。

<input type="url" name="url"/>
<input type="email" name="email"/>

新输入属性

IE10预览器提供了对新HTML input属性的支持,如required、pattern和placeholder能够帮助开发人员确保用户在网页中输入所需的、正确的数据。

  • required属性

required属性表示该元素必须填写值才能提交。该属性能够用于text、text area、URL、email、select、checkbox或者radio button等元素。这是一个Boolean属性。当用户的鼠标悬停在required区域时,他们会看到相应的必填提示,如果设定了title属性,那么会显示该值。

<form id="yourname">
<label>Enter your first name:
  <input name="firstname" type="text" required><input type="submit" value="Go"/>
</label>
</form>

如果用户尝试在不填写该区域的情况下提交表单,他们会收到错误信息,而且键盘焦点会置于为填写的区域中。

  • pattern属性

pattern属性允许你定义一个正则表达式要求用户的输入必须匹配。pattern属性支持text、search、url、email和password等输入元素。

<form>
<label>
    <input type="tel" name="tel" pattern="\(\d\d\d\) \d\d\d\-\d\d\d\d"
     title="enter a telephone number in   the format (xxx) xxx-xxxx"/>
    <input type="submit"/>
</label>
</form>

  • min、max和step属性

min、max和step属性适用于input type=number。min和max定义了数据的最小值和最大值。step属性定义了开发人员允许的跳跃值。例如,如果min=0,step=1,那么0、1、2、3......是允许的。如果min=1.1,step=1,那么1.1、2.1、3.1......是允许的。下面的例子展示了输入区域要求0到10之间的偶数。任何此范围之外的数据或者奇数都不能提交,而且会显示错误消息。

<form>
<label>Enter an even number between 0 and 10:
  <input type="number" min="0" max="10" step="2"/>
  <input type="submit"/>
</label>
</form>

  • placeholder属性

占位符属性,在web开发中很常见,通过设置该属性,用户能够在输入区域看到“虚拟”的示例,直观明了,也减轻了开发人员的负担。IE10预览版支持对该属性做样式化定制,包括属性值的文本颜色、背景颜色、字体等等。

  • autofocus属性

自动聚焦属性帮助开发人员设置页面加载后的光标位置,无须用户主动点击某个输入控件。该属性只能用于页面的单个元素,如果同一页面的多个元素都设置了autofocus属性,那么只有第一个元素起作用。

  • 大小写开关提示

该功能之前已经广泛应用于桌面客户端应用,比如用户输入密码时,如果打开了大小写开关(Caps lock ),那么应用会弹出对话框提示。IE10预览版加入了该项提示功能,无须开发人员编写任何代码,该功能在大小写开关打开的时候即自动触发提示。

HTML5解析

IE10预览版完全支持HTML5的解析算法,不断完善与其他浏览器的一致行为。这些努力包括支持SVG-in-HTML、HTML语义元素、保留未知元素的结构和改善对空格的处理。

IE团队在HTML解析器上的目标是让所有的HTML在跨浏览器中解析行为一致。这可能是因为HTML5是第一个完整定义HTML解析规则的标准,细致到最边缘的情况和错误条件。即使HTML标记是无效的,HTML5仍然定义了如何解析它,IE 10遵循了这些原则。这种跨浏览器的一致行为使得开发人员在创建应用解析DOM元素时,不必把过多精力花费在单独处理IE的“异常”行为。下面的解析例子展示了这些改进中修补的部分情况。

HTML DOM ( HTML5 + IE10 ) DOM ( IE9 )
<b>1<i>2</b> |- <b>
   |- "1"
   |- <i>
     |- "2"

 

|- <b>
   |- "1"
   |- <i>
   |- "2"
  |- <i>

<p>Test 1
<object>
<p>Test 2
</object>
|- <p>
  |- "Test 1\n"
|- <object>
  |- "\n "
  |- <p>
    |- "Test 2\n"
|- <p>
  |- "Test 1\n"
|- <object>
  |- "\n "
|- <p>
  |- "Test 2\n"

除此之外,因为早期IE的一些特性无法与HTML5解析兼容,它们已经从IE10预览版中删除。用户在使用IE10的legacy compatibility模式访问依赖这些陈旧特性的网站时不会出现问题。通过这种方式,现在正常运行的网站即使没有时间和资源来更新自己,那么网站依然可以在IE10中工作。

条件注释

条件注释在当前的跨浏览器Web开发中使用广泛,成为大家判断某项特性是否支持的重要判断方法,但是它们只适用于IE的老版本。

<!--[if IE]>
This content is ignored in IE10 Platform Preview and other browsers.
In older versions of Internet Explorer, this renders as part of the page.
<![endif]-->

如果需要区分浏览器,请使用feature detection ,例如下面的代码示例:

function registerEvent( sTargetID, sEventName, fnHandler )
{
  var oTarget = document.getElementById( sTargetID );
  if ( oTarget != null )
  {
     if ( oTarget.addEventListener ) {   
        oTarget.addEventListener( sEventName, fnToBeRun, false );
     } else {
       var sOnEvent = "on" + sEventName;
       if ( oTarget.attachEvent )
       {
          oTarget.attachEvent( sOnEvent, fnHandler );
       }
     }
  }
}

这种新式判断方式逐渐成为兼容性开发的主流,其优点在于不再依赖于条件注释,而是通过判断所需特性本身是否存在来做进一步的处理。

HTML5 沙箱

IE10预览版支持沙箱属性,确保对包含不可信内容的iframe元素的安全限制。这些限制通过防止不可信内容执行导致潜在恶意行为的操作提高安全性。

为了启用这些限制,在元素中设置sanbox属性,如下所示:

<iframe sandbox src="frame1.html"></iframe>

当sanbox属性在iframe元素中指定时,iframe元素中的内容称为被置于沙箱中。沙箱中的iframe元素,如下行为受到限制:

  • 沙箱内容不能打开弹出窗口和新浏览器窗口。某些方法如 createPopup()、showModalDialog()、showModelessDialog()等会失败(无反馈)。
  • 超链接不能在新窗口打开。
  • 沙箱内容被认为来自于单一域,防止对受到同源策略保护的API的访问,如cookie、local storage和其他文档的DOM。
  • 顶级窗口不能被沙箱内容导航。
  • 沙箱内容不能提交表单数据。
  • 插件(object、appletembed或者frame)不能实例化。
  • 自动的元素行为被禁用,包括meta元素的刷新、input控件的自动聚焦和audiovideo元素的自动播放

Web Workers

IE10预览版开始支持Web Workers。Web Workers API提供了一种在后台运行脚本的方式。

传统上,浏览器都是单线程的,强制应用中的所有脚本都在一个UI线程中统一运行。虽然你可以通过使用DOM时间和setTimeout API来创建若干任务同时执行的假象,但是计算密集型任务会对用户体验造成严重的伤害。

Web Worker API为Web应用开发者提供了一种启动后台脚本并与主页面并发运行的方式。你可以同时创建多个线程用于长时间运行的任务。新的Worker对象需要一个.js文件,通过对服务器的异步请求包含进来。

var myWorker = new Worker('worker.js');

进出worker线程的所有通信都通过消息管理。主worker和其他worker都可以利用postMessage发送消息,并利用onmessage事件监听响应。消息的内容作为事件的data 属性发送。

下面的例子创建了一个worker线程并监听消息。

var hello = new Worker('hello.js');
hello.onmessage = function(e) {
alert(e.data);
};

worker线程发送消息:

postMessage('Hello world!');

Web Worker之间的双向通信

要建立双向通信,主页面和worker线程都监听onmessage事件。在下面的例子中,worker线程在一定的延迟之后返回消息。首先,脚本创建worker线程。

var echo = new Worker('echo.js');
echo.onmessage = function(e) {
alert(e.data);
}

消息内容和超时值在表单中指定。当用户点击提交按钮,脚本把两个值传递给worker线程。为了防止页面在新的HTTP请求中提交表单值,事件处理器也调用了preventDefault函数。请注意你无法发送对DOM对象的引用给worker线程。Web Workers对它们能够访问的数据做了限制。只有Javascript原始数据类型,如Object或者String值允许。

<script>
window.onload = function() {
var echoForm = document.getElementById('echoForm');
echoForm.addEventListener('submit', function(e) {
  echo.postMessage({
    message : e.target.message.value,
timeout : e.target.timeout.value
});
e.preventDefault();
}, false);
}
</script><form id="echoForm">
<p>Echo the following message after a delay.</p>
<input type="text" name="message" value="Input message here."/><br/>
<input type="number" name="timeout" max="10" value="2"/> seconds.<br/>
<button type="submit">Send Message</button>
</form>

最后,worker线程监听消息并在指定的超时间隔后返回响应。

onmessage = function(e)
{
setTimeout(function()
{
  postMessage(e.data.message);
},
e.data.timeout * 1000);
}

在IE 10预览版中,Web Worker API支持如下方法和事件:

方法 描述
void close(); 终止worker线程。
void importScripts(in DOMString... urls); 逗号分隔的其他Javascript文件列表。
void postMessage(in any data); void postMessage(in any data);

通道消息

IE10预览版引入了通道消息(Channel Messaging),支持在不同的浏览器情境中直接通过端口通信。该特性来自于HTML5 Web Messaging标准。在创建端口之后,两边结合postMessage函数和onmessage事件来通信。

打开通道,创建MessageChannel对象:

var channel = new MessageChannel();

通道对象包含port1和port2两个端点。通常情况下,一个端点口作为本地端口,另一个发远程窗口或者worker线程。端口也可用于worker线程之间的通信。

下面的例子是发送端口用于跨文档通信。请注意端口数组必须是最后一个参数。

otherWindow.postMessage('hello', 'http://example.com', [channel.port2]);

同样,你可以通过postMessage发送端口给worker线程,如下:

worker.postMessage({code:"port"}, [channel.port2]);

端口数组在事件的port属性中发送。端口可以使用一次并关闭,也可以保存到本地重复使用。下面的例子显示了worker线程如何接收和使用端口。

// Worker Thread
onmessage = function (event) {
  if (event.data.code == "port") {
      event.ports[0].postMessage("Port received.");
  }
}

端口收到后,进一步的通信利用postMessage和onmessage事件实现。下面的代码定义了事件处理器并发送利用通道端口发送消息。

channel.port1.onmessage = function (event) {
// Message is in event.data
alert("Message is: " + event.data);
}
channel.port1.postMessage('hello');

本文只是汇总了IE10预览版对HTML5特性的支持,未来IE10正式版的具体情况我们还要拭目以待。长久以来,IE因其“我行我素”的风格受到Web开发人员的诟病,如今随着HTML5的标准化进程推进,IE团队也在努力追赶时代的脚步,特别是在Chrome和Firefox通过快速发布的方式抢占浏览器市场份额的严峻形势下,IE10的特性成为社区关注的焦点。感兴趣的读者可以从这里下载IE10平台预览版,并通过微软的Test Drvie项目中查看HTML5在IE中的演示程序。

注:本文涉及的所有代码示例均引自微软官方网站。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

小误 by lee ambar

dropArea.addEventListener("dragover", doNothing(event), false);
有误,找到原文(msdn.microsoft.com/en-us/ie/hh272905#_HTML5Drag...
dropArea.addEventListener("dragover", doNothing, false);

Re: 小误 by 崔 康

感谢您的指正,我查了原文,的确是代码错误,应该为pArea.addEventListener("dragover", doNothing, false); 我已经在文章中更改,希望您继续关注InfoQ的发展。

IE10 + HTML5 很好、很强大! by 高 翌翔

有时间去下一个玩玩先。

希望浏览器兼容性问题越少越少!

格式问题比较大 by Jeffrey Zhao

需要注意……

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

4 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT