HTML5 JavaScript API

部分参考自 w3school.com ,部分学术参考自《HTML5权威指南》《精通javascript》

W3C官方指定的HTML5规范已经修订了很多次,HTML5这个概念是与javascript API相捆绑的语义标记。在过去这些年中,HTML5这个词所指代的范围正以惊人的的速度膨胀,某种程度上已经成为一个笼统的称谓,用于指代网络开发中出现的一大堆新技术。值得一提的是,在该语言的第5版中,我们能够以用户为中心的设计了。HTML5有两个大的方面:新标记和新的javascript API

新标记

它能使我们创建更好地语义,构建更衣访问的内容(http://www.w3school.com.cn/html5/index.asp),它新增了诸如<header><footer><nav><section><article><aside><vidio><radio>等新的标记元素。同时还提供了ARIA规范的一些应用于元素的role属性,它们叫做地标角色属性。这类角色都表示起导航作用的地标:

application、banner、complementar、contentinfo、form、main、navigation、search它们能提升网站的易访问性,这样就可使用辅助技术(屏幕阅读器)来访问网站的无障碍导航形式,不要漠视小众用户!

 1 <header role="banner">
 2         <hgroup>
 3             <h1>biaoti1</h1>
 4             <h2>biaoti2</h2>
 5         </hgroup>
 6         </header>
 7 
 8         <nav role="navigation">
 9         <ul>
10             <li><a href="/">home</a></li>
11             <li><a href="/">home</a></li>
12             <li><a href="/">home</a></li>
13             <li><a href="/">home</a></li>
14         </ul>
15         </nav>
16 
17         <section>
18             <article role="main"></article>
19             <aside role="complementary"></aside>
20         </section>
21 
22         <footer role="contentinfo"></footer>

Javascript API

HTML5规范中不只有HTML,还有很多的javascript的内容。规范中为javascript语言预留了许多挂钩,而且还引入了一批新功能:

Navigator 对象

在javascript中,navigation是一个顶级对象,它用于反馈一些与用户正在使用的浏览器有关信息:浏览器名称、浏览器版本、平台、cookies功能是否启用、javascript功能是否启用、user agent字符串等等

1 //javascriptAPI打印浏览器信息
2  
3 console.log(navigator);

使用该方法可以在运行改代码的浏览器中的控制台中看到浏览器的有关信息,navigation对象是挖掘浏览器新功能的一条秘籍,很多与之相关的信息都会出现在此对象中。

地理位置API

一直以来我们可以根据用户的Ip地址发送给服务器处理,并输出其大概的位置。但是,在今天,我们需要Geolocation API给我们一个精细的地理位置了。Geolocation API中最有用的方法之一是getCurrentPosition()方法,此方法会返回定位用户所需的全部信息 : 经纬度(米)、海拔高度(米)、方向、速度。此API最常见的用法就是获取用户的经纬度快照,下面的代码列举将信息输出到浏览器中:

 1 //地理位置
 2 (function(){
 3     "usestrict";
 4 
 5     functiongetPositionData(position){
 6         varbody=document.getElementsByTagName("body")[0];
 7 
 8         body.innerHTML+="<p>维度估计:"+position.coords.latitude+"</p>";
 9         body.innerHTML+="<p>经度估计:"+position.coords.longitude+"</p>";
10         body.innerHTML+="<p>经纬度(米):"+position.coords.accuracy+"</p>";
11         body.innerHTML+="<p>高度估计:"+position.coords.altitude+"</p>";
12         body.innerHTML+="<p>移动角度方向:"+position.coords.heading+"</p>";
13         body.innerHTML+="<p>移动速度(米):"+position.coords.speed+"</p>";
14     }
15 
16     if(navigator.geolocation){
17         navigator.geolocation.getCurrentPosition(getPositionData)
18     }else{
19         alert("对不起,您的浏览器不支持此API")
20     }
21 })();

地理位置的安全性

很多情况下,很多用户并不想某站点获取其地理信息。鉴于此,支持该API的浏览器都实现了一套权限系统,他们都是以消息提示的形式询问用户是否把当前位置发送给服务器。另外要以谨慎实用的态度来使用这些数据,否则会导致用户的厌烦。

音频与视频

<audio><video>不仅仅是HTML5规范中的新元素,它们也预留了一些javascript API挂钩,让开发者创建自定义的音频及视频控件,这意味着用户可以从任何设备上随意访问媒体内容,而不像原来那样担心Flash等技术中的各种限制和安全隐患了。

 1  <!--自动缓存-->
 2         <audio preload="auto"autobuffer>
 3         <source src="audio/zhuy.mp3">
 4         <source src="audio/beiy.ogg">
 5         </audio>
 6 
 7         <div >
 8         <button type="button">play/pause</button>
 9         <button type="button">增大音量</button>
10         <button type="button">减小音量</button>
11         </div>
12 
13         <scriptsrc="js/html5.js"></script>
 1 (function(){
 2     var player=document.getElementById("player");
 3 
 4     function playPause(){
 5 //如果没有播放则播放,否则停止播放
 6         if(player.paused){
 7             player.play();
 8         }else{
 9             player.pause();
10         }
11     }
12 
13 //减音量
14     functionvolumeDown(){
15         if(player.volume>.1){
16             player.volume-=.1;
17         }else{}
18     }
19 //增音量
20     functionvolumeUp(){
21         if(player.volume<=.9){
22             player.volume+=.1;
23         }else{}
24     }
25 
26 //事件监听器绑定click事件
27     document.getElementById("play").addEventListener("click",playPause,false);
28 
29     document.getElementById("col-up").addEventListener("click",volumeUp,false);
30 
31     document.getElementById("col-down").addEventListener("click",volumeDown,false);
32 })();

History API

History API可以操作浏览器的地址栏和历史纪录。在网络应用程序中用Ajax来实现页面导航功能时存在一个问题,那就是除非你强制干预,否则URL就会一直保持不变,这回事用户通过浏览器分享URL或将地址加入收藏夹时遇到一些麻烦。而History API就是解决这个问题的,它可以将与当前页面内容相符的真实API推送到地址栏中,而且能够维护浏览器的历史纪录,使其与之同步。pushState()方法,此方法属于history对象,他接受三个参数:数据、页面标题、新的URL :首先要对之前的Ajax函数做轻微的修改

 1 request.onreadystatechange=function(){
 2     if(request.readyState===4||request.status===200){
 3 
 4 //使用request.responseText返回的数据
 5 
 6         varcontacts=request.responseText;
 7 
 8         if(callback==="function"){
 9             callback(contacts);
10         }
11     }
12 };
1  <!--historyAPI对应的HTML-->
2         <p>
3             <a href="cat.html">cats</a>
4             <a href="dog.html">dogs</a>
5             <a href="bird.html">birds</a>
6         </p>
7 
8         <div ></div>
 1 //将HistoryAPI与Ajax调用结合起来,改变页面的局部模块内容
 2 (function(){
 3     "usestrict";
 4 
 5     var links=document.getElementsByTagName("a"),
 6         linkCount=links.length,
 7         output=document.getElementById("output"),
 8         i;
 9 
10     if(linkCount>0){
11 //将事件监听器与循环语句配合,可以提高效率
12         for(i=0;i<linkCount;i++){
13             var obj=links[i];
14 
15             obj.addEventListener("click",function(e){
16                 e.preventDefault();
17 //获取a元素的URL和标题供pushState()使用
18                 var href=this.getAttribute("href");
19                 var title=this.innerHTML;
20 
21                 history.pushState(href,title,href);
22                 ajaxCall("href",output,function(data){
23 //将该URL返回的数据写入到所指向的output元素中
24                     output.innerHTML=data;
25                 })
26             });
27         }
28     }
29 })();

这时,我们会发现前进后退功能不正常,这对导致不好的用户体验。我们需要利用 popstate事件来修复它:

 1 //使用popstate事件解决后退前进按钮的功能问题
 2 window.addEventListener("popstate",function(e){
 3 
 4 //获取原来存放在history对象中的数据
 5     varstoreHistoryData=e.state;
 6 //
 7     ajaxCall(storeHistoryData,output,function(data){
 8         output.innerHTML=data;
 9     })
10 });

再向地址栏推送URL时,pushState()方法所设置的新URL必须是同一域名内的,这样可以防止跨站脚本攻击。

工作子线程

HTML5规范试图用工作线程来解决目前网络开发中最为棘手的问题之一:服务器通信。它是针对Ajax的,是作为最先由服务器通信模型的补充。我们都了解javascript的阻塞性了,也就是为什么要在DOM底部引入javascript以及为何每次只能执行一个请求的原因所在,还有浏览器只是用一个线程来执行javascript。如果最初那个Ajax调用尚未成功返回,则其余的Ajax请求都会被阻塞。各种请求就会开始发生冲突,这样一来也就会阻塞服务器的响应,并导致非常差的用户体验。

工作线程有助于缓解这个问题,它是为了与主线程来回传递数据而用的辅助线程,其代码存放在另一份javascript文件中。出于安全性考虑,工作线程不能访问DOM。我们可以由主线程传递信息,在辅助线程内将其捕获运算在将数据返回。

postMessage()方法可以在主文件和辅助文件之间互相传递数据

Message事件 是在postMessage方法调用之后触发的

1 <!--工作线程对应的HTML-->
2         <button type="button">开始</button>
3         <button type="button">停止</button>
4 
5         <div ></div>
6         <div ></div>
7 
8         <script src="/js/boke.js"></script>
 1 //主线程
 2 (function(){
 3     "usestrict";
 4 //创建一个新的工作线程
 5     var Worker=newWorker("js/worker.js");
 6 
 7     var btnStart=document.getElementById("start");
 8     var btnStop=document.getElementById("stop");
 9     var timerOutput=document.getElementById("timer");
10     var workerOutput=document.getElementById("output");
11     var num=0;
12 
13 //使用setInterval()方法模拟主线程在无休止的运行(占用线程)
14     setInterval(function(){
15         num=num+1;
16         timerOutput.innerHTML=num;
17     },500);
18 //通过ajax调用获得Salad.jsoningredient=data.ingredient;将ingredient对象发送给Worker线程
19     btnStart.addEventListener("click",function(){
20         Worker.postMessage(ingredient);
21     });
22 //当主线程接收到服主线程的数据,将数据依次写入到DOM
23     Worker.addEventListener("message",function(e){
24         workerOutput.innerHTML+=e.data;
25     });
26 
27 //停止辅助线程
28     btnStop.addEventListener("click",function(){
29         Worker.terminate();
30         btnStart.setAttribute("disabled","disabled");
31         alert("辅助工作已结束!")
32     })
33 })();
34 
35 //辅助线程
36 (function(){
37 //接受主线程的数据
38     addEventListener("message",function(e){
39         varfruit=e.data.fruit,
40             fruitCount=fruit.length,
41             counter=0;
42 //工作线程每半秒钟会传送一条数据
43         setInterval(function(){
44             if(counter<fruitCount){
45                 postMessage("<p>"+data[counter++].name+"</p>");
46             }
47         },500);
48     },false);
49 })();

通过Device API,我们可以进一步缩小哦固件原生应用程序与开发纯网页应用程序之间的差别。这是网络开发忠义乡前沿技术,支持此类规范的浏览器很少。不过,它代表了目前javascript中最有前景的发展趋势之一,此规范的出现,让我们找到了一种较先进的访问方式,用以获得用户访问网站时所持设备的信息。

我们都力求只用一套HTML,CSS,Javascript创建出的一套一站式网络应用程序,然而在设备功能查询时所遇到各种的限制。很大程度上归咎于javascript因安全问题上留下的负面影响。此API一部分加入到了javascript语言里面,一部分被加入到了HTML中,Device API开辟了一个崭新的领域,让开发者有机会获取详细的设备信息。它有3个主要组成部分:电池状态API、震动API、网络信息API,它们都是一项官方草案,将来他们都会发展成浏览器中进行客户端通信时所遵循的标准(Firefox新版本已经对该API提供支持)。

电池状态API

这套API提供了一种在浏览器中获取电池电量与设备状态的方式,它使开发者可以设计出搞笑的网络应用程序,该程序可以根据设备所剩的电量来提供最合适的用户体验:

 1 (function(){
 2     "usestrict";
 3 //通过该方法获取电池状态
 4     var battery=navigator.battery,
 5         body=document.getElementsByTagName("body")[0];
 6 
 7     function updateBatteryStatus(){
 8         body.innerHTML+="<p>电池电量"+battery.level*100+"%</p>";
 9         body.innerHTML+="<p>电池充电状态"+battery.charging+"</p>";
10         body.innerHTML+="<p>电池充满电所需时间"+battery.chargingTime+"</p>";
11         body.innerHTML+="<p>电池耗尽时间"+battery.dischargingTime+"</p>";
12     }
13 
14     if(battery){
15 //当电量增加时触发
16         battery.addEventListener("chargingchange",updateBatteryStatus);
17 //当充满电时间改变时触发
18         battery.addEventListener("chargingtimechange",updateBatteryStatus);
19 //当耗尽电量时间改变时触发
20         battery.addEventListener("dischargingchange",updateBatteryStatus);
21 //当电池电量改变时触发
22         battery.addEventListener("levelchange",updateBatteryStatus);
23     }
24 })();

震动API

它也是一个尚未获得广泛支持的最新功能,你可以通过navigator.vibrate()方法用编程的方式来操作折别的震动机能。该方法接受一个震动时长参数:

 1 //震动API
 2 (function(){
 3     document.getElementById("btn").addEventListener("click",function(){
 4 
 5         if(navigator.vibrate){
 6 //表示分别为1秒和2秒的震动,间隔半秒钟
 7             navigator.vibrate([1000,500,2000]);
 8         }else{
 9             alert("抱歉,您的浏览器不支持此API")
10         }
11     },false);
12 })();

它们能创造出独特的用户体验,但是要注意,震动功能要谨慎使用,它不适合用于通知。

网络信息API

它属于用户无法察觉到的API,它的潜力可能会成为最强大的API。网络信息API可以访问设备底层的连接信息,这意味着在加载资源前,可以现在设备上执行轻量级的链接及带宽测试,与电池信息API相似,我们可以根据当前可用的网络资源状况来调整网站的用户体验。创建一站式体验时遭遇最大的问题之一就是资源管理。想要创建一套合适各种浏览器与屏幕分辨率的网站设计方案是很难的,而且考虑到通过移动蜂窝网络上的带宽限制,这个问题就更难了。

在拥有网络信息API之后,就可以在带宽不足的情况下调整载入一些高的分辨率,以确保平滑的用户体验。通过navigation.connection.type()方法判断当前所处的网络是不是”未知、以太网、无线网络“;它们三者对应的type属性码分别是“0、1、2”

在下面的代码中,我们要检测网络的带宽情况,即时调整图像的src:

1  <!--网络信息API对应得HTML-->
2         <img src="images/large.jpg"data-small="images/small.jpg">
 1 //网络信息API
 2 (function(){
 3     "usestrict";
 4 
 5     var connection,
 6         connectionSpeed,
 7         images=document.querySelectorAll("img[data-small]"),
 8         imageCount=images.length,
 9         i;
10 //获取当前设备所处的网络类型
11     connection=navigator.connection||{"type":"0"};
12 //如果网络信息类型是移动蜂窝网络,则将数据量较小的数据源设置为图像的src
13     if(imageCount>0&&connection.type!=="0"&&connection.type!=="1"&&connection.type!=="2"){
14         for(i=0;i<imageCount;i++){
15             varobj=images[i],
16                 largeImg=obj.getAttribute("data-small");
17 
18             obj.setAttribute("src",largeImg);
19         }
20     }
21 })();

这些Device API距离获得各浏览器的支持的那一天终将会到来。现在我们只需要一台支持这些API的设备及浏览器。我们可以通过一些合理的条件语句与功能检测技术来提前尝试这些功能,毋庸置疑,FireFox对新标准的支持是最快的最活跃的。

对于部分我们了解的试验性对象,为了让代码能够正常运行,可能需要加上浏览器厂商前缀。比如navigator对象,在firefox中,battery对象可以通过navigator.mozBattery来引用;而chrome/safari,则使用navigation.webkitBattery来引用。如果你使用普通方法不适用可以试试这种方法,这和CSS是一个道理。所以说得小心了,因为你正在网络开发行业的最前端冲浪。

本随笔是年前的最后一篇,由于这段时间有很多的事务要处理,所以扎堆整理的内容较多,说实话这耗费了我很多的空闲时间,有需要的朋友也需要精读(大虾除外)。由于年后我要参加升学考试,所以我想暂时搁置一下,接下来几个月随笔不会有更新,不过这貌似影响不大(关注我的人太少)— —!,最后给大家拜个早年,身体健康,同时也祝自己学业有成!

如代码有错误或者有疑问请评论或联系我!