HTML5权威指南 | 第五部分 高级功能

2018-11-14  本文已影响16人  夏海峰

三十二、使用AJAX(上)

Ajax起步:

<div id="btns">
    <button>Apples</button>
    <button>Cherries</button>
    <button>Bananas</button>
</div>
<div id="target">
    Press a button.
</div>
<script>
    var btns = document.querySelectorAll("#btns button");
    bar omsg = document.getElementById("target");
    var httpRequest;
    for(var i=0; i<btns.length; i++){
        btns[i].addEventListener("click", handleBtn);
    }
    function handleBtn(e){
        httpRequest = new XMLHttpRequest();
        httpRequest.onreadystatechange = handleStateChange;
        httpRequest.open("GET",e.target.innerHTML+".html");
        httpRequest.send();
    }
    function handleStateChange(e){
        // if(e.target.readyState == XMLHttpRequest.DONE && e.target.status == 200){
        //  omsg.innerHTML = e.target.responseText;
        // }

        // 适配Opera浏览器的写法如下:
        if(httpRequest.readyState == 4 && httpRequest.status == 200){
            omsg.innerHTML = httpRequest.responseText;
        }
    }
</script>

使用Ajax事件:

<div id="req">
    <button>Apple</button>
    <button>Orange</button>
    <button>Banana</button>
</div>
<table id="dis" border="1">
    <tr>
        <th>Event</th>
        <th>lenghtComputable</th>
        <th>loaded</th>
        <th>total</th>
    </tr>
</table>
<div id="msg"></div>
<script>
    var oBtn = document.querySelectorAll("#req button");
    var oDis = document.getElementById("dis");
    var oMsg = document.getElementById("msg");
    var xhr;

    // 为按钮绑定Ajax请求
    for(var i=0; i<oBtn.length; i++){
        oBtn[i].onclick = handleReq;
    }
    // 请求函数
    function handleReq(e){
        clearTable();
        xhr = new XMLHttpRequest();
        // 绑定Ajax事件
        xhr.onreadystatechange = handleChange;
        xhr.onerror = handleError;
        xhr.onload = handleLoad;
        xhr.onloadend = handleLoadEnd;
        xhr.onloadstart = handleLoadStart;
        xhr.onprogress = handleProgress;        
        xhr.open("GET",e.target.innerHTML+".html");
        xhr.send();
    }
    // Ajax事件处理程序
    function handleChange(e){
        if(xhr.readyState==4 && xhr.status==200){
            oMsg.innerHTML = xhr.responseText;
        }
        displayAjax("onreadystatechange",e);
    }
    function handleError(e){
        displayAjax("onerror",e);
    }
    function handleLoad(e){
        displayAjax("onerror",e);
    }
    function handleLoadEnd(e){
        displayAjax("onerror",e);
    }
    function handleLoadStart(e){
        displayAjax("onerror",e);
    }
    function handleProgress(e){
        displayAjax("onerror",e);
    }

    // 把Ajax事件的信息放在表格中
    function displayAjax(eventName,e){
        if(e){
            oDis.innerHTML += "<tr><td>"+eventName+"</td><td>"+e.lenghtComputable+"</td><td>"
            +e.loaded+"</td><td>"+e.total+"</td></tr>";
        }else {
            oDis.innerHTML += "<tr><td>"+eventName+"</td><td>没有</td><td>没有</td><td>没有</td></tr>";
        }       
    }
    function clearTable(){
        oDis.innerHTML = "<tr><th>Event</th><th>lenghtComputable</th><th>loaded</th><th>total</th></tr>";
    }
</script>

Ajax请求的错误处理:

<div id="doer">
    <button>Apples</button>
    <button>Banana</button>
    <button>Orange</button>
    <button>Cucumb</button>
    <br>
    <button id="badhost">Bad Host</button>
    <button id="badurl">Bad URL</button>
</div>
<div id="tar">
    Press a Button.
</div>
<div id="errormsg"></div>
<div id="statusmsg"></div>
<script>
    var btnss = document.querySelectorAll("#doer button");
    var tar = document.getElementById("tar");
    var statusmsg = document.getElementById("statusmsg");
    var errormsg = document.getElementById("errormsg");
    var httpReq;
    for(var i=0; i<btnss.length; i++){
        btnss[i].onclick = handle;
    }
    // 点击事件处理程序
    function handle(e){
        clearmsg();
        httpReq = new XMLHttpRequest();
        httpReq.onreadystatechange = handleR;
        httpReq.onerror = handleE;
        try {
            switch (e.target.id) {
                case "badhost":
                    httpReq.open("GET","http://nodomain.com/aa.html");
                    break;
                case "badurl":
                    httpReq.open("GET","http://");
                    break;
                default:
                    httpReq.open("GET",e.target.innerHTML+".html");
                    break;
            }
            httpReq.send();
        } catch(e) {
            disErrorMsg("try/catch",e.message);
        }
    }

    // Ajax事件处理程序
    function handleR(e){
        if(httpReq.readyState==4){
            if(httpReq.status == 200){
                tar.innerHTML = httpReq.responseText;
            }else {
                statusmsg.innerHTML = "Status: "+httpReq.status + " "+httpReq.statusText;
            }
        }
    }
    // Ajax事件之error处理程序
    function handleE(e){
        disErrorMsg("Event Error",httpReq.status+":"+httpReq.statusText);
    }

    // 在div中显示错误捕获信息
    function disErrorMsg(src,msg){
        errormsg.innerHTML = src + ": "+ msg;
    }

    // 清空信息台
    function clearmsg(){
        errormsg.innerHTML = "";
        statusmsg.innerHTML = "";
    }
</script>

中止Ajax请求:

<div id="stops">
    <button>Apple</button>
    <button>Banan</button><br>
    <button id="stopAjax">Stop Ajax</button>
</div>
<div id="stopmsg"></div>
<script>
    var buttons = document.querySelectorAll("#stops button");
    var msgdiv = document.getElementById("stopmsg");
    var xhr1;
    for(var i=0; i<buttons.length;i++){
        buttons[i].onclick = handStop;
    }
    // 点击事件处理程序
    function handStop(e){
        if(e.target.id == "stopAjax"){
            xhr1.abort();
        }else {
            xhr1 = new XMLHttpRequest();
            xhr1.onreadystatechange = handResult;
            xhr1.onabort = disMsgs;
            xhr1.open("GET",e.target.innerHTML+".html");
            xhr1.send();
        }
    }
    // 请求完成的事件处理程序
    function handResult(e){
        if(xhr1.readyState == 4 && xhr1.status == 200){
            msgdiv.innerHTML = xhr1.responseText;
        }
    }
    // 中止事件处理程序
    function disMsgs(e){
        msgdiv.innerHTML = "Ajax请求,已经中止";
    }
</script>

三十三、使用AJAX(下)

准备向服务器发送数据:

<form action="" method="post" id="fruitform">
    <div class="table">
        <div class="row">
            <div class="cell label">
                Bananas:
            </div>
            <div class="cell">
                <input type="number" name="bananas" value="2">              
            </div>
        </div>
        <div class="row">
            <div class="cell label">
                Apples:
            </div>
            <div class="cell">
                <input type="number" name="apples" value="5">               
            </div>
        </div>
        <div class="row">
            <div class="cell label">
                Cherries:
            </div>
            <div class="cell">
                <input type="number" name="cherries" value="20">                
            </div>
        </div>
        <div class="row">
            <div class="cell label">Total:</div>
            <div id="results" class="cell">0 items</div>
        </div>
    </div>
    <button id="submit" type="submit">Submit Form</button>
</form>

手动收集和发送数据:

<script>
    // 给提交按钮添加点击事件,并阻止其默认事件
    document.getElementById("submit").onclick = ajaxSubmit;
    var xhr;  // 全局xhr对象

    // onclick处理程序
    function ajaxSubmit(e){
        e.preventDefault(); // 阻止“提交按钮”的默认事件
        // 手动收集表单数据
        var formData = "";
        var oForm = document.getElementById("fruitform");
        var oInput = document.querySelectorAll("#fruitform input");
        for(var i=0; i<oInput.length; i++){
            formData += oInput[i].name + "=" + oInput[i].value + "&";
        }

        // 创建Ajax
        xhr = new XMLHttpRequest();
        xhr.onreadystatechange = handResult;
        xhr.open("POST",oForm.action);
        xhr.setRequestHeader("Content-Tyep", "application/x-www-form-urlencoded");
        xhr.send(formData);
    }

    // 处理返回的数据结果
    function handResult(e){
        if(xhr.readyState==4 && xhr.status==200){
            document.getElementById("result").innerHTML = xhr.responseText;
        }
    }
</script>

Ajax发送文件:

<form action="" id="fileAjax">
    <input type="file" name="file1">
    <input type="file" name="file2">
    <button type="submit" id="subfile">提交文件至服务器</button>
</form>
<script>
    document.getElementById("subfile").onclick = handFile;
    var xhr1;

    function handFile(e){
        e.preventDefault();

        var oForm1 = document.getElementById("fileAjax");
        var formData1 = new FormData(oForm1);

        xhr1 = new XMLHttpRequest();
        xhr1.onreadystatechange = handRes1;
        xhr1.open("POST",oForm1.action);
        xhr1.send(formData1);
    }

    function handRes1(e){
        if(xhr1.readyState==4 && xhr1.status=200){
            console.log(xhr1.responseText);
        }
    }
</script>

实时监控Ajax上传进度:

<form action="" id="proAjax">
    <input type="file" name="file3">
    <button type="submit" id="prosub">提交</button>
</form>
<progress id="prog" value="0.5"></progress>
<script>
    document.getElementById("prosub").onclick = handPro;
    var xhr2;
    var prog = document.getElementById("prog");
    var oForm2 = document.getElementById("proAjax");
    function handPro(e){
        e.preventDefault();

        var formData2 = new FormData(oForm2);
        xhr2 = new XMLHttpRequest();
        xhr2.onreadystatechange = handRes2;
        xhr2.open("POST",oForm2.action);
        xhr2.send(formData2);

        var upload = xhr2.upload;
        upload.onprogress = function(e){
            prog.value = e.loaded;
            prog.max = e.total;
        }
        upload.onload = function(e){
            prog.value = 1;
            prog.max = 1;
        }
    }
    function handRes2(e){
        if(xhr2.readyState==4 && xhr2.status==200){
            console.log(xhr2.responseText);
        }
    }
</script>

三十四、使用多媒体

使用video元素:

<video src="images/timessquare.webm" width="360" height="240" autoplay controls preload="none" muted="">
    您的浏览不支持video,请更新你的浏览器版本。
</video>

视频的预加载方式:

<video src="images/timessquare.webm" width="360" height="240" controls muted preload="metadata">
    您的浏览不支持video,请更新你的浏览器版本。
</video>
<video src="images/timessquare.webm" width="360" height="240" controls muted preload="auto">
    您的浏览不支持video,请更新你的浏览器版本。
</video>

视频的点位图片:

<video src="images/timessquare.webm" width="360" height="240" controls preload="none" poster="images/poster.png">
    您的浏览不支持video,请更新你的浏览器版本。
</video>

<img src="images/poster.png" alt="" width="360" height="230">

<video src="images/timessquare.webm" width="800" height="240" controls></video>

指定视频格式:

<video controls width="360" height="240">
    您的浏览不支持video,请更新你的浏览器版本。
    <source src="images/timessquare.mp4" type="video/mp4">
    <source src="images/timessquare.webm" type="video/webm">
    <source src="images/timessquare.ogv" type="video/ogv">
</video>

音频:

<audio controls autoplay>
    <source src="images/music.mp3">
    您的浏览不支持audio,请更新你的浏览器版本。
</audio>

DOM操作多媒体,获取媒体信息:

<video controls width="360" height="240" preload="metadata" id="media1">
    <source src="images/timessquare.webm" type="video/webm">
    <source src="images/timessquare.mp4" type="video/mp4">
    不支持啊,请更新浏览器!
</video>
<table id="info" border="1">
    <tr>
        <th>Property</th>
        <th>Value</th>
    </tr>
</table>
<script>
    var oVideo = document.getElementById("media1");
    var oInfo = document.getElementById("info");

    var proplist = ["autoplay","currentSrc","controls","loop","muted","preload","src","volume"];
    for(var i=0;i<proplist.length;i++){
        oInfo.innerHTML += "<tr><td>"+proplist[i]+"</td><td>"+oVideo[proplist[i]]+"</td></tr>";
    }
</script>

评估浏览器的支持能力:

<video id="media2" controls width="360" height="240" preload="metadata">
    不支持,请更新浏览器版本。
</video>
<table id="info2" border="1">
    <tr>
        <th>property</th>
        <th>value</th>
    </tr>
</table>
<script>
    var oVideo2 = document.getElementById("media2");
    var oInfo2 = document.getElementById("info2");

    var mediaFiles = ["timessquare.webm","timessquare.ogv","timessquare.mp4"];
    var mediaTypes = ["video/webm","video/ogv","video/mp4"];

    oVideo2.poster = "images/poster.png";
    oVideo2.src = "./timessquare.webm";
    for(var i=0;i<mediaTypes.length; i++){
        var flag = oVideo2.canPlayType(mediaTypes[i]);
        if(!flag){
            flag = "no";
        }
        oInfo2.innerHTML += "<tr><td>"+mediaTypes[i]+"</td><td>"+flag+"</td></tr>";
    }
</script>

控制媒体的播放:

<video src="images/timessquare.webm" id="video3" autoplay preload="metadata" controls width="400" height="280">
    您的浏览器不支持,请更新浏览器版本。
</video>
<button id="press">控制媒体播放</button>
<table id="info3" border="1">
    <tr>
        <th>属性</th>
        <th>值</th>
    </tr>
</table>
<script>
    var oVideo3 = document.getElementById("video3");
    var oInfo3 = document.getElementById("info3");

    document.getElementById("press").onclick = handMedia;
    var pro = ["currentTime","duration","paused","ended"];

    function handMedia(e){
        oInfo3.innerHTML = "<tr><th>属性</th><th>值</th></tr>";
        for(var i=0; i<pro.length;i++){
            oInfo3.innerHTML += "<tr><td>"+pro[i]+"</td><td>"+oVideo3[pro[i]]+"</td></tr>";
        }
    }
</script>

替换默认的媒体控制条:

<video src="images/timessquare.webm" id="media4" preload="auto" width="400" height="280">
    哈哈,不支持
</video>
<button id="play" class="btns">播放</button>
<button id="pause" class="btns">暂停</button>
<script>
    var oVideo4 = document.getElementById("media4");
    var btns = document.querySelectorAll(".btns");

    for(var i=0;i<btns.length;i++){
        btns[i].onclick = handle;
    }
    function handle(e){
        if(e.target.id == "play"){
            oVideo4.play();
        }else {
            oVideo4.pause();
        }
    }
</script>

三十五、使用Canvas(上)

<canvas width="500" height="200" id="can1">
    你的浏览不支持canvas,请升级浏览器。
</canvas>
<script>
    var ctx = document.getElementById("can1").getContext("2d");
    ctx.fillRect(10,10,50,50);
</script>

绘制矩形:

<script>
    var ctx2 = document.getElementById("can2").getContext("2d");
    var offset = 10;
    var size = 50;
    var count = 5;
    draw2();

    function draw2(){
        for(var i=0; i<count; i++){
            ctx2.fillRect(i*(offset+size)+offset, offset, size, size);
            ctx2.strokeRect(i*(offset+size)+offset, (2*offset)+size, size,size);
        }
    }
</script>

擦除矩形区域:

<script>
    clear1();
    function clear1(){
        for(var i=0; i<5; i++){
            ctx2.clearRect(i*60+10, 15, 50, 40);
        }
    }
</script>

绘制的线宽:

<script>
    var ctx3 = document.getElementById("can3").getContext("2d");

    ctx3.lineWidth = 2;
    ctx3.strokeRect(10,10,50,50);

    ctx3.lineWidth = 4;
    ctx3.strokeRect(70,10,50,50);

    ctx3.lineWidth = 10;
    ctx3.strokeRect(130,10,50,50);
    ctx3.strokeRect(200,10,50,50);
</script>

设置线条的连接样式:

<script>
    var ctx4 = document.getElementById("can4").getContext("2d");
    ctx4.lineWidth = 30;

    ctx4.lineJoin = "round";
    ctx4.strokeRect(20,20,100,100);

    ctx4.lineJoin = "bevel";
    ctx4.strokeRect(160,20,100,100);

    ctx4.lineJoin = "miter";
    ctx4.strokeRect(300,20,100,100);
</script>

设置填充色、笔触色:

<script>
    var ctx5 = document.getElementById("can5").getContext("2d");
    var color1 = ["black","grey","lightgray","red","blue"];
    var color2 = ["rgb(0,0,0)","rgb(100,100,100)","rgb(200,200,200)","rgb(255,0,0)","rgb(0,0,255)"];
    draw5();
    function draw5(){
        for(var i=0; i<5; i++){
            ctx5.fillStyle = color1[i];
            ctx5.fillRect(10+i*60,10,50,50);
            ctx5.strokeStyle = color2[i];
            ctx5.strokeRect(10+i*60,70,50,50);
        }
    }
</script>

渐变色填充:

<script>
    var ctx6 = document.getElementById("can6").getContext("2d");

    // 创建渐变色
    var grad1 = ctx6.createLinearGradient(0,0,500,200);
    grad1.addColorStop(0,"red");
    grad1.addColorStop(0.5,"rgb(233,233,233)");
    grad1.addColorStop(1,"blue");

    ctx6.fillStyle = grad1;
    ctx6.fillRect(0,0,500,200);
</script>

渐变色区域和图形区域的大小不一致时:

<script>
    var cxt7 = document.getElementById("can7").getContext("2d");
    var grad2 = cxt7.createLinearGradient(10,10,60,60);
    grad2.addColorStop(0,"red");
    grad2.addColorStop(0.5,"rgb(233,233,233)");
    grad2.addColorStop(1,"blue");
    cxt7.fillStyle = grad2;
    cxt7.fillRect(10,10,150,150);
</script>

径向渐变:

<script>
    var ctx8 = document.getElementById("can8").getContext("2d");
    var grad3 = ctx8.createRadialGradient(250,70,20,200,60,100);
    grad3.addColorStop(0,"red");
    grad3.addColorStop(0.5,"white");
    grad3.addColorStop(1,"blue");

    ctx8.fillStyle = grad3;
    ctx8.fillRect(0,0,500,200);
</script>

径向渐变色区域和图形区域不一致时:

<script>
    var ctx9 = document.getElementById("can9").getContext("2d");
    var grad4 = ctx9.createRadialGradient(250,70,20,200,60,100);
    grad4.addColorStop(0,"red");
    grad4.addColorStop(0.5,"white");
    grad4.addColorStop(1,"blue");

    ctx9.fillStyle = grad4;
    ctx9.fillRect(150,20,75,50);

    ctx9.strokeStyle = grad4;
    ctx9.lineWidth = 10;
    ctx9.strokeRect(250,20,75,50);
</script>

图案填充:

 <img src="images/banana.png" alt="" hidden  id="imgsrc">
 <script>
    var ctx10 = document.getElementById("can10").getContext("2d");
    // var oImg = new Image();
    // oImg.src = "images/banana.png";
    // oImg.style.display = "none"; // 让图片不显示
    var oImg = document.getElementById("imgsrc");
    var pattern = ctx10.createPattern(oImg,"repeat");

    ctx10.fillStyle = pattern;
    ctx10.fillRect(20,20,100,100);
 </script>

保存和恢复绘制状态:

<button class="btns">保存</button>
<button class="btns">恢复</button>
<script>
    var ctx11 = document.getElementById("can11").getContext("2d");

    // 创建一个渐变色
    var grad11 = ctx11.createLinearGradient(500,0,500,200);
    grad11.addColorStop(0,"red");
    grad11.addColorStop(0.5,'white');
    grad11.addColorStop(1,"blue");

    var colors = ['black',grad11,'yellow','red','green','grey'];

    var cIndex = 0;
    var btns = document.querySelectorAll(".btns");

    // 初始状态
    ctx11.fillStyle = colors[cIndex];
    draw11();

    for(var i=0; i<btns.length;i++){
        btns[i].onclick = handlePress;
    }

    function handlePress(e){
        switch (e.target.innerHTML) {
            case "保存":
                ctx11.save();
                cIndex = (cIndex+1) % colors.length;
                ctx11.fillStyle = colors[cIndex];
                draw11();
                break;
            case "恢复":
                cIndex = Math.max(0,cIndex-1);
                ctx11.restore();
                draw11();
                break;
        }
    }

    function draw11(){
        ctx11.fillRect(0,0,500,200);
    }
</script>

绘制图像:

<img src="images/banana.png" alt="" hidden id="img12" width="50">
<script>
    var ctx12 = document.getElementById("can12").getContext("2d");
    var oImg12 = document.getElementById("img12");
    ctx12.drawImage(oImg12,0,0);
    ctx12.drawImage(oImg12,120,10,100,120);
    ctx12.drawImage(oImg12,20,20,100,50,250,10,100,120);
</script>

绘制视频图像:

<video src="images/timessquare.webm" id="vid" controls preload width="360" height="240">
    不支持视频,请更新浏览器!
</video>
<button id="draw13">绘制视频图像</button>
<script>
    var ctx13 = document.getElementById("can13").getContext("2d");
    document.getElementById("draw13").onclick = handVideo;
    function handVideo(e){
        var oV = document.getElementById("vid");
        ctx13.drawImage(oV,0,0,360,240);
    }
</script>

用canvas播放视频:

<canvas id="can14" width="360" height="240">不支持</canvas>
<button id="draw14">播放视频</button>
<script>
    var oVideo = document.getElementById("vid");
    var ctx14 = document.getElementById("can14").getContext("2d");
    document.getElementById("draw14").onclick = playVideo;
    var flag = true;
    var w = 100; 
    var h = 10;
    ctx14.lineWidth = 5;
    ctx14.strokeStyle = "red";
    var timer1,timer2;
    function playVideo(e){
        clearInterval(timer1);
        clearInterval(timer2);
        if(flag){
            oVideo.play();
            flag = false;
            timer1 = setInterval(function(){
                ctx14.drawImage(oVideo,0,0,360,240);
                ctx14.strokeRect(180-(w/2), 120-(h/2), w, h);
            }, 50); 
            timer2 = setInterval(function(){
                w = (w+1) % 200;
                h = (h+3) % 200;
            },25);
        }else {
            oVideo.pause();
            clearInterval(timer2);
            flag = true;
        }   
    }
</script>

绘制canvas图像:

<button id="draw15">绘制canvas</button>
<canvas id="can15" width="360" height="240">不支持时</canvas>
<script>
    var oCan = document.getElementById("can14");
    var ctx15 = document.getElementById("can15").getContext("2d");
    document.getElementById("draw15").onclick = drawCanvas;
    function drawCanvas(e){
        setInterval(function(){
            ctx15.drawImage(oCan,30,20,300,200);
        },50);
    }
</script>

三十六、使用Canvas(下)

由直线创建路径:

<script>
    var ctx1 = document.getElementById("c1").getContext("2d");

    ctx1.fillStyle = "yellow";
    ctx1.strokeStyle = "black";
    ctx1.lineWidth = 5;

    ctx1.beginPath();
    ctx1.moveTo(10,10);
    ctx1.lineTo(110,10);
    ctx1.lineTo(110,120);
    ctx1.closePath();
    ctx1.fill();
    ctx1.stroke();

    ctx1.beginPath();
    ctx1.moveTo(150,10);
    ctx1.lineTo(200,10);
    ctx1.lineTo(200,120);
    ctx1.lineTo(170,120);
    ctx1.fill();
    ctx1.stroke();

    ctx1.beginPath();
    ctx1.moveTo(250,10);
    ctx1.lineTo(250,120);
    ctx1.stroke();
</script>

使用 lineGap属性:

<script>
    var ctx2 = document.getElementById("c2").getContext("2d");
    ctx2.strokeStyle = "red";
    ctx2.lineWidth = 5;

    ctx2.beginPath();
    ctx2.moveTo(0,50);
    ctx2.lineTo(200,50);
    ctx2.stroke();

    ctx2.strokeStyle= "black";
    ctx2.lineWidth = 40;

    var xpos = 50;
    var styles = ["butt","round","square"];
    for(var i=0; i<styles.length; i++){
        ctx2.beginPath();
        ctx2.lineGap = styles[i];
        ctx2.moveTo(xpos,50);
        ctx2.lineTo(xpos,150);
        ctx2.stroke();
        xpos+=50;
    }
</script>

用rect方法绘制矩形子路径:

<script>
    var ctx3 = document.getElementById("c3").getContext("2d");

    ctx3.fillStyle= "yellow";
    ctx3.strokeStyle = "black";
    ctx3.lineWidth = 5;

    ctx3.beginPath();
    ctx3.moveTo(110,10);
    ctx3.lineTo(110,100);
    ctx3.lineTo(10,10);
    ctx3.closePath();

    ctx3.rect(110,10,100,90);
    ctx3.rect(110,100,130,30);

    ctx3.fill();
    ctx3.stroke();
</script>

使用分离的子路径:

<script>
    var ctx4 = document.getElementById("c4").getContext("2d");

    ctx4.fillStyle = "red";
    ctx4.strokeStyle = "black";
    ctx4.lineWidth = 5;

    ctx4.beginPath();
    ctx4.moveTo(110,10);
    ctx4.lineTo(110,100);
    ctx4.lineTo(10,10);
    ctx4.closePath();

    ctx4.rect(120,10,100,90);
    ctx4.rect(150,110,130,20);

    ctx4.fill();
    ctx4.stroke();
</script>

使用arcTo()绘制圆弧:

<script>
    var ctx5 = document.getElementById("c5").getContext("2d");

    var point1 = [100,10];
    var point2 = [200,10];
    var point3 = [200,110];

    ctx5.fillStyle= "red";
    ctx5.strokeStyle= "black";
    ctx5.lineWidth = 4;

    ctx5.beginPath();
    ctx5.moveTo(point1[0],point1[1]);
    ctx5.arcTo(point2[0],point2[1],point3[0],point3[1],100);
    ctx5.stroke();

    drawPoint(point1[0],point1[1]);
    drawPoint(point2[0],point2[1]);
    drawPoint(point3[0],point3[1]);

    ctx5.beginPath();
    ctx5.moveTo(point1[0],point1[1]);
    ctx5.lineTo(point2[0],point2[1]);
    ctx5.lineTo(point3[0],point3[1]);
    ctx5.stroke();

    function drawPoint(x,y){
        ctx5.lineWidth = 1;
        ctx5.strokeStyle = "red";
        ctx5.strokeRect(x-2,y-2,4,4);
    }
</script>

canvas响应鼠标事件:

<script>
    var oC6 = document.getElementById("c6");
    var ctx6 = oC6.getContext("2d");
    var p1 = [100,10];
    var p2 = [200,10];
    var p3 = [200,110];

    draw6();

    oC6.onmousemove = function(e){
        if(e.ctrlKey){
            p1 = [e.clientX, e.clientY];
        }else if(e.shiftKey){
            p2 = [e.clientX, e.clientY];
        }else {
            p3 = [e.clientX, e.clientY];
        }
        ctx6.clearRect(0,0,500,200);
        draw6();
    }

    function draw6(){
        ctx6.fillStyle = "yellow";
        ctx6.strokeStyle = "black";
        ctx6.lineWidth = 4;

        ctx6.beginPath();
        ctx6.moveTo(p1[0],p1[1]);
        ctx6.arcTo(p2[0],p2[1],p3[0],p3[1],50);
        ctx6.stroke();

        drawP(p1[0],p1[1]);
        drawP(p2[0],p2[1]);
        drawP(p3[0],p3[1]);

        ctx6.beginPath();
        ctx6.moveTo(p1[0],p1[1]);
        ctx6.lineTo(p2[0],p2[1]);
        ctx6.lineTo(p3[0],p3[1]);
        ctx6.stroke();
    }
    function drawP(x,y){
        ctx6.lineWidth = 1;
        ctx6.strokeStyle = "red";
        ctx6.strokeRect(x-2,y-2,4,4);
    }
</script>

使用arc方法,绘制圆弧:

<script>
    var ctx7 = document.getElementById("c7").getContext("2d");
    ctx7.fillStyle = "yellow";
    ctx7.lineWidth = 4;

    ctx7.beginPath();
    ctx7.arc(70,70,60,0,Math.PI*2,true);
    ctx7.stroke();

    ctx7.beginPath();
    ctx7.arc(200,70,60,Math.PI/2,Math.PI,true);
    ctx7.fill();
    ctx7.stroke();

    ctx7.beginPath();
    var val=0;
    for(var i=0;i<4;i++){
        ctx7.arc(350,70,60,val,val+Math.PI/4,false);
        val+=Math.PI/2;
    }
    ctx7.closePath();
    ctx7.fill();
    ctx7.stroke();
</script>

绘制贝塞尔曲线:

<script>
    var ctx8 = document.getElementById("c8").getContext("2d");
    ctx8.strokeStyle = "red";
    ctx8.beginPath();
    ctx8.bezierCurveTo(250,50,350,50,400,100);
    ctx8.stroke();

    ctx8.beginPath();
    ctx8.quadraticCurveTo(120,350,350,400);
    ctx8.closePath();
    ctx8.stroke();
    ctx8.fill();
</script>

创建剪切区域:

<script>
    var ctx9 = document.getElementById("c9").getContext("2d");
    ctx9.fillStyle = "red";
    ctx9.beginPath();
    ctx9.rect(0,0,500,200);
    ctx9.fill();

    ctx9.beginPath();
    ctx9.rect(50,50,300,50);
    ctx9.clip();

    ctx9.fillStyle = "green";
    ctx9.beginPath();
    ctx9.rect(0,0,500,200);
    ctx9.fill();
</script>

绘制文本:

<script>
    var ctx10 = document.getElementById("c10").getContext("2d");
    ctx10.fillStyle = "red";
    ctx10.strokeStyle = "blue";
    ctx10.lineWidth = 3;
    ctx10.font = "100px sans-serif";

    ctx10.shadowOffsetX = 5; // 阴影
    ctx10.shadowOffsetY = 5;
    ctx10.shadowBlur = 5;
    ctx10.shadowColor = "black";

    ctx10.globalAlpha = 0.5; //透明度

    ctx10.fillText("Hello World",50,100);
    ctx10.strokeText("Hello World",50,100);
    ctx10.fillRect(50,150,500,20);
</script>

使用globalCompositeOperation:

<canvas id="c11" width="500" height="300" style="border:1px solid red;">不支持</canvas>
<label for="">Composition Value:</label>
<select name="" id="list">
    <option>copy</option>
    <option>destination-atop</option>
    <option>destination-in</option>
    <option>destination-over</option>
    <option>destination-out</option>
    <option>lighter</option>
    <option>source-atop</option>
    <option>source-in</option>
    <option>source-out</option>
    <option>source-over</option>
    <option>xor</option>
</select>
<script>
    var ctx11 = document.getElementById("c11").getContext("2d");
    ctx11.fillStyle = "lightgrey";
    ctx11.strokeStyle = "black";
    ctx11.lineWidth = 3;

    var comVal = "copy";
    document.getElementById("list").onchange = function(e){
        comVal = e.target.value;
        draw11();
    }
    function draw11(){
        ctx11.clearRect(0,0,500,300);
        ctx11.globalAlpha = 0.8;
        ctx11.font = "80px sans-serif";
        ctx11.fillText("夏海峰",10,100);
        ctx11.strokeText("夏海峰",10,100);

        ctx11.globalCompositeOperation = comVal;
        ctx11.fillStyle = "red";
        ctx11.globalAlpha = 0.5;
        ctx11.fillRect(100,10,150,100);
    }
</script>

变换:

<script>
    var ctx12 = document.getElementById("c12").getContext("2d");
    ctx12.fillStyle = "red";
    ctx12.strokeStyle = "blue";
    ctx12.lineWidth = 3;

    ctx12.clearRect(0,0,300,150);
    ctx12.globalAlpha = 1.0;
    ctx12.font = "100px sans-serif";
    ctx12.fillText("轩轩",10,100);
    ctx12.strokeText("轩轩",10,100);

    ctx12.scale(1.3, 1);
    ctx12.translate(100, -50);
    ctx12.rotate(0.5);

    ctx12.fillStyle = "green";
    ctx12.globalAlpha = 0.5;
    ctx12.fillRect(100,10, 150,100);
    ctx12.strokeRect(0,0,300,200);
</script>

三十七、拖放

<head>
    <style>
        #src > * {float:left;}
        #target , #src img {
            border:thin solid black;
            padding: 2px;
            margin:4px;
            width:100px;
            height: 100px;
        }
        #target {
            height: 100px; width:100px;
            text-align: center;
            display: table;
        }
        #target p {
            display: table-cell;
            vertical-align:middle;
        }
        #target img {margin: 1px;}
        img.dragged {background-color: grey;}
    </style>
</head>

定义可拖拽项目:

<div id="src">
    <img src="images/banana.png" alt="1" id="banana" draggable="true">
    <img src="images/apple.png" alt="1" id="apple" draggable="true">
    <div id="target">
        <p id="msg">Drop Here.</p>
    </div>
</div>
<div style="clear: both;"></div>
<script>
    var src = document.getElementById("src");
    var tar = document.getElementById("target");
    var msg = document.getElementById("msg");

    var dragID;

    //拖动事件
    src.ondragstart = function(e){
        dragID= e.target.id;
        e.target.classList.add("dragged");
    }
    src.ondragend = function(e){
        var elems = document.querySelectorAll(".dragged");
        for(var i=0; i<elems.length; i++){
            elems[i].classList.remove("dragged");
        }
    }
    src.ondrag = function(e){
        msg.innerHTML = "正在拖放"+e.target.id;
    }

    //释放区域的事件
    tar.ondragenter = handDrag;
    tar.ondragover = handDrag;
    function handDrag(e){
        e.preventDefault();
    }
    // drop事件
    tar.ondrop = function(e){
        var newEle = document.getElementById(dragID).cloneNode(false);
        tar.innerHTML = "";
        tar.appendChild(newEle);
        e.preventDefault();
    }
</script>

使用DataTransfer对象,传递数据:

<div id="box1" style="width: 150px; height: 150px;">
    <img src="images/apple.png" alt="1" id="app" width="100" draggable='true'>
</div>
<div id="zoom" style="width: 150px;height: 150px;border:1px solid red;text-align: center;">
    释放区域
</div>
<script>
    var box1 = document.getElementById("box1");
    var zoom = document.getElementById("zoom");
    var cloneId;

    zoom.ondragenter = handle;
    zoom.ondragover = handle;

    function handle(e){
        e.preventDefault();
    }

    box1.ondragstart = function(e){
        cloneId = e.target.id;
        e.dataTransfer.setData("Text","夏海峰");
    }
    box1.ondragend = function(e){
        console.log("拖放已结束");
    }
    zoom.ondrop = function(e){
        e.preventDefault();
        var data = e.dataTransfer.getData("Text");
        var newEle = document.getElementById(cloneId).cloneNode(false);
        zoom.innerHTML = "";
        zoom.appendChild(newEle);
        console.log(data);
    }
</script>

拖放文件:

<div id="box2">
    <p id="msgs">Drop Files Here.</p>
</div>
<table id="datas" border="1"></table>
<script>
    var box2 = document.getElementById("box2");
    box2.ondragenter = hand1;
    box2.ondragover = hand1;
    function hand1(e){
        e.preventDefault();
    }
    box2.ondrop = function(e){
        var files = e.dataTransfer.files;
        var tabEle = document.getElementById("datas");
        tabEle.innerHTML = "<tr><th>Name</th><th>Type</th><th>Size</th></tr>";
        for(var i=0;i<files.length; i++){
            var row = "<tr><td>"+files[i].name+"</td><td>"+files[i].type+"</td><td>"+files[i].size+"</td></tr>";
            tabEle.innerHTML += row;
        }
        e.preventDefault();
    }
</script>

在表单中接受被拖放的文件:

<form action="" id="forms" method="post">
    <div class="table">
        <div class="row">
            <div class="cell label">Banana:</div>
            <div class="cell"><input type="text" name="banana" value="2"></div>
        </div>
        <div class="row">
            <div class="cell label">Apple:</div>
            <div class="cell"><input type="text" name="apple" value="5"></div>
        </div>
        <div class="row">
            <div class="cell label">Cherries:</div>
            <div class="cell"><input type="text" name="cherries" value="20"></div>
        </div>
        <div class="row">
            <div class="cell label">Files:</div>
            <div class="cell"><input type="text" name="files"></div>
        </div>
        <div class="row">
            <div class="cell label">Total:</div>
            <div class="cell">0 items</div>
        </div>
    </div>
    <div id="zom"><p id="ms">Drop Here.</p></div>
    <button type="submit" id="sub">提交表单</button>
</form>
<script>
    // ondrop事件中接受文件
    // 收集表单数据
    // Ajax提交数据

    var zom = document.getElementById("zom");
    var oForm = document.getElementById("forms");
    var oSub = document.getElementById("sub");
    var xhr;

    zom.ondragenter = hand3;
    zom.ondragover = hand3;
    function hand3(e){
        e.preventDefault();
    }
    // 收集表单数据
    var dataForm = new DataForm(oForm);
    zom.ondrop = function(e){
        var fis = e.dataTransfer.files;
        for(var i=0;i<fis.length; i++){
            dataForm.append("file"+i, fis[i]);
        }
        e.preventDefault(); 
    }
    // Ajax提交数据
    oSub.onclick = function(e){
        e.preventDefault();
        xhr = new XMLHttpRequest();     
        xhr.onreadystatechange = handRes;
        xhr.open("POST",oForm.action);
        xhr.send(dataForm);
    }
    // 处理响应
    function handRes(e){
        if(xhr.readyState==4 && xhr.status==200){
            console.log(xhr.responseText);
        }
    }
</script>

三十八、地理定位

使用地理定位:

<table id="tab1" border="1">
    <tr>
        <th>Longitude:</th><td id="longitude">-</td>
        <th>Latitude:</th><td id="latitude">-</td>
    </tr>
    <tr>
        <th>Altitued:</th><td id="altitued">-</td>
        <th>Accuracy:</th><td id="accuracy">-</td>
    </tr>
    <tr>
        <th>Altitude Accuracy:</th><td id="altitudeAccuracy">-</td>
        <th>Heading:</th><td id="heading">-</td>
    </tr>
    <tr>
        <th>Speed:</th><td id="speed">-</td>
        <th>Time Stamp:</th><td id="timestamp">-</td>
    </tr>
    <tr>
        <th>Error Code:</th><td id="errcode">-</td>
        <th>Error Message:</th><td id="errmessage">-</td>
    </tr>
</table>
<button id="cancle">取消监控</button>
<script>
    //设置获取定位的控制条件
    var options = {
        enableHighAccuracy:false,
        timeout:2000,
        maximumAge:3000
    }
    //获取当前位置信息
    var watchID = navigator.geolocation.getCurrentPosition(disPosition, handleErr, options);

    //监控定位
    navigator.geolocation.watchPosition(disPosition,handleErr,options);

    //获取定位成功时的回调函数
    function disPosition(pos){
        var pro = ["longitude","latitude","altitude","accuracy","altitudeAccuracy","heading","speed"];
        for(var i=0; i<pro.length; i++){
            var value = pos.coords[pro[i]];
            document.getElementById(pro[i]).innerHTML = value;
        }
        document.getElementById("timestamp").innerHTML = "111";
    }
    //获取定位失败时的回调函数
    function handleErr(e){
        document.getElementById("errcode").innerHTML = e.code;
        document.getElementById("errmessage").innerHTML = e.message;
    }

    //取消监控
    document.getElementById("cancle").onclick = function(e){
        navigator.geolocation.clearWatch(watchID);
    }
</script>

三十九、Web存储

本地存储:

<div id="box1">
    <div>
        <label for="">Key:</label>
        <input type="text" id="key" placeholder="Enter key">
    </div>
    <div>
        <label for="">Value:</label>
        <input type="text" id="value" placeholder="Enter value">
    </div>
    <div id="btns">
        <button id="add">Add</button>
        <button id="clear">Clear</button>
    </div>
    <p id="countmsg">There are <span id="count"> </span> items.</p>
</div>
<table id="data" border="1">
    <tr>
        <th>Item Count:</th>
        <td id="count">-</td>
    </tr>
</table>
<script>
    displayData();

    var btns = document.querySelectorAll("#btns button");
    for(var i=0; i<btns.length; i++){
        btns[i].onclick = handBtn;
    }

    function handBtn(e){
        switch (e.target.id) {
            case "add":
                var key = document.getElementById("key").value;
                var value = document.getElementById("value").value;
                localStorage.setItem(key,value);
                break;
            case "clear":
                localStorage.clear();
                break;
        }
        displayData();
    }
    function displayData(){
        var tab = document.getElementById("data");
        tab.innerHTML = "<tr><th>Item Count:</th><td id='count'>-</td></tr>";
        var itemCount = localStorage.length;
        document.getElementById("count").innerHTML = itemCount;
        for(var i=0; i<itemCount; i++){
            var key = localStorage.key[i];
            var val = localStorage[key];
            tab.innerHTML += "<tr><th>"+key+"</th><td>"+val+"</td></tr>";
        }
    }
</script>

监听onstorage事件:

<table id="eve" border="1">
    <tr>
        <th>key</th>
        <th>oldValue</th>
        <th>newValue</th>
        <th>url</th>
        <th>storageArea</th>
    </tr>
</table>
<script>
    var eveTab = document.getElementById("eve");
    window.onstorage = handStorChange;
    function handStorChange(e){
        eveTab.innerHTML += "<tr><td>"+e.key+"</td><td>"+e.oldValue+"</td><td>"+e.newValue+"</td><td>"+e.url+"</td><td>"+e.storageArea+"</td></tr>";
    }
</script>

会话存储:

<form action="" id="ses">
    <input type="text" id="key1" placeholder="输入键">
    <input type="text" id="value1" placeholder="输入值">
</form><br>
<div id="box">
    <button id="btn1">存储</button>
    <button id="btn2">清除</button>
</div>
<p id="sesmsg"></p>
<script>
    var bts = document.querySelectorAll("#box button");
    for(var i=0; i<bts.length; i++){
        bts[i].onclick = handSes;
    }
    dispalyMsg();

    function handSes(e){
        switch (e.target.id) {
            case "btn1":
                var key2 = document.getElementById("key1").value;
                var val2 = document.getElementById("value1").value;
                if(key2 != ""){
                    sessionStorage.setItem(key2,val2);
                }               
                break;
            case "btn2":
                sessionStorage.clear();
                break;
        }
        dispalyMsg();
    }
    function dispalyMsg(){
        var oP = document.getElementById("sesmsg");
        oP.innerHTML = "有 "+sessionStorage.length+" 条数据。<br />";
        var len = sessionStorage.length;
        for(var i=0; i<len; i++){
            var keys = sessionStorage.key(i);
            oP.innerHTML += "第 "+(i+1)+" 条数据的键是:"+keys+" 。 ";
            oP.innerHTML += "第 "+(i+1)+" 条数据的值是:"+sessionStorage[keys]+" 。<br />"
        }
    }
</script>

onstorage事件:

<button id="do">操作sessionStorage,监听事件</button>
<script>
    var oDo = document.getElementById("do");
    oDo.onclick = function(e){
        var rad = Math.floor(Math.random()*100000);
        sessionStorage.setItem("item"+rad, "values"+rad);
    }
    window.onstorage = function(e){
        alert(e.key);
    }
</script>

四十、离线Web应用

定义问题:

<img src="images/banana100.png" alt="1" id="imgs">
<div id="btns">
    <button id="banana">banana</button>
    <button id="apple">apple</button>
    <button id="cherries">cherries</button>
</div>
<script>
    var btns = document.querySelectorAll("#btns button");
    var oImg = document.getElementById("imgs");
    for(var i=0; i<btns.length; i++){
        btns[i].onclick = function(e){
            oImg.src = "images/"+e.target.id + "100.png";
        }
    }
</script>

检测浏览器是否离线:

<p id="res1">您的浏览器处于 <span id="res2"></span>!</p>
<script>
    var status;
    if(window.navigator.onLine){
        status = "在线状态";
    }else {
        status = "离线状态";
    }
    document.getElementById("res2").innerHTML = status;
</script>

直接使用应用程序缓存:

<div id="box">
    <img src="images/banana100.png" alt="1" id="target">
    <div>
        <button id="ban">banana</button>
        <button id="app">apple</button>
        <button id="che">cherries</button>
    </div>
    <div>
        <button id="update">更新缓存</button>
        <button id="swap">交换缓存</button>
    </div>
    <p id="stu">当前缓存的状态是 <span id="status"></span></p>
</div>
<table id="eventtable" border="1">
    <tr><th>事件类型</th></tr>
</table>
<script>
    var oBtn = document.querySelectorAll("#box button");
    var img1 = document.getElementById("target");
    for(var i=0;i<oBtn.length;i++){
        oBtn[i].onclick = handPress;
    }

    function handPress(e){
        switch (e.target.id) {
            case "swap":
                window.applicationCache.swapCache();
                break;
            case "update":
                window.applicationCache.update();
                checkStatus();
                break;
            default:
                img1.src = "images/"+e.target.innerHTML + "100.png";
                break;
        }
    }

    // 添加缓存事件
    window.applicationCache.onchecking = handEvent;
    window.applicationCache.onnoupdate = handEvent;
    window.applicationCache.ondownloading = handEvent;
    window.applicationCache.onupdateready = handEvent;
    window.applicationCache.oncached = handEvent;
    window.applicationCache.onobselete = handEvent;

    function handEvent(e){
        document.getElementById("eventtable").innerHTML += "<tr><td>"+e.type+"</td></tr>";
        checkStatus();
    }

    function checkStatus(){
        var stusName = ["UNCACHE","IDLE","CHECKING","DOWNLOADING","UPDATEREADY","OBSOLETE"];
        var stus = window.applicationCache.status;
        document.getElementById("status").innerHTML = stusName[stus];
    }
</script>

第五部分 结束!!!
上一篇 下一篇

猜你喜欢

热点阅读