2012-10-31 62 views
12

我想在原生javascript中創建一個可移動/可拖動的div,而不使用jquery和庫。是否有教程或任何註釋?在原生JavaScript中創建一個可拖動的div

+0

看看在這裏[http://stackoverflow.com/questions/9334084/moveable-draggable-div-using-javascript] – prageeth

+0

給你一個關於它是如何工作的基本概念:首先你需要將onmousedown和onmouseup事件處理程序附加到一個div 。然後,您需要將div的x和y座標更改爲指針位置的座標(但您必須考慮元素第一次拖動時的偏移量)。哦,不要忘記將元素的位置設置爲「絕對」 – KaeruCT

回答

15

好的,這裏是我用於輕量級部署的項目(使用庫的項目由於某種原因不允許或過度使用)。第一件事,第一,我一直用這個方便的功能,這樣我可以通過其中一個id或實際的DOM元素:

function get (el) { 
    if (typeof el == 'string') return document.getElementById(el); 
    return el; 
} 

作爲獎勵,get()短於document.getElementById()輸入和我的代碼最終短。

第二次意識到大多數圖書館正在做的是跨瀏覽器兼容性。如果所有瀏覽器的行爲相同,代碼就相當簡單。因此,讓我們寫一些跨瀏覽器功能來獲取鼠標位置:

function mouseX (e) { 
    if (e.pageX) { 
    return e.pageX; 
    } 
    if (e.clientX) { 
    return e.clientX + (document.documentElement.scrollLeft ? 
     document.documentElement.scrollLeft : 
     document.body.scrollLeft); 
    } 
    return null; 
} 

function mouseY (e) { 
    if (e.pageY) { 
    return e.pageY; 
    } 
    if (e.clientY) { 
    return e.clientY + (document.documentElement.scrollTop ? 
     document.documentElement.scrollTop : 
     document.body.scrollTop); 
    } 
    return null; 
} 

好的,上面的兩個函數是相同的。當然有更好的方法來編寫它們,但我現在保持相對簡單。

現在我們可以編寫拖放代碼。我喜歡這個代碼的事情是,所有東西都在一個閉包中捕獲,所以沒有全局變量或助手功能亂扔瀏覽器。此外,代碼將拖動手柄與正在拖動的對象分開。這對於創建對話框等非常有用。但如果不需要,您可以始終爲它們分配相同的對象。總之,這裏的代碼:

function dragable (clickEl,dragEl) { 
    var p = get(clickEl); 
    var t = get(dragEl); 
    var drag = false; 
    offsetX = 0; 
    offsetY = 0; 
    var mousemoveTemp = null; 

    if (t) { 
    var move = function (x,y) { 
     t.style.left = (parseInt(t.style.left)+x) + "px"; 
     t.style.top = (parseInt(t.style.top) +y) + "px"; 
    } 
    var mouseMoveHandler = function (e) { 
     e = e || window.event; 

     if(!drag){return true}; 

     var x = mouseX(e); 
     var y = mouseY(e); 
     if (x != offsetX || y != offsetY) { 
     move(x-offsetX,y-offsetY); 
     offsetX = x; 
     offsetY = y; 
     } 
     return false; 
    } 
    var start_drag = function (e) { 
     e = e || window.event; 

     offsetX=mouseX(e); 
     offsetY=mouseY(e); 
     drag=true; // basically we're using this to detect dragging 

     // save any previous mousemove event handler: 
     if (document.body.onmousemove) { 
     mousemoveTemp = document.body.onmousemove; 
     } 
     document.body.onmousemove = mouseMoveHandler; 
     return false; 
    } 
    var stop_drag = function() { 
     drag=false;  

     // restore previous mousemove event handler if necessary: 
     if (mousemoveTemp) { 
     document.body.onmousemove = mousemoveTemp; 
     mousemoveTemp = null; 
     } 
     return false; 
    } 
    p.onmousedown = start_drag; 
    p.onmouseup = stop_drag; 
    } 
} 

沒有爲稍微令人費解offsetX/offsetY計算的一個原因。如果你注意到,它只是將鼠標位置的差異加回到被拖動的div的位置。爲什麼不使用鼠標位置?那麼,如果你這樣做,當你點擊它時,div將跳轉到鼠標指針。這是我不想要的行爲。

+0

你有演示? – starbeamrainbowlabs

+1

上面的代碼是演示。複製粘貼到一個HTML文件(包括幫助函數),並調用頁面上的div的功能。 – slebetman

+0

注意:我也會把p.onmouseout = stop_drag;靠近鼠標事件結束。當我運行代碼時,有時候我的鼠標移動的速度比元素快,當鼠標脫離元素時,必須先點擊並釋放它,然後纔會停止動作。 –

14

你可以試試這個

HTML

<div id="one" style="height:50px; width:50px; border:1px solid #ccc; background:red;"> 
</div> 

JS腳本的可拖動DIV

window.onload = function(){ 
    draggable('one'); 
}; 

var dragObj = null; 
function draggable(id) 
{ 
    var obj = document.getElementById(id); 
    obj.style.position = "absolute"; 
    obj.onmousedown = function(){ 
      dragObj = obj; 
    } 
} 

document.onmouseup = function(e){ 
    dragObj = null; 
}; 

document.onmousemove = function(e){ 
    var x = e.pageX; 
    var y = e.pageY; 

    if(dragObj == null) 
     return; 

    dragObj.style.left = x +"px"; 
    dragObj.style.top= y +"px"; 
}; 

入住這Demo

+0

如何防止鼠標移動到左上角。我想將鼠標放在相對於在div中點擊的位置的位置 – Rod

+0

這非常簡單,我只是添加了一個小小的改變。爲了防止從dom中移除obj時的泄漏,obj.onmousedown處理程序不應該引用obj,它應該引用e.currentTarget。 – djabraham

+0

最佳解決方案。謝謝。 – modernator

-1
<div draggable=true ondragstart="event.dataTransfer.setData('text/plain', '12345')"> 
drag me 
</div> 

<div ondragover="return false;" ondrop="this.innerHTML=event.dataTransfer.getData('text/plain')"> 
drop on me 
</div> 
+1

酷,但可能不是什麼OP意味着「可拖動div」... –

8

此代碼糾正鼠標的位置(所以當你開始拖動拖動的對象不跳),並具有觸摸屏/手機的工作原理,以及

var dragObj = null; //object to be moved 
 
var xOffset = 0; //used to prevent dragged object jumping to mouse location 
 
var yOffset = 0; 
 
\t 
 
window.onload = function() 
 
{ 
 
\t document.getElementById("menuBar").addEventListener("mousedown", startDrag, true); 
 
\t document.getElementById("menuBar").addEventListener("touchstart", startDrag, true); 
 
} 
 

 
function startDrag(e) 
 
/*sets offset parameters and starts listening for mouse-move*/ 
 
{ 
 
\t e.preventDefault(); 
 
\t e.stopPropagation(); 
 
\t dragObj = e.target; 
 
\t dragObj.style.position = "absolute"; 
 
\t var rect = dragObj.getBoundingClientRect(); 
 
\t 
 
\t if(e.type=="mousedown") 
 
\t { 
 
\t \t xOffset = e.clientX - rect.left; //clientX and getBoundingClientRect() both use viewable area adjusted when scrolling aka 'viewport' 
 
\t \t yOffset = e.clientY - rect.top; 
 
\t \t window.addEventListener('mousemove', dragObject, true); 
 
\t } 
 
\t else if(e.type=="touchstart") 
 
\t { 
 
\t \t xOffset = e.targetTouches[0].clientX - rect.left; //clientX and getBoundingClientRect() both use viewable area adjusted when scrolling aka 'viewport' 
 
\t \t yOffset = e.targetTouches[0].clientY - rect.top; 
 
\t \t window.addEventListener('touchmove', dragObject, true); 
 
\t } 
 
} 
 

 
function dragObject(e) 
 
/*Drag object*/ 
 
{ 
 
\t e.preventDefault(); 
 
\t e.stopPropagation(); 
 
\t 
 
\t if(dragObj == null) return; // if there is no object being dragged then do nothing 
 
    else if(e.type=="mousemove") 
 
\t { 
 
\t \t dragObj.style.left = e.clientX-xOffset +"px"; // adjust location of dragged object so doesn't jump to mouse position 
 
\t \t dragObj.style.top = e.clientY-yOffset +"px"; 
 
\t } 
 
    else if(e.type=="touchmove") 
 
\t { 
 
\t \t dragObj.style.left = e.targetTouches[0].clientX-xOffset +"px"; // adjust location of dragged object so doesn't jump to mouse position 
 
\t \t dragObj.style.top = e.targetTouches[0].clientY-yOffset +"px"; 
 
\t } 
 
} 
 

 
document.onmouseup = function(e) 
 
/*End dragging*/ 
 
{ 
 
\t if(dragObj) 
 
\t { 
 
\t \t dragObj = null; 
 
\t \t window.removeEventListener('mousemove', dragObject, true); 
 
\t \t window.removeEventListener('touchmove', dragObject, true); 
 
\t } 
 
}
div{height:400px; width:400px; border:1px solid #ccc; background:blue; cursor: pointer;}
<div id="menuBar" >A</div>