2013-08-25 42 views
11

Im đấu tranh với vẻ như là một bài tập javascript đơn giản, viết một thao tác kéo và thả vani. Tôi nghĩ rằng Im thực hiện một sai lầm với 'addeventlisteners' của tôi, đây là mã:Mã kéo và thả đơn giản

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

Trả lời

11

Dưới đây là một jsfiddle với nó làm việc: http://jsfiddle.net/fpb7j/1/

Có 2 vấn đề chính, trước hết là việc sử dụng các onmousedown, onmousemoveonmouseup. Tôi tin rằng những người chỉ được sử dụng với các sự kiện kèm theo:

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

khi mousedown, mousemovemouseup là dành cho người nghe sự kiện:

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

Vấn đề thứ hai là vòng lặp do-while trong trường hợp di chuyển chức năng. Chức năng này được gọi mỗi khi chuột di chuyển một pixel, vì vậy vòng lặp không cần thiết:

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

Bằng cách này, tôi phải làm cho vị trí của mục tiêu tuyệt đối cho nó hoạt động.

+0

Cám ơn trả lời chi tiết. Tôi đã sử dụng Do While cho mousemove trong khi mousedown đang hoạt động, nếu không nó sẽ không chạy ... nếu tôi kích hoạt vòng lặp Do While, Firefox sẽ dừng lại. – Kayote

+0

@Kayote I gotcha, mặc dù nó sẽ không cần thiết do mức độ thường xuyên sự kiện 'mousemove' gọi' eleMouseMove() ' – iRector

+0

Tôi cập nhật nó một chút cho yêu cầu của tôi. Nó có thể hữu ích cho những người khác nữa, do đó http://jsfiddle.net/kjwLe9bq/ chia sẻ. – Savaratkar

11

bạn có thể thử fiddle này quá, 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

Tại sao bạn sử dụng offsetX/Y? –

+0

Để dừng việc kéo có thể kéo vào con trỏ chuột. Tôi hiểu rồi. –

1

Tôi đã chỉ cần thực hiện một kéo đơn giản.

Đó là một cách sử dụng một liner, và nó xử lý những thứ như bù đắp của chuột đến góc trên bên trái của phần tử, onDrag/onStop callbacks, và các yếu tố SVG kéo

Đây là mã.

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

và sử dụng nó:

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

Bạn cũng có thể sử dụng onDrag và callbacks onStop:

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

Kiểm tra repo của tôi ở đây để biết thêm chi tiết: https://github.com/lingtalfi/simpledrag