首頁 > web前端 > H5教程 > H5拖放API基礎篇

H5拖放API基礎篇

大家讲道理
發布: 2017-05-28 11:07:39
原創
2149 人瀏覽過

  不要搞錯,本文不是講如何拖地的。看過《javascript精粹》朋友應該知道,他實現拖放的過程比較複雜,現在時代不同了,我們用H5的新的拖放API就能非常方便的實作拖放效果了。最近在園子見一園友寫了一篇《HTML5 進階系列:拖放API 實現拖放排序》,真乃大師之作,大~熊同學作為一代菜鳥(不是宗師),無法與之想比,遂推出基礎篇,希望各位園友有所收穫。

一、一個簡單的例子--地上有石子撿幾個吧

  


    地上有石子,捡几个吧
    
    
        
        
        
    
    
    我是篮子    
    
    我是地
    
        石子
        石子
        石子
        石子
        石子
        石子
        石子
        石子
        石子
        石子
登入後複製


  (gif示範是用的edge,我的ubuntu做gif太麻煩了,借了個windows)

  

#  這裡用一個簡單的範例示範如何實作拖放,那麼問題來了,從上面的示範你可以猜出一些屬性和方法的用法了,那些方法的作用究竟是怎樣的?那些個屬性又是啥意思呢?下面一一到來。

二、實現拖放的一般步驟

  1、找到一個可拖的元素

  正如不是所有人都叫大熊一樣,並不是所有的元素都是可以拖曳的。 img和a元素預設可拖,其他元素預設為不可拖,當時可以加一個draggable=true讓它可拖。

  


<p draggable=&#39;true&#39;></p>
登入後複製


#  2、處理拖放有關事件

  所有相關事件如下:這摘自:http://www.cnblogs.com/linxin/p/6794542.html)

  來源物件#:

  • dragstart:來源物件開始拖放。

  • drag:來源物件拖放過程中。

  • dragend:來源物件拖曳結束。

  過程物件:

  • #dragenter:來源物件開始進入過程物件範圍內。

  • dragover:來源物件在過程物件範圍內移動。

  • dragleave:來源物件離開過程物件的範圍。

  目標物件:

  • #drop:來源物件被拖曳到目標物件內。

  我們可以用一個測試來看看這些事件的觸發時機和事件物件為何。

  


<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>testEvents</title>
    <style type="text/css">
        .source{
            width: 50px;
            height: 50px;
            border: 1px solid red;
        }
        .process{
            width: 100px;
            height: 100px;
            border: 1px solid black;
            margin-top: 10px;
        }
        .dest{
            width: 100px;
            height: 100px;
            border: 1px solid green;
            margin-top: 10px;
        }
    </style></head><body>
    <p class="source" id="source" draggable="true"></p>
    <p class="process" id="process"></p>
    <p class="dest" id="dest"></p>
    <script type="text/javascript">
    window.onload=function(){        var source = document.getElementById("source");        var process = document.getElementById("process");        var dest = document.getElementById("dest");        var sourceEle;

        source.addEventListener("dragstart",function(e){
            console.log("source dragstart");
            console.log(e);
            sourceEle = e.target;            var dt = e.dataTransfer;
            dt.effectedAllowed = "all";
        },false);

        process.addEventListener("dragenter",function(e){
            console.log("process dragenter");
            console.log(e);
        },false);

        process.addEventListener("dragover",function(e){
            console.log("process dragover");
            console.log(e);
        },false);

        process.addEventListener("dragleave",function(e){
            console.log("process dragleave");
            console.log(e);
        },false);

        source.addEventListener("drag",function(e){
            console.log("source drag");
            console.log(e);
        },false);

        dest.addEventListener("dragend",function(e){
            console.log("dest dragend");
            console.log(e);
            e.preventDefault();
        },false);

        dest.addEventListener("drop",function(e){
            console.log("dest drop");
            console.log(e);
            dest.appendChild(sourceEle);
            e.preventDefault();
            e.stopPropagation();
        },false);

        document.ondragover = function(e){e.preventDefault();}
        document.ondrop = function(e){e.preventDefault();}
    }    </script></body></html>
登入後複製


#  這個例子將拖放過過程涉及的事件做了一個羅列,這裡不再細講,你可以查看控制台看看事件的觸發順序和事件物件。

三、一個重要的物件DataTransfer物件

  這裡首字母大寫了,嚴格說叫做一個類,每一次拖放會實例化這個類,保存在事件物件的dataTransfer屬性中。其屬性和方法請見下表(取自:http://www.cnblogs.com/ijjyo/p/4316232.html)

  感謝這位兄台的總結,拿了你這麼多東西,謝謝啊。

       

  

       

  #下面做一些簡單的測試

   #下面做一些簡單的測試 和dropEffect

,這裡將前者置為effectAllowed後者用

下拉清單

選擇,以便於看到不同的滑鼠樣式。


  


<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>testEvents</title>
    <style type="text/css">
        .source{
            width: 50px;
            height: 50px;
            border: 1px solid red;
        }
        .process{
            width: 100px;
            height: 100px;
            border: 1px solid black;
            margin-top: 10px;
        }
        .dest{
            width: 100px;
            height: 100px;
            border: 1px solid green;
            margin-top: 10px;
        }
    </style></head><body>
    <select id="dpe">
        <option value="copy">copy</option>
        <option value="move">move</option>
        <option value="link">link</option>
        <option value="none">none</option>
    </select>
    <p class="source" id="source" draggable="true"></p>
    <p class="process" id="process"></p>
    <p class="dest" id="dest"></p>
    <script type="text/javascript">
    window.onload=function(){        var source = document.getElementById("source");        var process = document.getElementById("process");        var dest = document.getElementById("dest");        var dpe = document.getElementById("dpe");        var dpev;

        dpe.onchange = function(){
            dpev = this.value;
        }        var sourceEle;

        source.addEventListener("dragstart",function(e){
            console.log("source dragstart");
            console.log(e);
            sourceEle = e.target;            var dt = e.dataTransfer;
            dt.effectedAllowed = "all";
        },false);

        dest.addEventListener("dragend",function(e){
            console.log("dest dragend");
            console.log(e);
            e.preventDefault();
        },false);

        dest.addEventListener("drop",function(e){
            console.log("dest drop");
            console.log(e);
            dest.appendChild(sourceEle);
            e.preventDefault();
            e.stopPropagation();
        },false);

        document.ondragover = function(e){
            e.dataTransfer.dropEffect = dpev;
            e.preventDefault();
        }
        document.ondrop = function(e){e.preventDefault();}
    }    </script></body></html>
登入後複製

  我在ubuntu

chrome測試法現,都是一個手,但是置為none時拖不進去了,可能不同系統會有一些差異。

  

關於setData()和getData()方法#   這兩個是關於資料交換的方法,前者傳兩個參數,第一個參數是一個mime類型字串

,第二個是資料;後者傳一個參數,為mime型別。可用mime類型為text/plain,text/html,text/

xml

,text/uri-list.

  測試案例,將選單的菜拖曳到記錄本上。


  

##########
<!DOCTYPE html><html lang="en"><head>
    <meta charset="UTF-8">
    <title>点菜</title>
    <style type="text/css">
        .menu{
            width: 200px;
            height: 300px;
            border: 1px solid red;
            margin-right: 10px;
            float: left;
        }
        .record{
            width: 200px;
            height: 300px;
            border: 1px solid black;
            margin-right: 10px;
            float: left;
        }
    </style></head><body>
    <ul class="menu" id="menu">
        <li draggable="true">糖醋排骨</li>
        <li draggable="true">青椒肉丝</li>
        <li draggable="true">武昌鱼</li>
        <li draggable="true">手撕包材</li>
        <li draggable="true">千叶豆腐</li>    
    </ul>
    <ul class="record" id="record">
        
    </ul>
    <script type="text/javascript">
        window.onload = function(){            var menu = document.getElementById("menu");            var record = document.getElementById("record");

            menu.addEventListener("dragstart",function(e){                var dt = e.dataTransfer;                var tar = e.target;                if(tar.tagName=="LI"){
                    dt.setData("text/plain",tar.innerHTML);
                }
                dt.effectedAllowed = "all";
            },false);

            record.addEventListener("drop",function(e){                var li  = document.createElement("li");
                li.appendChild(document.createTextNode(e.dataTransfer.getData("text/plain")));
                record.appendChild(li);
                e.stopPropagation();
            },false);

            record.addEventListener("dropend",function(e){
                e.preventDefault();
            },false);

            document.addEventListener("dragover",function(e){e.preventDefault()},false);

            document.addEventListener("drop",function(e){e.preventDefault()},false);
        }    </script></body></html>
登入後複製


  关于setDragImage(Element img,long x,long y)

   这个方法是设置拖放时的图标的,第一个参数表是图标元素,第二个表示相对与光标的水平偏移,第三个是垂直的。

  还是前面的例子,在dragstart事件添加下面的代码,拖动时你会发现一只很大的手(不要被吓到);


var img = document.createElement("img");
                img.src = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1493802056263&di=232de2c30491e19f32833669ad5a67ae&imgtype=0&src=http%3A%2F%2Fstatic.freepik.com%2Ffree-photo%2Fone-finger_318-10333.jpg";
                dt.setDragImage(img,10,10);
登入後複製


 

 四、关于拖放数据传递

  上面的例子已经谈到了拖放的数据传递方法,这里在总结一下。

  1、通过dataTransfer的setData()和getData()方法传递

  2、通过闭包的方法,请参考开篇的例子。

五、总结

  HTML5的拖放api非常简洁实用,为我们省去了很多麻烦,如果没有它,我们可能需要通过mousedownmousemove等等事件才能实现上述功能。本文较为详细的介绍了相关api,希望对你有所帮助。关于拖放api的应用大家可以参看下面链接的文章,他做了一个拖放排序,这是一个比较常见的应用场景。

  大~熊同学的粉丝数正在逼近三位数,感谢各位园友的支持,大~熊会继续努力的! 

  参考:

  • http://www.cnblogs.com/ijjyo/p/4316232.html 

  • http://www.cnblogs.com/linxin/p/6794542.html

 

 

以上是H5拖放API基礎篇的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板