目前,有兩種使用JavaScript的方法來實現拖放功能,系統拖放和類比拖放。
首先,我們要明白的是系統拖放是IE only的,也就是說目前只有在IE上才能實現系統拖放。
對於系統拖放,IE預設給我們並讓我們Drag的元素並不多,其中有圖片,文本和連結。當我們拖動一個元素時,會觸發以下事件:
ondragstart:當按下滑鼠按鍵,開始移動滑鼠時,在被拖動的項上觸發的事件。
ondrag:ondragstart出發後,ondrag會一直出發,只要對象還在拖動,就一直觸發。
ondragend:當拖動停止時(在有效或無效的放置對象上放下該項),則觸發ondragend事件
而目的對象,也就是要Drop的元素上觸發的事件為:
ondragenter:當對象被拖放到有效放置目標上,會觸發ondragenter事件。
ondragover:在dragenter事件發生後,將立即觸發dragover事件,當被拖動的項在放置目標的邊界內時,將一直觸發。
ondragleave:當項被拖出放置目標後,dragover事件停止觸發,並且觸發dragleave事件。
ondrop:如果唄拖放的項正好是在這個目標上放下的,則會觸發drop事件。
一般來說,被拖動的項的事件總是先發生,除了drop事件要比dragend先觸發。因此,將一個對象拖動到兩一個對象所觸發的事件的順序如下:
ondragstart->ondrag->ondragenter->ondragover->(ondragleave|ondrop)->ondragend
但是僅僅拖放是毫無用處的,除非資料能真正受到影響,IE是引入event的一個特性,dataTransfer對象來協助進行資料轉送的。該對象有兩個方法,getData()和setData(),getData()用來擷取由setData()儲存的值。可以設定兩種類型的資料:普通文本和URL;dataTransfer還可以用來判斷,對被拖放的物體以及目標可以做哪種類型的動作。這主要通過兩個特性來完成,dropEffect和effectAllowed,dropEffect用很多值可供選擇,如copy,move等。它只能在ondragstart事件中初始化。如下的例子:
<br /> function handleDragDropEvent(oEvent)<br /> {<br /> switch(oEvent.type)<br /> {<br /> case "dragstart":<br /> oEvent.dataTransfer.effectAllowed="move";<br /> break;<br /> case "dragenter":<br /> // oEvent.dataTransfer.dropEffect="move";<br /> oEvent.returnValue=false;<br /> break;<br /> case "dragover":<br /> oEvent.returnValue=false;<br /> break;<br /> case "drop":<br /> oEvent.returnValue=false;<br /> oEvent.srcElement.innerHTML=oEvent.dataTransfer.getData("text");<br /> }<br /> }<br />
<p><input type="text" value="drag this text" ondragstart="handleDragDropEvent(event)"></p><p>
前面我們學了如何建立自己的放置目標,dragDrop方法可以讓我們建立自己的拖動目標.通過調用dragDrop方法來初始化系統拖動對象,可以讓一般情況下不能拖動的項觸發dragstart,drag和dragend事件
<br /> function handleMouseMove(oEvent)<br /> {<br /> if(oEvent.button==1)<br /> {<br /> oEvent.srcElement.dragDrop();<br /> }<br /> }<br /> function handleDragDropEvent(oEvent)<br /> {<br /> oEvent.dataTransfer.setData("text","This is a red square");<br /> }<br />
</p>This is a red<p>
而在非IE要實現拖放怎麼辦呢,這是就要用到虛擬拖放,虛擬拖放的思想很簡單:建立可以跟著滑鼠移動的絕對位置層,執行個體代碼如下:
<br /> var iDiffX=0;//滑鼠橫座標和div橫座標之間的差值<br /> var iDiffY=0;//滑鼠縱座標和div縱座標之間的差值<br /> function handleMouseMove()<br /> {<br /> var oEvent=window.event;<br /> var oDiv=document.getElementById("div1");<br /> oDiv.style.left=oEvent.clientX-iDiffX;<br /> oDiv.style.top=oEvent.clientY-iDiffY;<br /> }<br /> function handleMouseDown()<br /> {<br /> var oEvent=window.event;<br /> var oDiv=document.getElementById("div1");<br /> iDiffX=oEvent.clientX-oDiv.offsetLeft;//offsetLeft返回當前元素的左邊界到它的包含元素的左邊界的位移量,以像素為單位<br /> iDiffY=oEvent.clientY-oDiv.offsetTop;//offsetTop返回當前元素的上邊界到它的包含元素的上邊界的位移量,以像素為單位。<br /> document.body.attachEvent("onmousemove",handleMouseMove);<br /> document.body.attachEvent("onmouseup",handleMouseUp);<br /> }<br /> function handleMouseUp()<br /> {<br /> var oEvent=window.event;<br /> document.body.detachEvent("onmousemove",handleMouseMove);<br /> document.body.detachEvent("onmouseup",handleMouseUp);<br /> if(isOverDropTarget(oEvent.clientX,oEvent.clientY))<br /> {<br /> var oDiv=document.getElementById("div1");<br /> var oTarget=document.getElementById("divDropTarget");<br /> oDiv.style.left=oTarget.offsetLeft;<br /> oDiv.style.top=oTarget.offsetTop;<br /> }<br /> }<br /> //該方法接受一個座標作為參數,如果座標在放置目標內,則返回True;<br /> function isOverDropTarget(iX,iY)<br /> {<br /> var oTarget=document.getElementById("divDropTarget");<br /> var iX1=oTarget.offsetLeft;<br /> var iX2=iX1+oTarget.offsetWidth;//offsetWidth返回元素的寬度<br /> var iY1=oTarget.offsetTop;<br /> var iY2=iY1+oTarget.offsetHeight;//offsetHeight返回元素的高度<br /> return (iX>=iX1&&iX=iY1&&iY
<br /> #div1<br /> {<br /> background-color:red;<br /> height:100px;<br /> width:100px;<br /> position:absolute;<br /> z-index:10;<br /> }<br /> #divDropTarget<br /> {<br /> background-color:blue;<br /> height:200px;<br /> width:200px;<br /> position:absolute;<br /> left:300px;<br /> }<br />
<p>