2015年4月27日 星期一

Html5 drag anywhere

後記:
目前支援這個功能的,測試後FireFox還是最完整。
Chrome是半殘,dragover(判別該區塊是否可以drop的部份)在本機上運作是正常的,但要是放到網路上的網頁就會取不到值event.dataTransfer的資料,然後就會出現問題。
基本上就是在 drag_over時,讓他抓不到event.dataTransfer.getData時,讓他event.preventDefault(); 是就可以解決Chrome的問題(但這樣就不會出現禁止放置的圖示,弱了一點)
但還好drop時抓值是正確的,變成drop時要判斷好一點,誰能放誰不能放,擋掉就可以解決了。
-----------------------------------------------------------------

以往要做到網頁元件的拖拉,第一個想到的就是 jquery ui (jquery ui真的非常強大@@/)

但現在有個新的選擇,HTML5就開始內建這個功能了~
好站w3school 點出~在 IE9 應該就可以使用了~
http://www.w3schools.com/html/html5_draganddrop.asp

先說的是~HTML的用法與 jquery 不同~可能概念上也有點差異~
目前感覺起來,jquery是偏functional的使用(比較好上手)~
而HTML5在整體上似乎定義的更清楚(功能比較完整喔)~

先來看HTML5上的操作行為~找到一個網站寫得很讚~
這網站做為讀HTML5的參考書應該不錯~
http://apress.jensimmons.com/v5/pro-html5-programming/ch9.html

在HTML5上實作,要求一定要同時定義上 drag 和 drop 的部分才能運作。
(jquery可以只寫 draggable)
所以若只要 drag 的功能時,重點把他想成全部(body)都可以 drop 就是了~

另外在HTML5上,drag的每個階段,都要自己撰寫定義,缺點是有點麻煩,好處是會寫的話,變化可以很多,還有會顯示一個小icon (口跟禁止)來表示能不能放在那邊(小icon也可以改圖),相對來說UX是做得比較完整的~

HTML碼
一般可隨便拖的都是浮動在網頁上 ,Style基本上就是 position:absolute; float:left。
另外加入 HTML5 新attribute  draggable="true"
<div id="mydrag" draggable="true"
    style="position:absolute; float:left; right: 10px; top: 50px; width:50px; height:50px; border: solid 1px #AAAAAA;">Drag Me</div>


自訂function
//在開始拖拉時,就先將該項目之id,位置寫進 dataTransfer,以便後面判斷取用
function drag_start(event) {
    var style = window.getComputedStyle(event.target, null);
    event.dataTransfer.setData("pos",
        (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
    var dragdid = event.target.id;
    event.dataTransfer.setData("did", dragdid);
}
//在放開時,將該div改變位置移動放到新的位置
function drop(event) {
    var offset = event.dataTransfer.getData("pos").split(',');
    var dm = document.getElementById( event.dataTransfer.getData("did") );
    dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
    dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';   
    event.preventDefault();
    return false;
}
//不限制也不管他,(ondragover、dragover 這兩個行為還是不一樣,但在此期望的操作方式上,可以一起用)
function drag_over(event) {
    event.preventDefault();
    return false;
}

元件設定初始,可利用 js 的方式加入,
或是在該 div 上直接寫上event, ex : dragstart="drag_start(event)",
不過在外面統一加入比較好分工~
    var dm = document.getElementById('mydrag');
    dm.addEventListener('dragstart',drag_start,false);
    document.body.addEventListener('ondragover',drag_over,false);
    document.body.addEventListener('dragover',drag_over,false);
    document.body.addEventListener('drop',drop,false);

要注意的是~雖然已經將body設為可以drop的部分~
但是~若是網頁沒有填滿整個螢幕(通常是高的部分,沒到底的話),是不能放的XD...

沒有留言: