2013-08-25 32 views
11

Zmagam się z pozornie prostym ćwiczeniem javascript, pisząc o przeciągnięciu i upuszczeniu wanilii. Myślę Im pomyłki z moich „addeventlisteners”, oto kod:Prosty kod "przeciągnij i upuść"

var ele = document.getElementsByClassName ("target")[0]; 
var stateMouseDown = false; 
//ele.onmousedown = eleMouseDown; 
ele.addEventListener ("onmousedown" , eleMouseDown , false); 

function eleMouseDown() { 
    stateMouseDown = true; 
    document.addEventListener ("onmousemove" , eleMouseMove , false); 
} 

function eleMouseMove (ev) { 
    do { 
     var pX = ev.pageX; 
     var pY = ev.pageY; 
     ele.style.left = pX + "px"; 
     ele.style.top = pY + "px"; 
     document.addEventListener ("onmouseup" , eleMouseUp , false); 
    } while (stateMouseDown === true); 
} 

function eleMouseUp() { 
    stateMouseDown = false; 
    document.removeEventListener ("onmousemove" , eleMouseMove , false); 
    document.removeEventListener ("onmouseup" , eleMouseUp , false); 
} 

Odpowiedz

11

Oto jsfiddle z nim pracować: http://jsfiddle.net/fpb7j/1/

Były 2 główne problemy, pierwszy jest wykorzystanie onmousedown, onmousemove i onmouseup. Wierzę, że to są tylko do użytku z dołączonych wydarzeń:

document.body.attachEvent('onmousemove',drag); 

podczas mousedown, mousemove i mouseup są dla słuchaczy imprezy:

document.body.addEventListener('mousemove',drag); 

Drugim problemem był do-while w przypadku ruchu funkcjonować. Że funkcja na miano każdym razem, gdy mysz porusza piksel, więc pętla nie jest potrzebna:

var ele = document.getElementsByClassName ("target")[0]; 
ele.addEventListener ("mousedown" , eleMouseDown , false); 

function eleMouseDown() { 
    stateMouseDown = true; 
    document.addEventListener ("mousemove" , eleMouseMove , false); 
} 

function eleMouseMove (ev) { 
    var pX = ev.pageX; 
    var pY = ev.pageY; 
    ele.style.left = pX + "px"; 
    ele.style.top = pY + "px"; 
    document.addEventListener ("mouseup" , eleMouseUp , false); 
} 

function eleMouseUp() { 
    document.removeEventListener ("mousemove" , eleMouseMove , false); 
    document.removeEventListener ("mouseup" , eleMouseUp , false); 
} 

Nawiasem mówiąc, miałem zrobić stanowisko celowi absolutny go do pracy.

+0

Dzięki za szczegółowa odpowiedź. Używałem Do Do dla mousemove gdy mousedown jest aktywne, w przeciwnym razie nie powinno działać ... jeśli włączę pętlę Do While, Firefox zatrzymuje się. – Kayote

+0

@Kayote Mam gotcha, choć nie będzie to konieczne ze względu na to, jak często zdarzenie 'mousemove' wywołuje' eleMouseMove() ' – iRector

+0

Zaktualizowałem trochę, aby spełnić moje wymagania. Może być pomocny również dla innych, a więc udostępnianie przez http://jsfiddle.net/kjwLe9bq/. – Savaratkar

11

można spróbować tej skrzypce też http://jsfiddle.net/dennisbot/4AH5Z/

<!doctype html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8"> 
<title>titulo de mi pagina</title> 
<style> 
    #target { 
     width: 100px; 
     height: 100px; 
     background-color: #ffc; 
     border: 2px solid blue; 
     position: absolute; 
    } 
</style> 
<script> 
    window.onload = function() { 
     var el = document.getElementById('target'); 
     var mover = false, x, y, posx, posy, first = true; 
     el.onmousedown = function() { 
      mover = true; 
     }; 
     el.onmouseup = function() { 
      mover = false; 
      first = true; 
     }; 
     el.onmousemove = function(e) { 
      if (mover) { 
       if (first) { 
        x = e.offsetX; 
        y = e.offsetY; 
        first = false; 
       } 
       posx = e.pageX - x; 
       posy = e.pageY - y; 
       this.style.left = posx + 'px'; 
       this.style.top = posy + 'px'; 
      } 
     }; 
    } 
</script> 
</head> 
<body> 
    <div id="target" style="left: 10px; top:20px"></div> 
</body> 
</html> 
+0

Dlaczego używasz offsetX/Y? –

+0

Aby zatrzymać przeciąganie przeskakiwania do wskaźnika myszy. Rozumiem. –

1

Właśnie wykonane prostego przeciągania.

Jest to jeden Wykorzystanie liniowej i obsługuje rzeczy jak przesunięcie myszy do lewego górnego rogu elementu, onDrag/OnStop wywołań zwrotnych, a elementy SVG przeciągając

Oto kod.

// simple drag 
function sdrag(onDrag, onStop) { 
    var startX = 0; 
    var startY = 0; 
    var el = this; 
    var dragging = false; 

    function move(e) { 
     el.style.left = (e.pageX - startX) + 'px'; 
     el.style.top = (e.pageY - startY) + 'px'; 
     onDrag && onDrag(el, e.pageX, startX, e.pageY, startY); 
    } 

    function startDragging(e) { 
     if (e.currentTarget instanceof HTMLElement || e.currentTarget instanceof SVGElement) { 
      dragging = true; 
      var left = el.style.left ? parseInt(el.style.left) : 0; 
      var top = el.style.top ? parseInt(el.style.top) : 0; 
      startX = e.pageX - left; 
      startY = e.pageY - top; 
      window.addEventListener('mousemove', move); 
     } 
     else { 
      throw new Error("Your target must be an html element"); 
     } 
    } 

    this.addEventListener('mousedown', startDragging); 
    window.addEventListener('mouseup', function (e) { 
     if (true === dragging) { 
      dragging = false; 
      window.removeEventListener('mousemove', move); 
      onStop && onStop(el, e.pageX, startX, e.pageY, startY); 
     } 
    }); 
} 

Element.prototype.sdrag = sdrag; 

i go używać:

document.getElementById('my_target').sdrag(); 

Można również użyć onDrag i OnStop zwrotnych:

document.getElementById('my_target').sdrag(onDrag, onStop); 

Sprawdź mój repo tutaj po więcej szczegółów: https://github.com/lingtalfi/simpledrag