(第三天)HTML5之Range對(duì)象(下)葡公、Audio罐农、Video、拖放催什、Canvas標(biāo)簽

Range對(duì)象的方法


Range對(duì)象之cloneRange涵亏、cloneContents、extractContents方法
  • cloneRange():克隆并返回一個(gè)Range對(duì)象蒲凶,非Node類(lèi)型气筋,無(wú)法添加到其他節(jié)點(diǎn)中;
  • cloneContents():克隆Range對(duì)象下的所有子節(jié)點(diǎn)旋圆,并返回一個(gè)DocumentFragment對(duì)象宠默;
  • extractContents():提取所有子節(jié)點(diǎn),并返回一個(gè)DocumentFragment對(duì)象灵巧;

<small>注:
① cloneContents & extractContents操作的對(duì)象是Node(整個(gè)節(jié)點(diǎn))或是Contents(節(jié)點(diǎn)中的所有子節(jié)點(diǎn))由selectNode & selectNodeContents兩個(gè)方法決定搀矫;
②DocumentFragment是一個(gè)Node類(lèi)型,故可以作為Node被添加到其他Node中刻肄,添加方法:node.appendChild(fragment)瓤球。

<!-- cloneRange Demo -->
<body>
  <script>
  function cloneP(argument) {
      var p = document.getElementById("clone");
      var rangeObj = document.createRange();
      rangeObj.selectNodeContents(p);
      // 返回一個(gè)新的Range對(duì)象
      var cloneObj = rangeObj.cloneRange();
      // Range對(duì)象無(wú)法作為Node添加到節(jié)點(diǎn)中,故下面的appendChild方法會(huì)報(bào)錯(cuò)
      // p.appendChild(cloneObj);
      console.log(cloneObj.toString());

  }
  </script>
  <p id="clone">這是一個(gè)將被克隆的元素</p>
  <button onclick="cloneP()">克隆</button>
</body>
<!-- cloneContents Demo -->
<body>
  <script>
  function cloneAppend() {
      var rangeObj = document.createRange();
      var p = document.getElementById("p");
      // rangeObj.selectNode(p); /*選取整個(gè)p節(jié)點(diǎn)*/
      rangeObj.selectNodeContents(p); /*選取p節(jié)點(diǎn)中的所有子節(jié)點(diǎn)*/
      var fragMent = rangeObj.cloneContents(); /*clone選取的內(nèi)容(或節(jié)點(diǎn)),并返回DocumentFragMent對(duì)象*/
      p.appendChild(fragMent); /*往p節(jié)點(diǎn)中添加一個(gè)fragment*/
  }
  </script>
  <p id="p">克隆里面的內(nèi)容并追加到該p元素中</p>
  <button onclick="cloneAppend()">克隆并追加</button>
</body>
<!-- extractContents Demo -->
<body>
  <script>
  function extractAppend(argument) {
      var src = document.getElementById("srcDiv");
      var distDiv = document.getElementById("distDiv");
      var rangeObj = document.createRange();
      rangeObj.selectNodeContents(src);
      /*若上方使用的是selectNode方法敏弃,則會(huì)將src的整個(gè)節(jié)點(diǎn)提取(剪切)卦羡;若為selectNodeContents,則只提取(剪切)src節(jié)點(diǎn)中的內(nèi)容部分*/
      var fragment = rangeObj.extractContents();
      /*若上方使用的是selectNode方法,則會(huì)將src的整個(gè)節(jié)點(diǎn)提取(剪切)至distDiv中绿饵;若為selectNodeContents欠肾,則只提取(剪切)src節(jié)點(diǎn)中的內(nèi)容部分至distDiv中*/
      distDiv.appendChild(fragment);
  }
  </script>
  <!-- 內(nèi)容源 -->
  <div id="srcDiv" style="background-color: #0fc; width: 300px; height: 50px;">將被提取的內(nèi)容</div>
  <!-- 內(nèi)容提取后的放置目標(biāo) -->
  <div id="distDiv" style="background-color: #0cf; width: 300px; height: 50px; font-weight: bold;"></div>
  <button onclick="extractAppend()">提取并追加</button>
</body>
Range對(duì)象之insertNode方法
  • insertNode(newNode):將newNode插入到Range(范圍)起始點(diǎn)。
<!-- inserNode Demo -->
<body>
    <script>
    function insertB() {
        var p = document.getElementById("p");
        // 獲得一個(gè)選擇器
        var selection = document.getSelection();
        if (selection.rangeCount > 0) {
            // 獲取選擇器中的第一個(gè)range(選取范圍)
            var rangeObj = selection.getRangeAt(0);
            // 在range范圍起始位置插入整個(gè)p節(jié)點(diǎn)(<p id="p">這是一個(gè)<b>粗體</b></p>)
            rangeObj.insertNode(p);
        }
    }
    </script>
    <!-- 鼠標(biāo)按下彈起后觸發(fā)insertB函數(shù) -->
    <p onmouseup="insertB()">這段文字中將被插入一個(gè)b元素蝴罪,根據(jù)鼠標(biāo)點(diǎn)擊或選取范圍(Range)的起始位置決定插入位置董济。</p>
    <p id="p">這是一個(gè)<b>粗體</b></p>
</body>
Range對(duì)象之compareBoundaryPoints方法
  • compareBoundaryPoints(how,sourceRange):比較sourceRange邊界點(diǎn)與當(dāng)前Range邊界點(diǎn)的位置。
    • 返回值:如果當(dāng)前范圍的指定邊界點(diǎn)位于 sourceRange 指定的邊界點(diǎn)之前要门,則返回 -1虏肾。如果指定的兩個(gè)邊界點(diǎn)相同,則返回 0欢搜。如果當(dāng)前范圍的邊界點(diǎn)位于 sourceRange 指定的邊界點(diǎn)之后封豪,則返回 1。
    • how參數(shù):聲明如何執(zhí)行比較操作(即比較哪些邊界點(diǎn))炒瘟。它的合法值是 Range 接口定義的常量吹埠。
      • Range.START_TO_START - 比較兩個(gè) Range 節(jié)點(diǎn)的開(kāi)始點(diǎn)
      • Range.END_TO_END - 比較兩個(gè) Range 節(jié)點(diǎn)的結(jié)束點(diǎn)
      • Range.START_TO_END - 用 sourceRange 的開(kāi)始點(diǎn)與當(dāng)前范圍的結(jié)束點(diǎn)比較
      • Range.END_TO_START - 用 sourceRange 的結(jié)束點(diǎn)與當(dāng)前范圍的開(kāi)始點(diǎn)比較
<!-- compareBoundaryPoints Demo -->
<body>
    <script>
    function compare(argument) {
        var b = document.getElementById("b");
        var bRange = document.createRange();
        //這里也可以為selectNodeContents,因?yàn)闉g覽器表現(xiàn)的都是"粗體"這個(gè)文本對(duì)象疮装,但代碼不同缘琅,故可根據(jù)實(shí)際情況使用。
        bRange.selectNode(b);
        // 鼠標(biāo)點(diǎn)擊也是一種selection廓推,即鼠標(biāo)在左邊點(diǎn)一下相當(dāng)于在左邊選擇了刷袍,選擇范圍即點(diǎn)擊位置
        var selection = document.getSelection();
        if (selection.rangeCount > 0) { /*選擇的range數(shù)大于0*/
            var selRange = selection.getRangeAt(0); /*獲取選取的第一個(gè)Range對(duì)象*/
            /*將bRange與selRange對(duì)象進(jìn)行位置比較*/
            if (selRange.compareBoundaryPoints(Range.START_TO_END, bRange) <= 0) { /*bRange的開(kāi)始位置與selRange的結(jié)束位置相比;若小于0樊展,則表示selRange的結(jié)束位置在bRange的開(kāi)始位置左邊*/
                alert("選取的文字在指定節(jié)點(diǎn)(粗體節(jié)點(diǎn))左邊");
            } else if (selRange.compareBoundaryPoints(Range.END_TO_START, bRange) >= 0) { /*bRange的結(jié)束位置與selRange的開(kāi)始位置相比呻纹;若大于0,表示selRange的開(kāi)始位置大于bRange的結(jié)束位置专缠,即表示selRange在bRange的右邊*/
                alert("選取的文字在指定節(jié)點(diǎn)(粗體節(jié)點(diǎn))右邊");
            } else { /*這里省略了另外三種情況的判斷*/
                alert("另外3中情況之一");
            }
        }
    }
    </script>
    <p>這段文字中有一個(gè)加粗的<b id="b">粗體</b>间螟,為了比較選取范圍(Range)在粗體這個(gè)節(jié)點(diǎn)的位置</p>
    <button onclick="compare()">比較</button>
</body>
Range對(duì)象之collapse驴娃、detach方法
  • collapse(toStart):將Range的邊界點(diǎn)設(shè)置為重合(折疊)亭畜;
    • true:toStart的值倦沧,表示Range的結(jié)束邊界點(diǎn)設(shè)置為開(kāi)始邊界點(diǎn)的值;
    • false:toStart的值嘁圈,表示Range的開(kāi)始邊界點(diǎn)設(shè)置為結(jié)束邊界點(diǎn)的值省骂;
  • detach():釋放Range對(duì)象,無(wú)法針對(duì)釋放后的Range對(duì)象操作最住,否則拋出INVALID_STATE_ERR錯(cuò)誤钞澳;常用于釋放已無(wú)作用的Range對(duì)象,提高腳本運(yùn)行性能涨缚。

<small>detach():瀏覽器內(nèi)核為Gecko的版本轧粟,從v15.0開(kāi)始策治,該方法已失效。

<!-- collapse & detach Demo-->
<body>
    <script>
    var rangeObj = document.createRange();

    // 選取節(jié)點(diǎn)
    function selectObj() {
        rangeObj.selectNodeContents(document.getElementById("p")); /*選取p節(jié)點(diǎn)*/
    }
    // 取消選取兰吟,將collapse作為選擇器使用
    function unSelectObj() {
        // 將range的結(jié)束邊界點(diǎn)設(shè)置為開(kāi)始邊界點(diǎn)相同的值通惫,即折疊。
        // 這里即使為false混蔼,也是取消選擇range范圍履腋,因?yàn)閒alse表示將開(kāi)始邊界點(diǎn)設(shè)置為結(jié)束邊界點(diǎn)的值
        rangeObj.collapse(true);
    }
    // 顯示選取的內(nèi)容,selectObj的情況下惭嚣,會(huì)顯示p節(jié)點(diǎn)的所有子節(jié)點(diǎn)遵湖,即"待選取的對(duì)象";unSelectObj狀態(tài)下晚吞,rangeObj無(wú)選取內(nèi)容延旧,alert結(jié)果為空。
    function showObj() {
        alert(rangeObj.toString());
    }

    // 釋放Range對(duì)象槽地,釋放后無(wú)法對(duì)Range對(duì)象進(jìn)行操作迁沫,否則拋出INVALID_STATE_ERR錯(cuò)誤
    // detach方法在Gecko 15.0內(nèi)核開(kāi)始,操作沒(méi)有任何效果捌蚊。
    function detachRange() {
        rangeObj.detach();
    }

    function getRangeStartOffset(toStart) {
        var sel = document.getSelection();
        if (sel.rangeCount > 0) {
            var tmpRange = sel.getRangeAt(0);
            // 通過(guò)傳入不同的toStart集畅,觀(guān)察startOffset的值;
            // toStart為true時(shí)缅糟,startOffset為range開(kāi)始邊界點(diǎn)的值牡整;為false時(shí),startOffset為range結(jié)束邊界點(diǎn)的值溺拱。
            tmpRange.collapse(toStart);
            // 打印tmpRange在當(dāng)前節(jié)點(diǎn)的起點(diǎn)開(kāi)始位置;p節(jié)點(diǎn)中有三個(gè)子節(jié)點(diǎn)谣辞,startOffset的位置按當(dāng)前節(jié)點(diǎn)計(jì)算迫摔,從0開(kāi)始
            // startOffset的位置:0所1有2子3節(jié)4點(diǎn)5被6選7取8,9包10括11<b>0粗1體2</b>0這1個(gè)2節(jié)3點(diǎn)4
            console.log(tmpRange.startOffset);
        }
    }
    </script>
    <p id="p">所有子節(jié)點(diǎn)被選取泥从,包括<b>粗體</b>這個(gè)節(jié)點(diǎn)</p>
    <button onclick="selectObj()">選取對(duì)象</button>
    <button onclick="unSelectObj()">取消選取</button>
    <button onclick="showObj()">顯示對(duì)象</button>
    <button onclick="detachRange()">釋放Range對(duì)象</button>
    <button onclick="getRangeStartOffset(false)">獲取Range范圍的開(kāi)始點(diǎn)并打印在console中</button>
</body>

HTML5新增元素audio(音頻)與video(視頻)


audio元素
  • audio的屬性:
    • autoplay:如果出現(xiàn)該屬性句占,則音頻在就緒后馬上播放;
    • controls:如果出現(xiàn)該屬性躯嫉,則向用戶(hù)顯示控件纱烘,比如播放按鈕;
    • src:要播放的音頻的 URL祈餐;
    • loop:如果出現(xiàn)該屬性擂啥,則每當(dāng)音頻結(jié)束時(shí)重新開(kāi)始播放;
    • preload:如果出現(xiàn)該屬性帆阳,則音頻在頁(yè)面加載時(shí)進(jìn)行加載哺壶,并預(yù)備播放。如果使用 "autoplay",則忽略該屬性山宾。
vedio元素
  • vedio的屬性:
    • autoplay:如果出現(xiàn)該屬性至扰,則視頻在就緒后馬上播放;
    • controls:如果出現(xiàn)該屬性资锰,則向用戶(hù)顯示控件敢课,比如播放按鈕;
    • src:要播放的視頻的 URL绷杜;
    • loop:如果出現(xiàn)該屬性直秆,則每當(dāng)視頻結(jié)束時(shí)重新開(kāi)始播放;
    • preload:如果出現(xiàn)該屬性接剩,則視頻在頁(yè)面加載時(shí)進(jìn)行加載切厘,并預(yù)備播放。如果使用 "autoplay"懊缺,則忽略該屬性疫稿;
    • height、width:定義視頻的高度與寬度鹃两;
    • muted:規(guī)定視頻的音頻輸出應(yīng)該被靜音遗座;
    • poster:規(guī)定視頻下載時(shí)顯示的圖像URL,或者在用戶(hù)點(diǎn)擊播放按鈕前顯示的圖像URL俊扳。
source元素

為媒介元素(比如 <video> 和 <audio>)定義媒介資源途蒋。主要用途為允許您規(guī)定可替換的視頻/音頻文件供瀏覽器根據(jù)它對(duì)媒體類(lèi)型或者編解碼器的支持進(jìn)行選擇。該元素為媒介元素的子標(biāo)簽(即元素應(yīng)放在媒介元素之內(nèi))馋记。

  • 常用屬性src号坡,定義資源URL;
<!-- audio Demo-->
<body>
    <!-- 當(dāng)autoplay存在時(shí)梯醒,preload(預(yù)加載)忽略 -->
    <!-- <audio src="../raw/1.mp3" controls="controls" preload="preload" autoplay="autoplay" loop="loop"></audio> -->
    <audio id="audio" src="../raw/1.mp3">您的瀏覽器不支持</audio>
    <button onclick="playPause()">播放/暫停</button>
    <script>
    // 若再全局變量中聲明宽堆,須注意該節(jié)點(diǎn)是否已加載(瀏覽器從上往下逐步加載),否則會(huì)出現(xiàn)獲取不到的情況茸习。
    var audio = document.getElementById("audio");

    function playPause(argument) {
        if (audio.paused) { /*如果音樂(lè)為暫停狀態(tài)*/
            // 播放音樂(lè)
            audio.play();
        } else {
            audio.pause();
        }
    }
    </script>
</body>

<!--video & source Demo-->
<body>
    <button onclick="playPause()">播放/暫停</button>
    <button onclick="bigger()">放大</button>
    <button onclick="smaller()">縮小</button>
    <!-- 一種文件格式的video畜隶,弊端:某些瀏覽器可能出現(xiàn)不支持對(duì)應(yīng)的視頻格式 -->
    <video src="../raw/movie.ogg" id="myControls">您的瀏覽器不支持</video>
    <script>
    var video = document.getElementById("myControls");

    // 播放暫停功能
    function playPause(argument) {
        if (video.paused) {
            video.play();
        } else {
            video.pause();
        }
    }
    // 放大視頻窗口功能
    function bigger(argument) {
        video.width = 800; /*將video節(jié)點(diǎn)的寬度設(shè)置為800px*/
        video.height = 800; /*將video節(jié)點(diǎn)的高度設(shè)置為800px*/
    }
    // 縮小視頻窗口功能
    function smaller(argument) {
        video.width = 100;
        video.height = 100;
    }
    </script>
    <!-- 根據(jù)瀏覽器支持的格式獲取對(duì)應(yīng)的資源文件 -->
    <video controls="controls">
        <!-- ogg格式 -->
        <source src="../raw/movie.ogg">
        <!-- mp4格式 -->
        <source src="../raw/movie.mp4">
    </video>
</body>

HTML5的拖放功能


<small>先了解這些知識(shí)(原理部分)
1.開(kāi)始拖動(dòng)某元素,會(huì)觸發(fā)該元素的ondragstart事件号胚;在這個(gè)事件里設(shè)置拖動(dòng)的元素籽慢。
2.拖動(dòng)的元素A經(jīng)過(guò)元素B時(shí),會(huì)觸發(fā)B元素的ondragover事件猫胁;在這個(gè)事件里設(shè)置B元素允許被其他元素放入箱亿。
3.拖動(dòng)的元素A在元素B上放手后,會(huì)出發(fā)B元素的ondrop事件弃秆;在這個(gè)事件里設(shè)置A元素放入到B元素的添加行為极景。
4.拖放中的數(shù)據(jù)傳輸察净,依賴(lài)于event中的dataTransfer對(duì)象。

網(wǎng)頁(yè)元素之間的拖放
  • 拖放流程
    1. 開(kāi)始拖動(dòng)盼樟,在被拖動(dòng)的元素上調(diào)用ondragstart監(jiān)聽(tīng)事件氢卡;
    2. 設(shè)置拖動(dòng)數(shù)據(jù),在ondragstart事件中晨缴,通過(guò)事件的dataTransfer設(shè)置拖放數(shù)據(jù)(setData方法)译秦;
    3. 設(shè)置拖放位置,在拖放目標(biāo)位置击碗,設(shè)置元素允許被其他元素放入筑悴,通過(guò)ondragover事件避免瀏覽器默認(rèn)方式(不允許元素被其他元素放入)處理;
    4. 獲取拖動(dòng)的元素并將該元素放入目的位置元素稍途,通過(guò)ondrop事件阁吝,完成拖放元素添加到目標(biāo)元素的動(dòng)作。
  • 實(shí)現(xiàn)方法(兩種)
    • 通過(guò)JS實(shí)現(xiàn)
      獲取拖動(dòng)元素及目標(biāo)位置元素械拍,通過(guò)拖動(dòng)元素A監(jiān)聽(tīng)ondragstart事件突勇,設(shè)置拖動(dòng)數(shù)據(jù);通過(guò)目標(biāo)位置元素B監(jiān)聽(tīng)ondragover和ondrop事件坷虑,設(shè)置允許拖入甲馋,并將A添加到B元素。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML5網(wǎng)頁(yè)中元素的拖放-通過(guò)JS實(shí)現(xiàn)</title>
    <style>
    div {
        float: left;
        height: 300px;
        width: 300px;
    }
    #box {
        background-color: #ECAD12;
    }
    #secBox {
        background-color: #34CA7E;
    }
    </style>
    <script>
    // 頁(yè)面加載完成之后立即執(zhí)行如下函數(shù)
    window.onload = function() {
            var box = document.getElementById("box");
            var secBox = document.getElementById("secBox");
            var dragImg = document.getElementById("dragImg");
            // 第一步:在被拖動(dòng)的節(jié)點(diǎn)上使用ondragstart方法迄损,表示開(kāi)始拖動(dòng)定躏;同時(shí)設(shè)置拖動(dòng)的數(shù)據(jù)
            dragImg.ondragstart = function(ev) {
                // 設(shè)置拖動(dòng)的數(shù)據(jù),"myData"表示一個(gè)types元素(可以理解為id)芹敌,將被拖動(dòng)數(shù)據(jù)放入目標(biāo)位置時(shí)獲取數(shù)據(jù)使用
                // "myData"會(huì)寫(xiě)入到dataTransfer對(duì)象的types鍵(該鍵下包含很多類(lèi)型,myData表示一種類(lèi)型)中
                // 數(shù)據(jù)的傳輸是通過(guò)event的dataTransfer來(lái)實(shí)現(xiàn)的
                // ev.target.id:事件目標(biāo)的id痊远,這里指的是dragImg對(duì)象的元素id屬性值
                ev.dataTransfer.setData("myData", ev.target.id);
            }
            // 第二步:ondragover規(guī)定在何處放置被拖動(dòng)數(shù)據(jù),默認(rèn)情況下氏捞,無(wú)法將元素/數(shù)據(jù)放到其他數(shù)據(jù)中
            // 此處自定義ondragover事件拗引,阻止瀏覽器使用默認(rèn)處理方式,即允許其他元素放到該元素中
            box.ondragover = unDefault;
            secBox.ondragover = unDefault;
            // 第三步:放置數(shù)據(jù)時(shí)會(huì)出發(fā)ondrop事件幌衣,故通過(guò)重寫(xiě)該事件的處理方式達(dá)到放置目的。
            box.ondrop = imgDrag;
            secBox.ondrop = imgDrag;
            // ondragover調(diào)用的方法:避免瀏覽器對(duì)數(shù)據(jù)的默認(rèn)處理方式
            function unDefault(event) {
                // 避免瀏覽器對(duì)數(shù)據(jù)的默認(rèn)處理方式的方法
                event.preventDefault();
            }
            // ondrop調(diào)用的方法:獲取拖動(dòng)數(shù)據(jù)壤玫,放入到目的地節(jié)點(diǎn)
            function imgDrag(ev) {
                showObj(ev.dataTransfer, "dataTransfer");
                showObj(ev.dataTransfer.types, "types"); //types中會(huì)顯示setData設(shè)置的數(shù)據(jù)
                showObj(ev.dataTransfer.files, "files"); //files的length若大于0豁护,表示有有文件拖放行為;這里是img元素欲间,所以該屬性的length=0楚里;
                // 網(wǎng)頁(yè)元素拖放實(shí)際測(cè)試發(fā)現(xiàn),drop事件不改變默認(rèn)處理方式猎贴,也能拖放至目的地班缎;前提是dragover事件中需避免默認(rèn)處理蝴光。ondrop的默認(rèn)處理方式是以鏈接形式打開(kāi)。
                // 本地資源拖放則必須使用該方法避免默認(rèn)處理方式執(zhí)行
                ev.preventDefault();
                // 獲取設(shè)置的數(shù)據(jù)標(biāo)記(id)
                var myData = ev.dataTransfer.getData("myData");
                // 通過(guò)數(shù)據(jù)標(biāo)記獲得一個(gè)節(jié)點(diǎn)
                var myImg = document.getElementById(myData);
                //將節(jié)點(diǎn)加入追加到拖放目的地節(jié)點(diǎn)中 ev.target表示事件目標(biāo)达址,即拖放目的地節(jié)點(diǎn)
                ev.target.appendChild(myImg);
            }
        }
        // 顯示對(duì)象key和value信息
    function showObj(obj, flag) {
        for (var key in obj) { /*obj為鍵值對(duì)*/
            str += key + ":" + obj[key] + " -- " + flag + "<br/>";
        }
        var objDiv = document.getElementById("objDiv");
        objDiv.innerHTML = str + "<br/>";
    }
    </script>
</head>
<body>
    <!-- 被拖放數(shù)據(jù)放置的區(qū)域1 -->
    <div id="box"></div>
    <!-- 被拖放數(shù)據(jù)放置的區(qū)域2 -->
    <div id="secBox"></div>
    <img id="dragImg" src="../raw/submit.gif">
    <p id="objDiv"></p>
</body>
</html>
* *通過(guò)屬性實(shí)現(xiàn)*

在拖動(dòng)元素中設(shè)置ondragstart屬性蔑祟,設(shè)置事件調(diào)用的方法drag(event);在目標(biāo)位置元素中設(shè)置ondragover與ondrop屬性沉唠,并以此設(shè)置allowDrag(event)與allDrop(event)方法疆虚。

<small>方法名可自定義,參數(shù)必須是event</small>

  ```html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5網(wǎng)頁(yè)中元素的拖放-通過(guò)屬性實(shí)現(xiàn)</title>
<style>
div {
width: 500px;
height: 300px;
float: left;
}
#box {
background-color: #EABD14;
}
#secBox {
background-color: #CE30C6;
}
</style>
<script>
var str = "";
// 第一步:被拖放數(shù)據(jù)設(shè)置數(shù)據(jù)满葛,開(kāi)始拖放
function drag(ev) {
// "test"會(huì)寫(xiě)入到dataTransfer對(duì)象的types鍵中
ev.dataTransfer.setData("test", ev.target.id);
}
// 第二步:拖放目的地避免默認(rèn)處理方式(不允許其他元素放到自身元素中,避免后允許),決定被拖放數(shù)據(jù)的位置
function dragOver(ev) {
ev.preventDefault();
}
// 第三步:放置數(shù)據(jù)觸發(fā)的事件径簿,將設(shè)置的數(shù)據(jù)獲取,并將得到的數(shù)據(jù)獲取節(jié)點(diǎn)后追加到目的地節(jié)點(diǎn)
function boxDrop(ev) {
showObj(ev.dataTransfer, "dataTransfer");
showObj(ev.dataTransfer.types, "types"); //types中會(huì)顯示setData設(shè)置的數(shù)據(jù)
showObj(ev.dataTransfer.files, "files"); //files的length若大于0嘀韧,表示有有文件拖放行為
// showObj(ev.dataTransfer.files);
// 實(shí)際測(cè)試發(fā)現(xiàn)篇亭,drop事件不改變默認(rèn)處理方式,也能拖放至目的地锄贷;前提是dragover事件中需避免默認(rèn)處理
// 本地資源拖放則必須使用該方法避免默認(rèn)處理方式執(zhí)行
ev.preventDefault();
var img = document.getElementById(ev.dataTransfer.getData("test"));
ev.target.appendChild(img);
}
// 顯示對(duì)象key和value信息
function showObj(obj, flag) {
for (var key in obj) { /obj為鍵值對(duì)/
str += key + ":" + obj[key] + " -- " + flag + "
";
}
var objDiv = document.getElementById("objDiv");
objDiv.innerHTML = str + "
";
}
</script>
</head>
<body>

<div ondragover="dragOver(event)" ondrop="boxDrop(event)" id="box"></div>
<div ondragover="dragOver(event)" ondrop="boxDrop(event)" id="secBox"></div>

<img draggable="true" id="gif" ondragstart="drag(event)" src="../raw/submit.gif">
<div id="objDiv"></div>
</body>
</html>


#####本地資源拖放至網(wǎng)頁(yè)(以圖片為例)
  * **拖放流程**
    1. 設(shè)置拖放位置译蒂,在拖放目標(biāo)位置,設(shè)置元素允許被其他元素放入肃叶,通過(guò)ondragover事件避免瀏覽器默認(rèn)方式(不允許元素被其他元素放入)處理蹂随;
    2. 獲取拖動(dòng)的元素并將該元素放入目的位置元素,通過(guò)ondrop事件因惭,完成拖放元素添加到目標(biāo)元素的動(dòng)作岳锁。

  > <small>注:
1.因?yàn)槭潜镜刭Y源的拖放,所以沒(méi)有元素需要ondragstart事件蹦魔;
2.獲取拖動(dòng)數(shù)據(jù)的方法:var file = event.dataTransfer.files[0]激率;files是一個(gè)數(shù)組,訪(fǎng)問(wèn)拖動(dòng)的第一個(gè)文件勿决,所以索引值為0乒躺;
3.創(chuàng)建一個(gè)FileReader容器讀取文件:var fileReader = new FileReader();
4.設(shè)置文件讀取進(jìn)度的監(jiān)聽(tīng)事件:fileReader.onload = allDrop(readerEvent)低缩;讀取完成后執(zhí)行allDrop函數(shù)嘉冒;
5.在allDrop文件中使用readerEvent.target.result屬性獲取讀取結(jié)果數(shù)據(jù)并將輸入添加到目標(biāo)容器(拖放目的地)中;target為當(dāng)前event的filereader對(duì)象咆繁。
6.開(kāi)始讀取文件:fileReader.readAsDataURL(file)讳推,將文件讀取為一串Data URL字符串。`讀取文件的方法請(qǐng)根據(jù)文件類(lèi)型決定`玩般。

  * **實(shí)現(xiàn)方法(兩種)**
    * *通過(guò)JS實(shí)現(xiàn)*
通過(guò)目標(biāo)位置元素監(jiān)聽(tīng)ondragover和ondrop事件银觅,設(shè)置允許拖入,讀取拖動(dòng)的本地資源數(shù)據(jù)并將其添加到B元素中坏为。
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML5之本地資源拖放到網(wǎng)頁(yè)-通過(guò)JS實(shí)現(xiàn)</title>
    <style>
    #imgContainer {
        background-color: #ccc;
        height: 300px;
        width: 300px;
    }
    </style>
    <script>
    // 監(jiān)聽(tīng)頁(yè)面加載完成后執(zhí)行如下函數(shù)
    window.onload = function() {
        // 獲取裝載圖片的容器
        var imgContainer = document.getElementById("imgContainer");
        // 設(shè)置圖片加載的位置究驴,取消默認(rèn)瀏覽器行為镊绪;即允許元素放入其他元素
        imgContainer.ondragover = function(ev) {
            ev.preventDefault();
        }
        // 放置圖片
        imgContainer.ondrop = function(ev) {
            // 本地資源拖放,必須禁止瀏覽器默認(rèn)行為(默認(rèn)行為:以鏈接形式打開(kāi))
            ev.preventDefault();
            // 獲取第一個(gè)文件
            var uploadFile = ev.dataTransfer.files[0];
            var fileReader = new FileReader();
            // 文件成功讀取完成后執(zhí)行如下函數(shù)
            fileReader.onload = function(subEv) {
                    // target為一個(gè)FileReader對(duì)象,圖片鏈接就是該對(duì)象下result鍵對(duì)應(yīng)的值
                    imgContainer.innerHTML = "<img src=\"" + subEv.target.result + "\">"
                }
                // 讀取圖片為DataUrl格式,若為其他類(lèi)型資源洒忧,請(qǐng)根據(jù)實(shí)際情況選擇fileReader的讀取文件方法
            fileReader.readAsDataURL(uploadFile);
        }
    }
    </script>
</head>
<body>
    <div id="imgContainer"></div>
</body>
</html>
* *通過(guò)屬性實(shí)現(xiàn)*

在目標(biāo)位置元素中設(shè)置ondragover與ondrop屬性蝴韭,并以此設(shè)置allowDrag(event)與allDrop(event)方法。

<small>方法名可自定義跑慕,參數(shù)必須是event</small>

  ```html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5之本地資源拖放到網(wǎng)頁(yè)-通過(guò)屬性實(shí)現(xiàn)</title>
<style>
#imgContainer {
background-color: #ccc;
height: 300px;
width: 300px;
}
</style>
</head>
<body>
<script>
var str = "";
function allowDrag(ev) {
ev.preventDefault();
}
function allDrop(ev) {
// 本地資源拖放則必須使用該方法避免默認(rèn)處理方式執(zhí)行
ev.preventDefault();
showObj(ev.dataTransfer, "dataTransfer");
showObj(ev.dataTransfer.types, "types");
showObj(ev.dataTransfer.files, "files");
// 可以獲取到files文件列表第一個(gè)文件的文件名万皿、最后修改時(shí)間、大小核行、類(lèi)型等
showObj(ev.dataTransfer.files[0], "file");

    // 從File數(shù)組中獲取第一個(gè)File文件
    var uploadFile = ev.dataTransfer.files[0];
    // 創(chuàng)建一個(gè)文件讀取器
    var fileReader = new FileReader();
    // 數(shù)據(jù)讀取成功完成時(shí)觸發(fā)
    fileReader.onload = function(subEv) {
        showObj(subEv.target); /*target 是一個(gè)FileReader對(duì)象*/
        // subEv.target.result是一個(gè)base64加密的被拖放圖片的地址
        ev.target.innerHTML = "<img src=\"" + subEv.target.result + "\">"
    }

    // 將文件讀取為一串Data URL字符串牢硅,將小文件以一種特殊格式的URL地址直接讀入頁(yè)面。小文件指圖像與html等格式的文件芝雪。
    fileReader.readAsDataURL(uploadFile);
}
// 顯示對(duì)象key和value信息
function showObj(obj, flag) {
    for (var key in obj) { /*obj為鍵值對(duì)*/
        str += key + ":" + obj[key] + " -- " + flag + "<br/>";
    }

    var objDiv = document.getElementById("objDiv");
    objDiv.innerHTML = str + "<br/>";
}
</script>
<div ondragover="allowDrag(event)" ondrop="allDrop(event)" id="imgContainer"></div>
<div id="objDiv"></div>

</body>
</html>


##canvas元素的基本使用
***
#####canvas元素
只是一個(gè)圖形容器减余,必須通過(guò)JS來(lái)繪制圖形;可以繪制各種路徑惩系、圖形位岔、圖像、文字等堡牡。
> <small>注:所有繪制均須在畫(huà)布只能抒抬,超出畫(huà)布范圍將無(wú)法繪制。

  * ***canvas的創(chuàng)建方式(兩種)***
    * 通過(guò)JS創(chuàng)建:`document.body.innerHTML = "<canvas id=\"canvas\">您的瀏覽器不支持</canvas>"`
    * 直接創(chuàng)建:`<canvas id="canvas">您的瀏覽器不支持</canvas>`
  * ***canvas的2d渲染模式下的應(yīng)用***
    * *繪制矩形*
      1. 獲取畫(huà)布:`var canvas = document.getElementById("canvas");`
      2. 獲取2d模式上下文:`var ctx = canvas.getContext("2d");`
      3. 設(shè)置填充樣式:`ctx.fillStyle = "rgba(255,255,0,0.5)"`晤柄,值也可以為`#ff0擦剑、yellow`格式;
      4. 繪制矩形:`ctx.fillRect(x,y,width,height);`
    * *繪制圖片*
      1. 獲取畫(huà)布:`var canvas = document.getElementById("canvas");`
      2. 獲取2d模式上下文:`var ctx = canvas.getContext("2d");`
      3. 創(chuàng)建圖片對(duì)象:`var img = new Image()`芥颈,設(shè)置圖片路徑:`img.src="xxx.jpg"`惠勒;圖片對(duì)象也可從網(wǎng)頁(yè)元素中獲取爬坑;
      4. 監(jiān)聽(tīng)圖片加載完成事件:`img.onload = function(event){...}`
      5. 在onload的函數(shù)體內(nèi)執(zhí)行`ctx.drawImage(img,0,0)`方法纠屋,該方法有多種參數(shù)類(lèi)型,可參考API

> 更多Canvas的使用可查閱Mozilla提供的API:[點(diǎn)擊查看](https://developer.mozilla.org/en-US/docs/Web/API)

```html
<!-- canvas demo-->
<body>
    <script>
    var canvas, ctx;
    window.onload = function() {
        getCanvas();
        // fillRect();
        drawImg();
    }

    function getCanvas() {
        // 通過(guò)js創(chuàng)建canvas
        // document.body.innerHTML = "<canvas id=\"canvas\"></canvas>";
        // 獲取canvas
        canvas = document.getElementById("canvas");
        if (canvas == null) { /*canvas獲取失敗的情況下盾计,返回false*/
            return false;
        }
        // 通過(guò)2d渲染畫(huà)圖售担,獲得一個(gè)上下文
        ctx = canvas.getContext("2d");
    }

    function fillRect() {
        ctx.fillStyle = "#ff0000"; /*繪圖顏色*/
        ctx.rotate(45 * Math.PI / 180); /*順時(shí)針45度*/
        // ctx.scale(2, 0.5); /* x*2,y*0.5 坐標(biāo)與長(zhǎng)寬都會(huì)根據(jù)這個(gè)因子變化*/
        ctx.fillRect(450, 0, 50, 50); /*繪制一個(gè)矩形署辉,參數(shù)分別是x族铆,y,width涨薪,height*/

    }

    function drawImg() {
        var img = new Image();
        // 當(dāng)img成功讀取完成時(shí),執(zhí)行下方函數(shù)
        img.onload = function(ev) {
            // 若圖片大于畫(huà)布大小炫乓,則只會(huì)繪畫(huà)畫(huà)布大小部分的圖片
            ctx.drawImage(img, 0, 0);
        }
        img.src = "../raw/1.jpg";

    }
    </script>
    <!-- 這是直接創(chuàng)建的方式刚夺,更多情況下通過(guò)js創(chuàng)建 -->
    <canvas id="canvas" width="500px" height="500px"></canvas>
</body>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末献丑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侠姑,更是在濱河造成了極大的恐慌创橄,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莽红,死亡現(xiàn)場(chǎng)離奇詭異妥畏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)安吁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)醉蚁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鬼店,你說(shuō)我怎么就攤上這事网棍。” “怎么了妇智?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵滥玷,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我巍棱,道長(zhǎng)惑畴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任航徙,我火速辦了婚禮如贷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捉偏。我一直安慰自己倒得,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布夭禽。 她就那樣靜靜地躺著霞掺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讹躯。 梳的紋絲不亂的頭發(fā)上菩彬,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音潮梯,去河邊找鬼骗灶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛秉馏,可吹牛的內(nèi)容都是我干的耙旦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼萝究,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼免都!你這毒婦竟也來(lái)了锉罐?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绕娘,失蹤者是張志新(化名)和其女友劉穎脓规,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體险领,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侨舆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绢陌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挨下。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖下面,靈堂內(nèi)的尸體忽然破棺而出复颈,到底是詐尸還是另有隱情,我是刑警寧澤沥割,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布耗啦,位于F島的核電站,受9級(jí)特大地震影響机杜,放射性物質(zhì)發(fā)生泄漏帜讲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一椒拗、第九天 我趴在偏房一處隱蔽的房頂上張望似将。 院中可真熱鬧蚀苛,春花似錦在验、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至渗蟹,卻和暖如春块饺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雌芽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工授艰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人世落。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓淮腾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谷朝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 接上 關(guān)于HTML/HTML5(一)http://www.reibang.com/p/33fc7840c079 學(xué)...
    Amyyy_閱讀 778評(píng)論 0 4
  • H5 meta詳解 viewport width:控制 viewport 的大小篮灼,可以指定的一個(gè)值,如果 600徘禁,...
    FConfidence閱讀 800評(píng)論 0 3
  • +概述:HTML5是W3C 與 WHATWG 合作的結(jié)果。 新特性:1)canvas:用于繪畫(huà)髓堪;2)video/a...
    南山伐木閱讀 222評(píng)論 0 0
  • HTML5拖放(Drag 和 Drop) 拖放(Drag 和 drop)是 HTML5 標(biāo)準(zhǔn)的組成部分送朱。 拖放 拖...
    GreenHand1閱讀 345評(píng)論 0 0
  • 1.htm5新特性 1.語(yǔ)義化標(biāo)簽 1.1.htm5新特性 1.2.新選著器### 1.3 獲取class列表屬性...
    believedream閱讀 527評(píng)論 0 0