一、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个属性可以拿到四周的边距。

整理下PC和移动获取点击、移动坐标的代码和坑的更多相关文章

  1. (java)selenium webdriver学习,选择模块,点击下一页,获取当前url

    selenium webdriver学习,选择模块,点击下一页,获取当前url 查找下一页有多种方法,这里列举两种: isSelected()函数用于判断是否点击选中,返回Boolean类型 impo ...

  2. jQuery获取点击对象的父级

    一.使用$('body').on('click','.index',function(event){})绑定事件时,例: <div class="project-box"&g ...

  3. win7下用python3.3获取cable modem的设备信息

    毕业一年多了,一直做cable modem的测试,总是觉得在国内这一行的人才很少,想找个师傅真的很不容易. 苦闷了许久之后,终于决定,自己去写点东西,万一就找到同行了呢? 下面就是本小姐写的第一篇博客 ...

  4. Android tabhost下的activity怎样获取传来的值

    android tabhost下的activity怎样获取传来的值,具体解决方案如下: 解决方案: 其他activity设置intent:Intent intent=new Intent(); int ...

  5. 基于定位下拉框或者需要点击link才显示的下拉框,二次定位与多次定位实现的实际效果区别

    还是基于上次那个练习的后续出现的思考,http://www.cnblogs.com/8013-cmf/p/6555790.html 界面: 源码: 写法如下:  继续解释这两种的区别: 1.其实基于定 ...

  6. ios下,<input type="checkbox"> 点击时出现黑色块

    ios下,<input type="checkbox"> 点击时出现黑色块如下图 解决方法:

  7. 清流,获取点击的img路径

    清流: <div style="clear:both"></div> 获取img的路径到TextBox3内: //获取展示的头像的集合var _heads ...

  8. 百度“搜索设置”之基于定位下拉框或者需要点击link才显示的下拉框,二次定位与多次定位实现的实际效果区别

    还是基于上次那个练习的后续出现的思考,http://www.cnblogs.com/8013-cmf/p/6555790.html 界面: 源码: 写法如下:  继续解释这两种的区别: 1.其实基于定 ...

  9. 页面中php传值后循环列表js获取点击的id

    页面中php传值后循环列表js获取点击的id值进行js操作 <script type="text/javascript" src="__PUBLIC__/js/jq ...

随机推荐

  1. 4.4 使用STM32控制MC20进行GPS帧数据解析

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  2. easyui-combobox 中多选的默认值设置、获取多选值及JS包含字符串、删除字符串

    1.项目中使用到combobox的多选值及相关操作,不多说,直接上代码: <input id="education" name="education" c ...

  3. Python进阶(4)_进程与线程 (python并发编程之多进程)

    一.python并发编程之多进程 1.1 multiprocessing模块介绍 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大 ...

  4. 利用onresize使得div可以随着屏幕大小而自适应的代码

    原文:http://www.jb51.net/article/21831.htm 当我们让div居中时候,一般有两种方法,一种是固定左右宽度,也就是使用像素绝对定位:另一种是用百分比来相对定位,在这种 ...

  5. Service degrade

    服务降级:主要是针对非正常情况下的应急服务措施;比如电商平台,在针对618.双11等高峰情形下采用部分服务不出现或者延时出现的情形. 为什么是非正常情况下呢,比如我要出差,如果经常出差的话,要带的衣服 ...

  6. FTP下载

    import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import ja ...

  7. matlab fread

    Matlab中fread函数用法    “fread”以二进制形式,从文件读出数据. 语法1:[a,count]=fread(fid,size,precision) 语法2:[a,count]=fre ...

  8. codeforces 435B

    题意:只能对相邻的两个数字进行交换,允许k次交换,输出交换能得到的最大的数.从最高位开始寻找最优,每次寻找能交换的步数里交换到的最大值进行交换. #include<cstdio> #inc ...

  9. hql join

    文章一: 1.用hql语句 ` String hql="select student.id, student.name ,class.name from student映射实体类名 as s ...

  10. 如何使用REST请求风格

    REST:即 Representational State Transfer.(资源)表现层状态转化.是目前最流行的一种互联网软件架构. 它结构清晰.符合标准.易于理解.扩展方便, 所以正得到越来越多 ...