On Github Halo9Pan03 / presentation-wn
潘昊
You can select from different transitions, like: Cube - Page - Concave - Zoom - Linear - Fade - None - Default
Reveal.js comes with a few themes built in: Default - Sky - Beige - Simple - Serif - Night Moon - Solarized
* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <head> using a <link>.
HTML5 ~= HTML + CSS + JS
迎接意外
// use localStorage for persistent storage // use sessionStorage for per tab storage saveButton.addEventListener('click', function () { window.localStorage.setItem('value', area.value); window.localStorage.setItem('timestamp', (new Date()).getTime()); }, false); textarea.value = window.localStorage.getItem('value');
Save text value on the client side (crash-safe)
保存var db = window.openDatabase("DBName", "1.0", "description", 5*1024*1024); //5MB db.transaction(function(tx) { tx.executeSql("SELECT * FROM test", [], successCallback, errorCallback); });
查看数据库:Developer > Developer Tools > Storage
var idbRequest = window.indexedDB.open('DatabaseName'); idbRequest.onsuccess = function(event) { var db = event.target.result; var transaction = db.transaction(['ObjectStoreName'], 'readonly'); var curRequest = transaction.objectStore('ObjectStoreName').openCursor(); curRequest.onsuccess = ...; }; idbRequest.onupgradeneeded = function(event) { var db = event.target.result var objectStore = db.createObjectStore('ObjectStoreName'); }
<html manifest="cache.appcache">
window.applicationCache.addEventListener('updateready', function(e) { if (window.applicationCache.status == window.applicationCache.UPDATEREADY) { window.applicationCache.swapCache(); if (confirm('A new version of this site is available. Load it?')) { window.location.reload(); } } }, false);
cache.appcache:
CACHE MANIFEST # version 1.0.0 CACHE: /assets/logic.js /assets/style.css /assets/background.png NETWORK: *
此演示可以离线运行!
// Request Status webkitStorageInfo.queryUsageAndQuota(webkitStorageInfo.TEMPORARY, function(used, remaining) { console.log("Used quota: " + used + ", remaining quota: " + remaining); } ); // Request Quota (only for File System API) webkitStorageInfo.requestQuota(webkitStorageInfo.PERSISTENT, 10 * 1024 * 1024, function(used) { console.log("Used quota: " + used + ", remaining quota: " + remaining); } );默认(临时) 配额(持久) Web Storage 5Mb N/A App Cache 存储总空间的10%
保持连接
var worker = new Worker('task.js'); worker.onmessage = function(event) { alert(event.data); }; worker.postMessage('data');
self.onmessage = function(event) { // Do some work. self.postMessage("recv'd: " + event.data); };
窗口的动画不会被 Web Workers打断
点击方块,开始动画。动画使用了 requestAnimationFrame的新方法
点击左边的按钮开始Web Worker
Messages from Worker:
var socket = new WebSocket('ws://html5rocks.websocket.org/echo'); socket.onopen = function(event) { socket.send('Hello, WebSocket'); }; socket.onmessage = function(event) { alert(event.data); } socket.onclose = function(event) { alert('closed'); }
在浏览器中实现和服务器端双向通信。双向通信可以拓展浏览器上的应用类型,例如实时的数据推送(股票行情)、游戏、聊天等。
if (window.Notification && Notification.permission !== "granted") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } }); }
if (window.Notification && Notification.permission === "granted") { var n = new Notification(d.title, {icon: d.icon, body: d.message, tag: d.tag}); }
仅仅支持Chrome 22+ 和 Firefox 22+
与操作系统深度融合
document.addEventListener('dragstart', function(event) { event.dataTransfer.setData('text', 'Customized text'); event.dataTransfer.effectAllowed = 'copy'; }, false);Select text and drag 选择并拖拽文字试试:-)
从文件系统拖入文件
document.querySelector('#dd-dropzone').addEventListener('drop', function(e) { var reader = new FileReader(); reader.onload = function(evt) { document.querySelector('img').src = evt.target.result; }; reader.readAsDataURL(e.dataTransfer.files[0]); }, false);
拖出文件到文件系统
<a href="assets/let_it_go_1.mp4" draggable="true" class="dragout" data-downloadurl="MIMETYPE:FILENAME:ABSOLUTE_URI_TO_FILE">download</a>
var files = document.querySelectorAll('.dragout'); for (var i = 0, file; file = files[i]; ++i) { file.addEventListener('dragstart', function(e) { e.dataTransfer.setData('DownloadURL', this.dataset.downloadurl); }, false); }
仅仅支持Google Chrome
使用Javascript异步的将文件写入沙盒文件系统中
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function(fs) { // fs.root is a DirectoryEntry object. fs.root.getFile('log.txt', {create: true}, function(fileEntry) { fileEntry.createWriter(function(writer) { // writer is a FileWriter object. writer.onwrite = function(e) { ... }; writer.onerror = function(e) { ... }; var bb = new BlobBuilder(); bb.append('Hello World!'); writer.write(bb.getBlob('text/plain')); }, opt_errorHandler); } }, opt_errorHandler);
仅仅支持Google Chrome 9+
if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function(position) { var map = new BMap.Map("allmap"); var point = new BMap.Point( position.coords.latitude, position.coords.longitude); map.centerAndZoom(point,15); }, errorHandler); }当前位置(百度地图)
需要Google服务,可能无法正常工作,你懂的
window.addEventListener('deviceorientation', function(event) { var a = event.alpha; var b = event.beta; var g = event.gamma; }, false);加载设备方向
X axis:x Y axis:y Z axis:z
需要 FF3.6+ 或者 Google Chrome 并且设备支持方向传感器
<input type="text" speech x-webkit-speech />
该功能在Chrome中因为安全原因,已经被废弃
新SpeechRecognition,仅支持Chrome 22+
var recognition = new webkitSpeechRecognition(); recognition.continuous = true; recognition.interimResults = true; recognition.onresult = function(event) { ...... } recognition.start();
点击下面的输入框,然后说话试试
var msg = new SpeechSynthesisUtterance('Hello World'); speechSynthesis.speak(msg);
使标签更有意义
<body> <header> <hgroup> <h1>Page title</h1> <h2>Page subtitle</h2> </hgroup> </header> <nav> <ul> Navigation... </ul> </nav> <section> <article> <header> <h1>Title</h1> </header> <section> Content... </section> </article> <article> <header> <h1>Title</h1> </header> <section> Content... </section> </article> </section> <aside> Top links... </aside> <figure> <img src="..."/> <figcaption>Chart 1.1</figcaption> </figure> <footer> Copyright © <time datetime="2010-11-08">2010</time>. </footer> </body>
<input list="cars"/> <datalist id="cars"> <option value="BMW"/> <option value="Ford"/> <option value="Volvo"/> </datalist> <menu> <command type="command" disabled label="Publish" /> </menu> <details> <summary>HTML 5</summary> This slide deck teaches you everything you need to know about HTML 5. </details> HTML 5Web 开发的未来之路
<meter min="0" max="100" low="40" high="90" optimum="100" value="91">A+</meter> Your score is: A+ <progress>working...</progress> 下载:working... <progress value="75" max="100">3/4 complete</progress> 目标完成:3/4 complete
<link rel="alternate" type="application/rss+xml" href="http://halo9pan.info/feed"/> <link rel="icon" href="/favicon.ico"/> <link rel="pingback" href="http://halo9pan.info/xmlrpc.php"/> <link rel="prefetch" href="http://halo9pan.info/"/> ... <a rel="archives" href="http://myblog.com/archives">old posts</a> <a rel="external" href="http://notmysite.com">tutorial</a> <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">license</a> <a rel="nofollow" href="http://notmysite.com/sample">wannabe</a> <a rel="tag" href="http://halo9pan.info/category/codeway">CodeWay</a> ...
<template id="template-sample"> <img src="" alt="great image"> <div class="comment"></div> </template>
<script> var t = document.querySelector('#template-sample'); // Populate the src at runtime. t.content.querySelector('img').src = 'logo.png'; var clone = document.importNode(t.content, true); document.body.appendChild(clone); </script>Use me
var XFoo = document.registerElement('x-foo', { prototype: Object.create(HTMLElement.prototype) });
<x-foo></x-foo>
var xFoo = document.createElement('x-foo'); xFoo.addEventListener('click', function(e) { alert('Thanks!'); });
var xFoo = new XFoo(); document.body.appendChild(xFoo);
var MegaButton = document.registerElement('mega-button', { prototype: Object.create(HTMLButtonElement.prototype), extends: 'button' });
<button is="mega-button">
var megaButton = document.createElement('button', 'mega-button');
var megaButton = new MegaButton(); document.body.appendChild(megaButton);
自定义标签名必须包含“-”
<button id="hello-shadow">Hello, Shadow!</button> <script> var host = document.querySelector('#hello-shadow'); var root = host.createShadowRoot(); root.textContent = '欢迎来到影子世界!'; </script>Hello, Shadow!
<div itemscope itemtype="http://example.org/band"> <p>My name is <span itemprop="name">Neil</span>.</p> <p>My band is called <span itemprop="band">Four Parts Water</span>.</p> <p>I am <span itemprop="nationality">British</span>.</p> </div>
已废弃,RDFa替代
Google 网页摘要测试工具http://www.google.com/webmasters/tools/richsnippet The Downward Spiral of Microdata<ul id="tree1" role="tree" tabindex="0" aria-labelledby="label_1"> <li role="treeitem" tabindex="-1" aria-expanded="true">Fruits</li> <li role="group"> <ul> <li role="treeitem" tabindex="-1">Oranges</li> <li role="treeitem" tabindex="-1">Pineapples</li> ... </ul> </li> </ul>
<style> [required] { border-color: #88a; -webkit-box-shadow: 0 0 3px rgba(0, 0, 255, .5); } :invalid { border-color: #e88; -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8); } </style>
<input type="text" required /> <input type="email" value="some@email.com" /> <input type="date" min="2010-08-14" max="2011-08-14" value="2010-08-14"/> <input type="range" min="0" max="50" value="10" /> <input type="search" results="10" placeholder="Search..." /> <input type="tel" placeholder="(555) 555-5555" pattern="^\(?\d{3}\)?[-\s]\d{3}[-\s]\d{4}.*?$" /> <input type="color" placeholder="e.g. #bbbbbb" /> <input type="number" step="1" min="-5" max="10" value="0" />
type="text"Android
type="number"Android
type="email"iOS
type="tel"iOS
2D & 3D
<audio id="audio" src="sound.mp3" controls></audio> document.getElementById("audio").muted = false;
<video id="video" src="movie.webm" autoplay controls></video> document.getElementById("video").play();
<video width="390" id="clip" controls> <source src="Google_Developer_Stories.webm" type='video/webm; codecs="vp8, vorbis"' /> <track label="English subtitles" kind="subtitles" srclang="en" src="video-subtitles-en.vtt" default /> </video>
if (elem.webkitRequestFullScreen) { elem.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); } else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); } else if (elem.requestFullScreen){ elem.requestFullScreen(); }
:-webkit-full-screen-ancestor:root { overflow: hidden; } :-webkit-full-screen-ancestor { z-index: auto; -webkit-transform: none; -webkit-transition: none; } pre:-webkit-full-screen { background-color: white; }
<canvas id="canvas" width="400" height="240"></canvas> <script> var canvasContext = document.getElementById("canvas").getContext("2d"); canvasContext.fillRect(250, 25, 150, 100); canvasContext.beginPath(); canvasContext.arc(450, 110, 100, Math.PI * 1/2, Math.PI * 3/2); canvasContext.lineWidth = 15; canvasContext.lineCap = 'round'; canvasContext.strokeStyle = 'rgba(255, 127, 0, 0.5)'; canvasContext.stroke(); </script>
<canvas id="canvas" width="400" height="240"></canvas> <script> var gl = document.getElementById("canvas").getContext("experimental-webgl"); gl.viewport(0, 0, canvas.width, canvas.height); ... </script>加载 显示/隐藏 更多有趣的例子: Goo Video Sphere VideoFX
<html> <svg width="400px" height="200px"> <defs> <linearGradient id="myGradient" x1="0%" y1="100%" x2="100%" y2="0%"> <stop offset="5%" stop-color="red"></stop> <stop offset="95%" stop-color="blue" stop-opacity="0.5"></stop> </linearGradient> </defs> <circle id="myCircle" class="important" cx="50%" cy="50%" r="100" fill="url(#myGradient)" onmousedown="alert('hello');"/> </svg> </html>
Presentation & Styling
.row:nth-child(even) { background: #dde; } .row:nth-child(odd) { background: white; }
div { display: inline-block; }
input[type="text"] { background: #eee; }
:not(.box) { color: #00c; } :not(span) { display: block; }
h2:first-child { ... } div.text > div { ... } h2 + header { ... }
@font-face { font-family: 'LeagueGothic'; src: url(LeagueGothic.otf); } header { font-family: 'LeagueGothic'; }
人之初,性本善。性相近,习相远。
苟不教,性乃迁。教之道,贵以专。
昔孟母,择邻处。子不学,断机杼。
窦燕山,有义方。教五子,名俱扬。
div { text-overflow: ellipsis; }
Play with the slider on this and further pages!
-webkit-column-count: 2; -webkit-column-rule: 1px solid #bbb; -webkit-column-gap: 2em;
人之初,性本善,性相近,习相远,苟不教,性乃迁。
教之道,贵以专,昔孟母,择邻处,子不学,断机杼。
窦燕山,有义方,教五子,名俱扬,养不教,父之过。
教不严,师之惰,子不学,非所宜,幼不学,老何为。
玉不琢,不成器,人不学,不知义,为人子,方少时。
亲师友,习礼仪,香九龄,能温席,孝于亲,所当执。
融四岁,能让梨,弟于长,宜先知,首孝弟,次见闻。
知某数,识某文,一而十,十而百,百而千,千而万。
三才者,天地人,三光者,日月星,三纲者,君臣义。
父子亲,夫妇顺,曰春夏,曰秋冬,此四时,运不穷。
曰南北,曰西东,此四方,应乎中,曰水火,木金土。
此五行,本乎数,曰仁义,礼智信,此五常,不容紊。
稻粱菽,麦黍稷,此六谷,人所食,马牛羊,鸡犬豕。
此六畜,人所饲,曰喜怒,曰哀惧,爱恶欲,七情具。
匏土革,木石金,丝与竹,乃八音,高曾祖,父而身。
身而子,子而孙,自子孙,至玄曾,乃九族,人之伦。
父子恩,夫妇从,兄则友,弟则恭,长幼序,友与朋。
君则敬,臣则忠,此十义,人所同,凡训蒙,须讲究。
详训诂,名句读,为学者,必有初,小学终,至四书。
论语者,二十篇,群弟子,记善言,孟子者,七篇止。
讲道德,说仁义,作中庸,乃孔伋,中不偏,庸不易。
作大学,乃曾子,自修齐,至平治,孝经通,四书熟。
如六经,始可读,诗书易,礼春秋,号六经,当讲求。
有连山,有归藏,有周易,三易详,有典谟,有训诰。
有誓命,书之奥,我周公,作周礼,著六官,存治体。
大小戴,注礼记,述圣言,礼乐备,曰国风,曰雅颂。
号四诗,当讽咏,诗既亡,春秋作,寓褒贬,别善恶。
三传者,有公羊,有左氏,有谷梁,经既明,方读子。
撮其要,记其事,五子者,有荀杨,文中子,及老庄。
经子通,读诸史,考世系,知终始,自羲农,至黄帝。
号三皇,居上世,唐有虞,号二帝,相揖逊,称盛世。
夏有禹,商有汤,周文武,称三王,夏传子,家天下。
div { -webkit-text-fill-color: black; -webkit-text-stroke-color: red; -webkit-text-stroke-width: 0.00px; }
color: hsla(120, 40%, 40%, 0.75); background: hsla(120, 80%, 80%, 0.75);
color: hsla( 120 40%, 40%, 1.00 );
face{border-radius: 0px} left eye{border-radius: 0px} right eye{border-radius: 0px} base white{border-radius: 0px} mouth{border-radius: 0px} nose{border-radius: 0px} left black eye{border-radius: 0px} right black eye{border-radius: 0px}
background-image: linear-gradient(top, hsla(90, 40%, 40%, 0.4) 0%, hsl(90, 40%, 100%) 50%, hsl(150, 80%, 100%) 50%, hsla(150, 80%, 20%, 0.6) 100%);
background-image: radial-gradient(center, circle cover, hsla(150, 80%, 40%, 0.8), hsla(90, 40%, 80%, 0.2) 40%);
text-shadow: rgba(64, 64, 64, 0.5) 0px 0px 0px; box-shadow: rgba(0, 0, 128, 0.25) 0px 0px 0px;
text-shadow: rgba(0, 0, 0, 0.5) 0 0px 0px; background: -webkit-gradient(linear, left top, left bottom, from(rgba(200, 200, 240, 0)), to(rgba(255, 255, 255, 0))); border-radius: 0px; -webkit-box-reflect: below 10px -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(255, 255, 255, 0)));
#logo { background: url(logo.gif) center center no-repeat; background-size: autocontaincover100%; }
Resize me! »
div { background: url(assets/zippy-plus.png) 10px center no-repeat, url(assets/gray_lines_bg.png) 0 center repeat-x; }
-webkit-border-image: url(border_image_1.png) 20%40%153350stretchrepeatroundstretchrepeatround; border-width: 10px;
.box { display: -webkit-box; -webkit-box-orient: horizontalvertical; } .box .one, .box .two { -webkit-box-flex: 1; } .box .three { -webkit-box-flex: 3; }
.box { display: -webkit-box; -webkit-box-pack: centerstartend; -webkit-box-align: centerstartendstretch; }
#box.left { margin-left: 0; } #box.right { margin-left: 1000px; } document.getElementById('box').className = 'go-left'; Left document.getElementById('box').className = 'go-right'; Right
#box { -webkit-transition: margin-left 1s ease-in-out; } document.getElementById('box').className = 'go-left'; Left document.getElementById('box').className = 'go-right'; Right
#threed-example { -webkit-transition: -webkit-transform 2s ease-in-out; } #threed-example:hover { -webkit-transform: rotateZ(-30deg); }
Original
Transformed
@-webkit-keyframes pulse { from { opacity: 0.0; font-size: 100%; } to { opacity: 1.0; font-size: 200%; } } div { -webkit-animation-name: pulse; -webkit-animation-duration: 2s; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: ease-in-out; -webkit-animation-direction: alternate; }
越来越快
var el = document.getElementById('section1'); el.focus(); var els = document.getElementsByTagName('div'); els[0].focus(); var els = document.getElementsByClassName('section'); els[0].focus();
var els = document.querySelectorAll("ul li:nth-child(odd)"); var tds = document.querySelectorAll("table.test > tr > td"); var el = document.querySelector("table.test > tr > td"); // el == tds[0]
<div id="out" data-id="good" data-name="joe" data-screen-name="user1"></div>
// Add new data attributes via JS. var el = document.querySelector('#out'); el.setAttribute('data-foo', 'bar'); var html = []; for (var key in el.dataset) { html.push(key, ': ', el.dataset[key], '<br>'); } el.innerHTML = html.join('');
Output:
id: good name: joe screenName: user1 foo: bar
<div id="main" class="shadow rounded"></div>
var el = document.querySelector('#main').classList; el.add('highlight'); el.remove('shadow'); el.toggle('highlight'); console.log(el.contains('highlight')); // false console.log(el.contains('shadow')); // false console.log(el.classList.toString() == el.className); // true
Output:
<div id="main" class="rounded"></div>
<link rel="prefetch" href="http://halo9pan.info"/> <link rel="prefetch" href="http://halo9pan.info"/>
document.addEventListener('visibilitychange', function(e) { // Start or stop processing depending on state if(document.hidden) { ... } }, false);你的浏览器不支持 <video> 标签
link.addEventListener('click', function(event) { // manually add a value to the history stack // without making the browser load any new page history.pushState('Contact Page Form', 'Contact Page', '/contact'); }); // capture navigation in case we want to change, // for instance, some content when it changes window.addEventListener('popstate', function(event) { document.querySelector('h1').innerHTML = event.state; // 'Contact Page Form' });