2012-10-31 14 views
12

Chcę utworzyć ruchomy/przeciągalny div w macierzystym javascript bez użycia jquery i bibliotek. Czy istnieje samouczek lub coś innego?Tworzenie przeciągalnego elementu div w macierzystym javascript

+0

Spójrz tutaj [http://stackoverflow.com/questions/9334084/moveable-draggable-div-using-javascript] – prageeth

+0

Aby dać ci podstawowe pojęcie jak to działa: najpierw musisz załączyć onmousedown i onmouseup narzędzia obsługi zdarzeń do div . Następnie musisz zmienić współrzędne X i Y diva na położenie wskaźnika (ale musisz wziąć pod uwagę przesunięcie, z którego element został po raz pierwszy przeciągnięty).Aha, i nie zapomnij ustawić pozycji elementu na "absolutny" – KaeruCT

Odpowiedz

15

OK, oto mój osobisty kod, którego używam do lekkich wdrożeń (projekty, w których korzystanie z biblioteki jest z jakiegoś powodu niedozwolone lub przesadne). Pierwszą rzeczą po pierwsze, zawsze korzystać z tej funkcji spożywczy tak, że mogę przechodzić albo identyfikatora lub rzeczywistego elementu DOM:

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

jako bonus, get() jest krótszy niż wpisywać document.getElementById() i mój kod kończy się krótsze.

Po drugie, zdajesz sobie sprawę, że większość bibliotek robi kompatybilność z różnymi przeglądarkami. Jeśli wszystkie przeglądarki zachowują się tak samo, kod jest dość banalny. Napiszmy więc funkcje w różnych przeglądarkach, aby uzyskać pozycję myszy:

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; 
} 

OK, powyższe dwie funkcje są identyczne. Są na pewno lepsze sposoby na ich pisanie, ale na razie utrzymuję je (stosunkowo) proste.

Teraz możemy napisać kod przeciągnij i upuść. To, co podoba mi się w tym kodzie, to to, że wszystko zostało przechwycone w jednym zamknięciu, więc nie ma żadnych zmiennych globalnych ani funkcji pomocniczych zaśmiecających przeglądarkę. Ponadto kod oddziela uchwyt przeciągnięcia od przeciąganego obiektu. Jest to przydatne przy tworzeniu okien dialogowych itp. Ale jeśli nie jest to konieczne, zawsze można przypisać im ten sam obiekt. Tak czy inaczej, oto kod:

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; 
    } 
} 

Jest powód, dla nieco zawiłe offsetX/offsetY obliczeń. Jeśli zauważysz, to tylko różnica między pozycjami myszy i dodanie ich z powrotem do pozycji przeciągniętego div. Dlaczego po prostu nie używać pozycji myszy? Jeśli to zrobisz, div przejdzie do wskaźnika myszy po kliknięciu. Którego zachowania nie chciałem.

+0

Masz demo? – starbeamrainbowlabs

+1

Powyższy kod jest demo. Skopiuj go do pliku html (łącznie z funkcjami pomocniczymi) i wywołaj funkcję na div na stronie. – slebetman

+0

UWAGA: Chciałbym również umieścić p.onmouseout = stop_drag; pod koniec zdarzenia myszy. Kiedy uruchamiałem kod, czasami moja mysz poruszała się szybciej niż element, a kiedy mysz się z niego wyłączyła, trzeba najpierw kliknąć i zwolnić, zanim przestanie działać. –

14

Można spróbować tej

HTML

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

Js Script dla Draggable 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"; 
}; 

Sprawdź to Demo

+0

Jak powstrzymać go od przesunięcia myszy do lewego górnego rogu. Chciałbym zostawić mysz tam, gdzie została upuszczona względem miejsca, w którym została kliknięta w div – Rod

+0

To jest niesamowite i proste, właśnie dodałem jedną drobną zmianę. Aby zapobiec wyciekom, jeśli obiekt zostanie usunięty z domeny, obiekt obj.onmousedown nie powinien odwoływać się do obiektu obj, powinien odwoływać się do e.currentTarget. – djabraham

+0

Najlepsze rozwiązanie. Dzięki. – 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

Fajnie, ale prawdopodobnie nie to, co OP oznacza "przeciągalny div" ... –

8

Kod ten koryguje pozycję myszy (tak przeciągany obiekt nie skakać po rozpoczęciu przeciągania) i współpracuje z ekranami dotykowymi/telefonów oraz

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>

Powiązane problemy