HTML5新特性

本章的主要内容有:


[1] 用于媒体回放的 video 和audio 元素

[2] HTML5拖放

[3] canvas简单应用

[4] Web存储: localStorage 和 SessionStorage

[5] Input输入类型

[6] 表单类型

[7] 表单属性

[8] 地理定位 (geolocation)

[9] Web Workers: Worker

[10] 服务器发送事件 EventSource


[1] 用于媒体回放的 video 和audio 元素

  • video 支持格式:ogg/mp4/webm; audio 支持格式:ogg/mp3/wav

  • audio 和 vedio 的用法基本相同, 只不过 audio 没有 width 和 height 属性

  • controls 属性向用户显示控件, 比如播放按钮; autoplay 属性自动播放

  • 根据 source 标签浏览器将使用第一个可识别的格式

    <video width="100px" height="100px" autoplay>
        <source src="vai/movie.ogg" type="video/ogg">
        <source src="vai/movie.mp4" type="video/mp4">
    </video>

    <audio src="vai/song.mp3" controls></audio>
视频/音频.png

[2] HTML5拖放

  1. 把拖放元素的 draggable 属性设置为 true
  2. 拖放元素的属性 ondragstart 调用一个函数, 通过 event 的 dataTransfer.setData() 方法设置被拖数据的数据类型和值
  3. ondragover 属性规定在何处放置被拖动的数据, 这里必须要通过 event 的 preventDefault() 方法阻止对元素的默认处理方式
  4. ondrop 属性设置被拖动的数据

** [注] IE 不支持 **

    <div ondrop="drop()" ondragover="allowDrop()">
        <imgsrc="vai/w3c.gif" draggable="true" ondragstart="drag()" id="drag1" />  /* 这里我就无能为力了,简书会把我的img替换成它的图片格式,为了防止自动转化,我把img和src中间空格去了 */
    </div>
    <div ondrop="drop()" ondragover="allowDrop()"></div>

    <script type="text/javascript">
        function allowDrop() {
            event.preventDefault();
        }
        function drag() {
            event.dataTransfer.setData("***", event.target.id);  /* 在这个例子中, 数据类型是 "***", 值是可拖动元素的 id ("drag1") */
        }
        function drop() {
            event.preventDefault();  /* 避免浏览器对数据的默认处理 (drop 事件的默认行为是以链接形式打开) */
            var data = event.dataTransfer.getData("***");   
            /* 通过 event 的 dataTransfer.getData() 方法传入数据类型 "***", 获得可拖动数据元素 id ("drag1") */
            event.target.appendChild(document.getElementById(data));   /* 把被拖元素追加到放置元素 (目标元素) 中 */
        }
    </script>
拖放.gif

[3] canvas简单应用

  • canvas 元素本身是没有绘图能力, 所有的绘制工作必须在 JavaScript 内部完成
    <canvas id="myCanvas"  width="400" height="200" style="border:1px solid #c3c3c3;">
        坐标原点 (0, 0) 从左上角开始, 宽代表 x 轴, 高代表 y 轴
    </canvas>   
    
    <script type="text/javascript">
        var c = document.getElementById("myCanvas");
        var cxt = c.getContext("2d");  /* getContext("2d") 对象是内建的 HTML5 对象, 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法 */   
        // 画矩形
        cxt.fillStyle = "#FFFF00";    /* 矩形的背景颜色, 默认为黑色 */
        cxt.fillRect(0,0,250,150);  /* 矩形坐标, 在画布上绘制 150x75 的矩形,从左上角开始 (0, 0) */
        // 画路径 
        cxt.moveTo(10,10);    /* 起点 */
        cxt.lineTo(150,50);  /* 第一个连接点 */
        cxt.lineTo(10,50);  /* 第二个连接点 */
        cxt.strokeStyle = "blue";  /* 颜色 */
        cxt.stroke();  /* stroke() 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色 */
        // 画圆形
        cxt.fillStyle = "#FF0000";  /* 圆形背景 */
        cxt.beginPath();
        cxt.arc(125,75,15,0,Math.PI*2,true);  /* 圆心 (x, y)、半径、起始角、结束角、逆时针 (false为顺时针) */
        cxt.closePath();
        cxt.fill();  /* 圆形填充 */
        // 画渐变色
        var grd = cxt.createLinearGradient(0,100,175,50);  /* 渐变开始点(x, y) 渐变结束点(x, y) */
        grd.addColorStop(0,"#000000");   /* 渐变开始颜色 */
        grd.addColorStop(1,"#FFFFFF");  /* 渐变结束颜色 */
        cxt.fillStyle = grd;
        cxt.fillRect(0,100,175,50);
        // 把一副图像放在画布上 (Chrome不支持)
        var img = new Image();
        img.src = "vai/1.png";
        cxt.drawImage(img,200,100);
    </script>
canvas绘图.png

[4] Web存储: localStorage 和 SessionStorage

  1. localStorage 方法存储的数据没有时间限制。第二天、第二周或下一年之后, 数据依然可用
  2. sessionStorage 方法针对一个 session 进行数据存储。当用户关闭浏览器窗口后, 数据会被删除
    <div id="result"></div>
    <script>
        // localStorage 和 sessionStorage 的存储与访问
        if (typeof Storage !== "undefined") {
            localStorage.setItem("firstname", "Bill");   /* 存储, 或者 localStorage.lastname="Gates"; */
            sessionStorage["lastname"] = "Gates";
            document.getElementById("result").innerHTML = localStorage.getItem("firstname") + " " + sessionStorage.getItem("lastname");
        } else {
            document.getElementById("result").innerHTML = "抱歉!您的浏览器不支持 Web Storage ...";
        }
        // localStorage 计数功能, 关闭浏览器数据不丢失
        if (localStorage.pagecount) {   
            localStorage.pagecount=Number(localStorage.pagecount) +1;  // 建立的是 String 类型
        }
        else {    // 如果没有该对象属性, 则创建
            localStorage.pagecount=1;
        }
            document.write("Visits "+ localStorage.pagecount + " time(s).");
        // sessionStorage 方法与 localStorage 用法相同
    </script>
result.png

[5] Input输入类型

  • email, url, number, range, (date, month, week, time, datetime, datetime-local), color, search
    <form action="" method="get">
        Email: <input type="email" name="email" />
        <!-- numner 出现 1~10 的选择框, 和 range 用法相同 (会出现滑动条); step 属性规定合法的数字间隔, 只能选择 1、4、7、10 -->
        Points: <input type="number" name="point" min="1" max="10" step="3" />   <!-- 规定了 name 属性后点击提交, 值会出现在 url 框中 -->
        Date: <input type="date" name="date" />
        Time: <input type="time" name="time" />
        DateTime: <input type="datetime-local" name="datetime-local" /> <!-- 设置日期加时间 (本地时间) -->
        Color: <input type="color" name="color" value="#ff00ff" />  <!-- 默认在输入框中为黑色 -->
        <input type="submit" /> 
    </form>
result.png

[6] 表单类型

  • datalist (下拉框), keygen (公钥和密钥), output (输出框)
    Webpage: <input type="url" list="url_list" name="link" />  <!-- 必须通过 input 的 list 属性引用 datalist 标签的 id -->
    <datalist id="url_list">  
        <option label="W3School" value="http://www.W3School.com.cn" />  <!-- [注] 与 select 中的 option 用法不一样 (select 中 option 要闭合) -->
        <option label="Google" value="http://www.google.com" />
        <option label="Microsoft" value="http://www.microsoft.com" />
    </datalist>
datalist应用.png

[7] 表单属性

  • placeholder, multiple, autofocus, required, pattern, form
    <!-- input 属性 -->
    期待输入(灰色): <input type="search" name="user_search"  placeholder="Search W3School" /> <br>
    多文件上传: <input type="file" name="mulfile" multiple="multiple" /> <br>
    自动获焦: <input type="text" name="user_name"  autofocus="autofocus" /> <br>
    必填字段: <input type="text" name="usr_name" required="required" /> <br>
    正则判断: <input type="text" name="country_code" pattern="[A-z]{3}" title="Three letter country code" /> <br> <!-- 出错会显示title信息 -->
    <!-- form 属性 -->
    <form action="" method="get" id="user_form">
        First name: <input type="text" name="fname" />
        <input type="submit" />
    </form>
    Last name: <input type="text" name="lname" form="user_form" />  <!-- 利用 input 的 form 属性引用表单的 id 使 input 仍然位于该表单之中 -->
result.png

[8] 地理定位 (geolocation)

    <p id="demo"> 点击这个按钮, 获得您的位置: </p>
    <button onclick="getLocation()">试一下</button>
    <div id="mapholder"></div>
    <script>
        var x=document.getElementById("demo");
        function getLocation() {
            if (navigator.geolocation) {
                /* 如果 getCurrentPosition() 运行成功, 则向参数 showPosition 中规定的函数返回一个 coordinates 对象 */
                navigator.geolocation.getCurrentPosition(showPosition,showError);  /* 参数为两个回调函数 (函数名, 不加括号) */
            }
            else{
                x.innerHTML="Geolocation is not supported by this browser.";
            }
        }
        function showPosition(position) {
            var latlon=position.coords.latitude+","+position.coords.longitude; /* 维度、经度*/
            var img_url="http://maps.googleapis.com/maps/api/staticmap?center="+latlon+"&zoom=14&size=400x300&sensor=false"; /* 谷歌地图 */
            document.getElementById("mapholder").innerHTML = "<imgsrc='"+img_url+"' />";  /* 将谷歌地图的链接加入图片的路径中 */
        }
        function showError(error) {
            switch(error.code) {
                case error.PERMISSION_DENIED:
                    x.innerHTML="User denied the request for Geolocation."
                break;
                case error.POSITION_UNAVAILABLE:
                    x.innerHTML="Location information is unavailable."
                break;
                case error.TIMEOUT:
                    x.innerHTML="The request to get user location timed out."
                break;
                case error.UNKNOWN_ERROR:
                    x.innerHTML="An unknown error occurred."
                break;
            }
        }
    </script>
获得地理位置.png

[9] Web Workers: Worker

  • Web Worker 是运行在后台的 JavaScript, 不会影响页面的性能
  • 由于 web worker 位于外部文件中, 它们无法访问下例 JavaScript 对象: window 对象, document 对象, parent 对象
  • 需要跨域访问, 故在本地不能运行 (上传至服务器即可查看下面代码的运行效果)
    Count numbers: <output id="res"></output><br>
    <button onclick="startWorker()">Start Worker</button>
    <button onclick="stopWorker()">Stop Worker</button>
    <br />
    <script>
        var w;
        function startWorker() {
            if(typeof Worker !== "undefined") {
                if(typeof w =="undefined") {
                    w=new Worker("js/timeCount.js");  /* 创建 Worker 对象 */
                    // w.postMessage("hello");     /* 向worker发送数据, 模拟双线程 */
                    w.onmessage = function (evt) {   /* 当 web worker 传递消息时,会执行事件监听器中的代码 */
                        document.getElementById("res").innerHTML=evt.data; /* 从 timeCount.js 收到的数据*/
                    /* [注] event可传参,也可以不传参 */
                    };
                }
            }
            else {
                document.getElementById("res").innerHTML="Sorry, your browser does not support Web Workers..."; 
            }
        }
        function stopWorker() { 
            w.terminate();  /* 终止 web worker, 并释放浏览器/计算机资源, 请调用 terminate() 方法 */
        }
    </script>
  • js/timeCount.js文件
var i=0;
function timeCount() {
    i=i+1;
    postMessage(i);   /* postMessage() 方法向主线程发送数据 */
    setTimeout(timeCount,500);  /* 或 setTimeout("timeCount()",500); */
    timeCount();
}
timeCount();  /* 一定要调用函数执行 */

// 模拟双线程的用法

// onmessage = function (evt){
//   var p = evt.data;  //通过evt.data获得发送来的数据
//   var r = p + " world!!!";
//   postMessage(r);  //将获取到的数据加工后发送回主线程
// }
result.png

[10] 服务器发送事件 EventSource

  • HTML5 服务器发送事件 (server-sent event) 允许网页获得来自服务器的更新
    <div id="resu"></div>  <!-- id 不能和前面例子的 id 相同 -->
    <script>
        if(typeof EventSource !=="undefined") {
            var source=new EventSource("php/server.php");  /* 创建 EventSource 对象 */
            source.onmessage=function(event) {
                document.getElementById("resu").innerHTML += event.data + "<br />";  /* 获得 php/server.php 发来的数据 */
            };
        }
        else {
            document.getElementById("resu").innerHTML = "抱歉,您的浏览器不支持 server-sent 事件 ...";
        }
    </script>
  • php/server.php 文件
<?php
    header('Content-Type: text/event-stream');  /* 把报头 "Content-Type" 设置为 "text/event-stream" */
    header('Cache-Control: no-cache');  /* 规定不对页面进行缓存 */

    $time = date('r');
    echo "data: The server time is: ".$time."\n\n";  /* 格式不能变, 以 data: 开头 (data: 不输出), 最后跟两个回车 (回车用 \n, 用 <br> 不通过) */
    flush();
?>
result.png
欢迎指正错误和补充!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容