摘要:Eric Bidelman是Google Chrome开发团队里面的一位高级软件工程师,根据多年的Web开发经验,他总结了如何在实际中灵活运用HTML5和CSS3并把内容归纳为5大点。作为一名Web开发人员,这五点你知道吗?你OUT了吗?
本文围绕如何使用最新的Web技术来进行实际操作,并且在网页中展示最新的最炫的Web效果。毕竟,拥有华丽的外表才会吸引人的关注,没有人会去访问一个无序的,乱糟糟的网站。
在本文中,我们将会钻研“The Web Can Do That!?”中五种最神奇的Web效果。
备注:本文讨论的技术都非常新,最好在Chrome 21+上试用或演示。
1.CSS Web应用
CSS已经向我们展示了许多神奇、魅力非凡的地方,但不幸地是,CSS在布局和展现能力方面(绝对定位和浮动)已经不能满足现代Web开发需求。值得关注的是我们构建的不仅仅是一个网站——而是应用程序。这个需求是非常不同的,许多原始网站架构在某方面都做的很糟糕,比如响应式设计。
幸运的是,CSS Working Group已经提前做了3个调整,并且还提出了一系列的新规范来直接解决应用程序的布局和设计问题。CSS网格布局、层次结构、区域和灵活的方框布局模块等等。
下面让我们来探讨其中一个:CSS Flexbox
Alignment
这里我特别要提到的是Flexbox,因为他可以使内容在水平和垂直方向居中,仅需要3行CSS代码。
示例代码:
- .box {
- display: +flex;
- +justify-content: center;
- +align-items: center;
- }
- <section class=”box”>
- <div>A</div><div>B</div><div>C</div>
- </section>
备注:代码中的“+”表示供应商前缀,例如“+flex”可能是-webkit-flex,-ms-flex等。
以上例子会产生如下布局:
display:flex——通知父容器要成为一个‘flex container’。在上面的插图中,红色的区域表示flex container并且里面包含三个“孩子”,蓝色的区域,属于‘flex items’。A、B、C这三个字母位于主轴和十字轴位置上。仅仅使用了:justify-content:center和align-items:center这两行代码。
排序和方向定位
Flexbox的另一个神奇属性是我们可以从标签的呈现方式上对其进行完全独立排序。这个需要用到两个新的CSS属性,order和flex-direction。Order是对每个“兄弟姐妹”成员进行排序,flex-direction修改他们的方向(行VS列)。
你想把A、B、C这三个字母放在同一个列里面吗?没问题,只需要设置flex-direction:column即可。
备注:默认情况下,每个项目的排序是根据标签的默认排序来的,但是我们可以轻易地覆盖默认排序,通过给B一个比其他家庭成员低一阶的值,它将优先于其他成员。
- .box {
- +flex-direction: column;
- }
- .box > :nth-child(2) {
- +order: -1;
- }
效果:
值得注意的是,我们不能改变文件内容,它仍然是A、B、C三个字母。Flexbox可以使我们能够独立于内容进行编排页面样式。
Flexibility
Flexbox的“面包”和“黄油”正是flexibility这一特征的体现。除了alignment、orientation、和ordering,还可以通知项目成员增加/减少填充它们周围可利用的空间。这些都可以通过flex属性实现。
Flex属性需要三个值,第一个postive flex值:与其他兄弟姐妹相比,还有多少元素可以增加;第二个是negative flex:可以缩小多少个元素;第三个表示元素所需的宽度。
修改我们之前的例子,我们可以使用flex属性来使B的空间可以多添加2个成员。
- .box > * {
- +flex: 1 0 auto;
- }
- .box > :nth-child(2) {
- +flex: 3 0 auto;
- }
期望效果:
案例要求:Chrome 21
这个例子,如下图所示,使用CSS Flexbox来创建一个‘Holy Grail’布局(头部,3列,尾)。最好的是,整个应用程序是响应式的,试着调整你的浏览器窗口吧!
浏览器支持
Chrome 21和IE 10支持最新的Flexbox规范。
2.单向数据绑定
数据绑定是所有现代Web应用程序中不可或缺的。在Web组件MDV面世之前,我们不得不依赖JavaScript框架来填补这部分的空白,比如Angular和Ember。
Angular是我目前最喜欢的MVC框架,因为它很简单。不需要学习任何新APIs或者语法就可以直接使用,它依赖原始HTML作为其模板语言和纯JavaScript代码作为逻辑控制器。
在Angular中进行单向数据绑定是非常简单的事情,只需使用一个小标记:
- <div ng-app ng-init=”val=25″>
- Volume: <input type=”range” min=”0″ max=”100″ ng-model=”val”> {{val}}/100
- </div>
随着用户的滑动,名为val的模块不断进行更新并且其相应的模块变量会自动重新计算。Angular确实承担了许多繁重的任务通过设置隐藏事件监听器和随着模块的变化重新设计视图。
使用HTML5 data-*属性
使用HTML5特性可以做许多相同的事情,一个非常聪明的技巧:使用:before/:after伪元素。然而,在HTML5案例中,我们并没有进行奢侈的自动化数据绑定,这个过程看起来像是:
- Model:data-*属性,使用CSS的attr()方法来获取值。
- View:使用:before/:after伪元素来生成内容。
- 如何绑定?:钩起一个事件监听器来观察数据模型的变化。
我们可以通过这个想法实现与Angular同样的滑块且无需框架。
- <style>
- input::after {
- content: attr(data-value) ’/' attr(max);
- position: relative;
- left: 135px; top: -20px;
- }
- </style>
- <input type=”range” min=”0″ max=”100″ value=”25″>
- <script>
- var input = document.querySelector(‘input’);
- inputinput.dataset.value = input.value; // Set an initial value.
- input.addEventListener(‘change’, function(e) {
- thisthis.dataset.value = this.value; // Update the view.
- });
- </script>
使用<datalist>
或许在HTML5中实现数据单向绑定的更好方法(或更多语义的)是使用<datalist>元素。
Opera和Firefox多年前就支持<datalist>啦,但是在WebKit中是最近才有的。
数据绑定步骤:
- Model:在<datalist>元素中使用<option>来指定值。
- View:一个普通的<input>元素。
- 如何绑定?:参考数据列表的id属性列表。
同样非常简单的代码:
- Browsers: <input list=”browsers”>
- <datalist id=”browsers”>
- <option value=”Chrome”>
- <option value=”Firefox”>
- <option value=”Internet Explorer”>
- <option value=”Opera”>
- <option value=”Safari”>
- </datalist>
<datalist>是一个给<input>元素指定预定义列表选项的一个非常好的方式。会从IndexedDB数据库中自动填充表单。
浏览器支持
不管你信不信,所有现代浏览器都支持这些免费框架数据绑定。
3.访问文件系统
在他们的生命周期中,大多数体面的应用程序都会在某种程度上涉及文件I/0。HTML5文件系统API给Web开发带来了一个非常合适的文件系统,无需插件,请不要感到惊奇,拥有它,用户可以把存放数据的文件或者文件夹放到文件系统沙盒中,最后在放到你的Web应用程序端口上。
打开文件系统,调用window.requestFilesystem
- window.webkitRequestFileSystem(
- TEMPORARY, // Storage type: PERSISTENT or TEMPORARY
- 1024 * 1024, // size (bytes) of needed space
- initFs, // success callback
- opt_errorHandler // opt. error callback, denial of access
- );
显而易见,我们不需要从用户本地我的文档或我的图片文件夹中读/写数据。HTML5文件系统只能与沙盒文件系统相互作用来创建应用程序。这也意味着你不能在另一个Web应用程序中修改数据。
对于这个API来说,最常见的例子是一个AppCache替换。作为一个司空见惯的例子来说,动态缓存一个图像文件是轻而易举的事:
- var xhr = new XMLHttpRequest();
- xhr.open(‘GET’, ’/path/to/image.png’, true);
- xhr.responseType = ’arraybuffer’; // We want a byte array, not a string.
- xhr.onload = function(e) {
- window.requestFileSystem(TEMPORARY, 1024 * 1024, function(fs) {
- // fs.root is the root DirectoryEntry for the filesystem.
- fs.root.getFile(‘image.png’, {create: true}, function(fileEntry) {
- fileEntry.createWriter(function(writer) {
- writer.onwriteend = function(e) { … };
- writer.onerror = function(e) { … };
- writer.write(new Blob([xhr.response], {type: ’image/png’}));
- }, onError);
- }, onError);
- }, onError);
- };
- xhr.send();
案例要求:Chrome
Filesystem Playground是一个在HTML5文件系统顶端可视化的用户接口。整个应用程序都是客户端,其中一些功能包括从桌面拖拽文件或文件夹到Web应用程序中,创建空文件夹,预览文件,重命名,下载等等。
HTML5终端模拟一个老派的命令行,基于Filesystem API。
在你创建了几个文件以后,你可以尝试使用3D命令!
浏览器支持
HTML5文件系统API目前只有Chrome支持。如果你想深入探讨文件系统API,你可以参考Using the HTML5 Filesystem API。此外给一个filer.js文件作为参考,它是一个非常方便的包装器库文件。
4.访问本地硬件
看到这个标题,你肯定会用打破砂锅问到底的劲来问我:“什么什么?Web竟然能访问本地硬件?”,对于这个疑问,我并不会去否定,如今的Web去访问诸如USB、蓝牙、UDP仍然是不可能的。我们已经看到了一些框架,例如PhoneGap已经为开发者们打下了基础——但事实是,驱动Web开发并没有给开发者们提供所有的API支持。
设备访问已经成为最近的热门话题, W3C已经在2011年8月组织了设备APIs工作小组来专门解决这一问题。最近的项目例如Chrome Apps和Firefox OS也开始在这方面进行努力探索。
我们现在能做些什么?
目前,Web应用程序通过高级的JavaScript APIs访问底层硬件的能力已经实现。在过去几年已经拥有了一批API:
- 地理定位API(定位GPS)
- 设备定位API(加速表)
- WebGL (GPU)
- HTML5 文件系统API(沙盒文件I/O)
- navigator.onLine / navigator.connection(网络链接)
- 蓄电API
- 手柄API(通过USB接口访问特定设备)
- WebRTC(音频/视频处理)/网络音频API(核心系统音频)
- ……
这个列表还在不断增加,目前我们把注意力集中到最后一个上面。
麦克风访问
自从人类诞生以来,在Web上一个梦寐以求的访问已经很好的实现——摄像头和麦克风访问(无需插件)。第一步,在Chrome里面实现x-webkit-speech属性。
- <input type=”text” x-webkit-speech>
这是一个令人兴奋的属性。通过这个属性,我们可以最低限度的去访问用户的麦克风并且用户可以以一个全新的方式来与我们的应用程序进行交互。
值得注意的是,浏览器正在逐渐扩大对越来越多的Speech JavaScript API的支持。
如今,我们可以做的更好通过使用WebRTC空间。WebTRC的核心是getUserMedia方法,一个允许应用程序请求访问麦克风/相机的API。
- <video autoplay controls></video>
- windowwindow.URL = window.URL || window.webkitURL;
- navigatornavigator.getUserMedia = navigator.getUserMedia ||
- navigator.webkitGetUserMedia ||
- navigator.mozGetUserMedia;
- navigator.getUserMedia({audio: true, video: true}, function(stream) {
- document.querySelector(‘video’).src = window.URL.createObjectURL(stream);
- }, function(e) {
- console.log(e);
- });
像getUserMedia是真心受人喜欢的,因为她可以重用平台上的一些旧模块,即HTML5<video>。而不是把video.src文件放到一个可移动文件夹中,把它设置在一个相机流创建的二进制对象URL中。这种集成与较新的老APIs相比是一个非常好的例子。
录制视频
碰巧我很期待能够(并不完全)录制LocalMediaStream这个本地化媒体流。
- <input type=”button” value=”⚫” οnclick=”record(this)”>
- <input type=”button” value=”◼” οnclick=”stop(this)”>
- var localMediaStream;
- var recorder;
- function record(button) {
- recorder = localMediaStream.record();
- }
- function stop(button) {
- localMediaStream.stop();
- recorder.getRecordedData(function(blob) {
- // Upload blob using XHR2.
- });
- }
浏览器支持
支持getUserMedia的浏览器版本:Chrome 20+(启用:flags),Opera12,和Firefox17。
5.多媒体流
Web开发人员常常疑惑不解的问:“HTML5可以做音频流吗?”事实证明,这是毫无疑问的!其中的秘密武器就是一个二进制WebSockets和Web音频API。
对于许多moons,只能通过WebSocket发送字符串数据。对于这一限制阻止使用WebSocket构建一些疯狂的酷应用程序。目前在Web平台上已经有了JavaScript类型数据和二进制数据。为什么不能使用流文件?规范制定者和浏览器厂商最终还是泄漏了这个小想法,实现包含一个更新的send()方法来支持二进制传送。
这个概念类似于XHR2。你只需简单地设置需要交换的数据格式,例如,发送一个二进制大对象/文件,给Blob设置.binaryType属性。
- var socket = new WebSocket(‘ws://example.com/sock’, ['dumby-protocol']);
- socket.binaryType = ’blob’; // or ’arraybuffer’
- socket.onopen = function(e) {
- window.setInterval(function() {
- // Send off data when nothing is buffered.
- if (socket.bufferedAmount == 0) {
- socket.send(new Blob([blob1, blob2])); // presumably image data.
- }
- }, 50); // rate limit us.
- };
- socket.onmessage = function(e) {
- document.querySelector(‘img’).src = window.URL.createObjectURL(e.data);
- };
在接收端(例如onmessage处理器),我们可以使用图像文件(e.data)直接从里面创建一个二进制对象URL,不再需要Base64编码/解码两端数据。
流式音频
二进制的套接字支持一些非常有趣的用例,例如流式音频。
这里面并没有涵盖非常详细的技术,您可以通过查看audio_streamer这个案例来研究代码是如何工作的。然而,这个过程是十分简单的:
(1)在DJ机上:
a.在整个.mp3文件上面使用Web音频API的decodeAudioData()方法。
b.一旦文件进行解码,就会把整个AudioBuffer切分成多个小块。
c.使用一个简单的Node.js服务器去把每个音频块(作为一个ArrayBuffer)发送到二进制套接字里面。
(2)在监听器上:使用Web音频API去加载并且在精确的时间里安排每个音频块,这种无缝“再现”的音频监听器就像它是一个单一的文件。
这种工作流的结果其本质上就是流式音频……在Web平台上拥有两个新特征:二进制的WebSockets和Web音频API。
WebRTC数据通道
也许未来的文件共享是通过来自WebRTC的DataChannel API进行的。但不幸的是,这只能在Chrome和Firefox上实现。该API的目标是实现数据能够实时进行点对点的交换。
浏览器支持
Chrome,Firefox,IE 10和Safari。Chrome和Safari是唯一支持Web音频API的浏览器。
总结
目前,本地化VS网络化仍然是一个争论点。作为Web开发人员,关心的并不是本地可以做什么,而真正关心的是Web能做什么!比如Web组件正在改变我们构建Web应用程序方式。
最后希望本文能给你带来一些开发上的欢乐!
英文出自:netmagazine
转载自:http://www.csdn.net/article/2012-08-16/2808582?bsh_bid=122687956