2015-10-23 14 views
5

Tôi đang cố gắng để thực hiện một chức năng kéo-như sử dụng các mô hình tiếp theo:cảm ứng Move sự kiện không sa thải sau khi chạm vào Bắt đầu mục tiêu được lấy ra

  • Theo dõi Marker kiện Pointer Down.
  • Khi sự kiện Xuống kích hoạt đăng ký các sự kiện Di chuyển và Di chuyển cửa sổ trên Màn hình và xóa điểm đánh dấu.
  • Thực hiện một số thao tác trong khi Di chuyển.
  • Khi sự kiện Up kích hoạt hủy đăng ký khỏi Di chuyển và Lên.

Điều này phù hợp với sự kiện chuột nhưng không hoạt động đối với sự kiện Chạm. Chúng không cháy sau khi phần tử mục tiêu Touch Start bị xóa. Tôi đã cố gắng sử dụng Pointer Events Polyfill nhưng nó không hoạt động.

Tôi đang sử dụng Công cụ Chrome Dev để mô phỏng sự kiện chạm. Xem mẫu:

initTestBlock('mouse', { 
 
    start: 'mousedown', 
 
    move: 'mousemove', 
 
    end: 'mouseup' 
 
}); 
 
initTestBlock('touch', { 
 
    start: 'touchstart', 
 
    move: 'touchmove', 
 
    end: 'touchend' 
 
}); 
 
initTestBlock('touch-no-remove', { 
 
    start: 'touchstart', 
 
    move: 'touchmove', 
 
    end: 'touchend' 
 
}, true); 
 

 
function initTestBlock(id, events, noRemove) { 
 
    var block = document.getElementById(id); 
 
    var parent = block.querySelector('.parent'); 
 
    var target = block.querySelector('.target'); 
 
    target.addEventListener(events.start, function(e) { 
 
    console.log(e.type); 
 
    if (!noRemove) { 
 
     setTimeout(function() { 
 
     // Remove target 
 
     target.parentElement.removeChild(target); 
 
     }, 1000); 
 
    } 
 

 
    function onMove(e) { 
 
     console.log(e.type); 
 
     var pt = getCoords(e); 
 
     parent.style.left = pt.x + 'px'; 
 
     parent.style.top = pt.y + 'px'; 
 
    } 
 

 
    function onEnd(e) { 
 
     console.log(e.type); 
 
     window.removeEventListener(events.move, onMove); 
 
     window.removeEventListener(events.end, onEnd); 
 
    } 
 

 
    window.addEventListener(events.move, onMove); 
 
    window.addEventListener(events.end, onEnd); 
 

 
    }); 
 
} 
 

 
// Returns pointer coordinates 
 
function getCoords(e) { 
 
    if (e instanceof TouchEvent) { 
 
    return { 
 
     x: e.touches[0].pageX, 
 
     y: e.touches[0].pageY 
 
    }; 
 
    } 
 
    return { 
 
    x: e.pageX, 
 
    y: e.pageY 
 
    }; 
 
} 
 

 
window.addEventListener('selectstart', function() { 
 
    return false; 
 
}, true);
.parent { 
 
    background: darkred; 
 
    color: white; 
 
    width: 10em; 
 
    height: 10em; 
 
    position: absolute; 
 
} 
 
.target { 
 
    background: orange; 
 
    width: 4em; 
 
    height: 4em; 
 
} 
 
#mouse .parent { 
 
    left: 0em; 
 
} 
 
#touch .parent { 
 
    left: 11em; 
 
} 
 
#touch-no-remove .parent { 
 
    left: 22em; 
 
}
<div id="mouse"> 
 
    <div class="parent">Mouse events 
 
    <div class="target">Drag here</div> 
 
    </div> 
 
</div> 
 
<div id="touch"> 
 
    <div class="parent">Touch events 
 
    <div class="target">Drag here</div> 
 
    </div> 
 
</div> 
 
<div id="touch-no-remove"> 
 
    <div class="parent">Touch (no remove) 
 
    <div class="target">Drag here</div> 
 
    </div> 
 
</div>

+0

Tôi gặp sự cố liên quan. Bạn đã tìm thấy một giải pháp trong khi đó? –

+0

@SebastianvomMeer Xem câu trả lời của tôi http://stackoverflow.com/a/34980275/4137472 –

Trả lời

2

Bí quyết là để che giấu yếu tố cho đến khi kết thúc liên lạc di chuyển, nhưng không phải để xoá bỏ nó. Dưới đây là một số ví dụ (kích hoạt chế độ cảm ứng trong Chrome Dev Tools và chọn một số thiết bị hoặc sử dụng thiết bị thực): https://jsfiddle.net/alexanderby/na3rumjg/

var marker = document.querySelector('circle'); 
 
var onStart = function(startEvt) { 
 
    startEvt.preventDefault(); // Prevent scroll 
 
    marker.style.visibility = 'hidden'; // Hide target element 
 
    var rect = document.querySelector('rect'); 
 
    var initial = { 
 
    x: +rect.getAttribute('x'), 
 
    y: +rect.getAttribute('y') 
 
    }; 
 
    var onMove = function(moveEvt) { 
 
    rect.setAttribute('x', initial.x + moveEvt.touches[0].clientX - startEvt.touches[0].clientX); 
 
    rect.setAttribute('y', initial.y + moveEvt.touches[0].clientY - startEvt.touches[0].clientY); 
 
    }; 
 
    var onEnd = function(endEvt) { 
 
    window.removeEventListener('touchmove', onMove); 
 
    window.removeEventListener('touchend', onEnd); 
 
    marker.removeEventListener('touchstart', onStart); 
 
    marker.parentElement.removeChild(marker); // Remove target element 
 
    }; 
 
    window.addEventListener('touchmove', onMove); 
 
    window.addEventListener('touchend', onEnd); 
 
}; 
 
marker.addEventListener('touchstart', onStart);
<svg> 
 
    <circle r="20" cx="50" cy="20" cursor="move"/> 
 
    <rect x="10" y="50" width="80" height="80" /> 
 
</svg>

3

Thật vậy, according to the docs,

Nếu yếu tố mục tiêu được xóa khỏi tài liệu, sự kiện sẽ vẫn là được nhắm mục tiêu vào đó và do đó sẽ không nhất thiết phải bong bóng lên đến cửa sổ hoặc tài liệu nữa. Nếu có bất kỳ nguy cơ nào của một phần tử bị xóa trong khi nó đang được chạm vào, cách tốt nhất là đính kèm các liên lạc trực tiếp vào mục tiêu .

Nó chỉ ra rằng giải pháp là để đính kèm touchmovetouchend nghe đến event.target chính nó, ví dụ:

element.addEventListener("touchstart", (event) => { 
    const onTouchMove =() => { 
     // handle touchmove here 
    } 
    const onTouchEnd =() => { 
     event.target.removeEventListener("touchmove", onTouchMove); 
     event.target.removeEventListener("touchend", onTouchEnd); 
     // handle touchend here 
    } 
    event.target.addEventListener("touchmove", onTouchMove); 
    event.target.addEventListener("touchend", onTouchEnd); 
    // handle touchstart here 
}); 

Thậm chí nếu các yếu tố event.target được lấy ra từ DOM, các sự kiện sẽ tiếp tục sa thải bình thường và đưa ra tọa độ chính xác.

+1

Điều này đã cứu ngày của tôi! : D – raeffs

Các vấn đề liên quan