整理下PC和移動獲取點擊、移動坐標的代碼和坑


一、PC

PC是通過鼠標點擊和移動,相對比較簡單,比如onmousedown、onmouseup、onmousemove、onmouseout鼠標按鍵按下、按鍵起來、鼠標在元素上移動、鼠標從元素上離開。

canvas.onmousedown = function(e) {
    console.log(e.clientX, e.clientY);
}
canvas.onmouseup = function(e) {
    console.log(e.clientX, e.clientY);
}
canvas.onmousemove = function(e) {
    console.log(e.clientX, e.clientY);
}
canvas.onmouseout = function(e) {
    console.log(e.clientX, e.clientY);
}

PC端可以直接通過事件的clientX和clientY來獲取點擊的坐標,這個坐標(e.clientX , e.clientY)是相對於window的左上角來確定的。

同樣事件參數evnet,有一些常用方法如阻止事件在瀏覽器中的默認操作和事件冒泡。

e.preventDefault()為阻止事件在瀏覽器中的默認操作,如input type為submit時的提交操作,我一般在事件函數中都會使用它,特別是在移動端。記得之前有個坑,在微信內置瀏覽器中,touchmove事件觸發時,微信內置瀏覽器會默認拖動整個WebView向上或向下移動,顯示出那個QQ瀏覽器內核什么鬼的文字,而沒有執行想要的操作。

e.stopPropagation()為防止事件穿透,不調用此方法時,事件被捕獲后,仍然會繼續傳播可能會被下方的元素事件所捕獲進而造成影響。所以在元素覆蓋元素,且都有綁定事件的時候需要阻止事件冒泡。

 

二、移動

移動和PC在處理事件上有些不同之處,首先事件上不同,移動這邊是touchstart、touchmove、touchend這3個事件。

canvas.addEventListener("touchstart", function(e) {
    console.log(e.touches[0].pageX, e.touches[0].pageY);
});
canvas.addEventListener("touchmove", function(e) {
    if(e.touches.length > 1 || e.scale && e.scale !== 1) return;
    console.log(e.touches[0].pageX, e.touches[0].pageY);
});
canvas.addEventListener("touchend", function(e) {});

移動端由於是手指操作而非鼠標,所以存在多點觸控,即多根手指在屏幕上觸發事件。所以,不在跟PC一樣,通過e.clientX來獲取單個點坐標。而是事件event中存在一個觸控集合touches這個數組,通過取數組的第一個元素來獲取坐標位置,即第一個觸碰屏幕手指的坐標(e.touches[0].pageX , e.touches[0].pageY)。而有時往往有需要獲取全部觸碰點的位置,那就要循環數組了,逐個處理。另一個坑就是有時要防止多點觸碰,以及手指對屏幕進行縮放的影響,可以加入以上判斷if(e.touches.length > 1 || e.scale && e.scale != 1)。

最后就是touchend事件,代表手指離開屏幕不存在觸控,所以e.touches這個數組的長度為0,也就不能在touchend的處理函數中獲取pageX屬性了。

 

三、元素內的位置

通過以上方法獲取的坐標是以window左上角為原點的坐標,但是在實際中,往往獲取的是以某個元素左上角為原點的坐標,這時就需要做個轉化。以canvas為例

function windowToCanvas(x, y) { //window坐標轉canvas坐標
    return {
        x: Math.round(x - document.getElementById("canvas").getBoundingClientRect().left - document.body.scrollLeft),
        y: Math.round(y - document.getElementById("canvas").getBoundingClientRect().top - document.body.scrollTop)
    }
}
 
        

getBoundingClientRect()方法可以獲取元素的盒子模型,通過top、left、right、bottom這4個屬性可以拿到四周的邊距。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM