在 JavaScript 中,当事件发生时,获取鼠标的位置是件很重要的事件。由于浏览器的不兼容性,不同浏览器分别在各自事件对象中定义了不同的属性,说明如下表所示。这些属性都是以像素值定义了鼠标指针的坐标,但是由于它们参照的坐标系不同,导致精确计算鼠标的位置比较麻烦。

属性及其兼容性

属性

说明

兼容性

clientX

以浏览器窗口左上顶角为原点,定位 x 轴坐标

所有浏览器,不兼容 Safari

clientY

以浏览器窗口左上顶角为原点,定位 y 轴坐标

所有浏览器,不兼容 Safari

offsetX

以当前事件的目标对象左上顶角为原点,定位 x 轴坐标

所有浏览器,不兼容 Mozilla

offsetY

以当前事件的目标对象左上顶角为原点,定位 y 轴坐标

所有浏览器,不兼容 Mozilla

pageX

以 document 对象(即文档窗口)左上顶角为原点,定位 x 轴坐标

所有浏览器,不兼容 IE

pageY

以 document 对象(即文档窗口)左上顶角为原点,定位 y 轴坐标

所有浏览器,不兼容 IE

screenX

计算机屏幕左上顶角为原点,定位 x 轴坐标

所有浏览器

screenY

计算机屏幕左上顶角为原点,定位 y 轴坐标

所有浏览器

layerX

最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 x 轴坐标

Mozilla 和 Safari

layerY

最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 y 轴坐标

Mozilla 和 Safari

示例1

下面介绍如何配合使用多种鼠标坐标属性,以实现兼容不同浏览器的鼠标定位设计方案。

首先,来看看 screenX 和 screenY 属性。这两个属性获得了所有浏览器的支持,应该说是最优选用属性,但是它们的坐标系时计算机屏幕,也就是说,以计算机屏幕左上角为定位原点。这对于以浏览器窗口为活动空间的网页来说没有任何价值。因为不同的屏幕分辨率,不同的浏览器窗口大小和位置,都使得在网页中定位鼠标成为一件很困难的事情。

其次,如果以 document 对象为坐标系,则可以考虑选用 pageX 和 pageY 属性实现在浏览器窗口中进行定位。这对于设计鼠标跟随来说是一个好主意,因为跟随元素一般都以绝对定位的方式在浏览器窗口中移动,在 mousemove 事件处理函数中把 pageX 和 pageY 属性值传递给跟绝对定位元素的 top 和 left样式属性即可。

IE 事件模型不支持上面的属性,为此还需寻求兼容 IE 的方法。而看 clientX 和 clientY 属性是以 window 对象为坐标系,且 IE 事件模型支持它们,可以选用它们。不过考虑 window 等对象可能出现的滚动条偏移量,所以还应加上相对于 window 对象的页面滚动的偏移量。

var posX = 0, posY = 0;

var event = event || window.event;

if (event.pageX || event.pageY) {

posX = event.pageX;

posY = event.pageY;

} else if (event.clientX || event.clientY) {

posX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;

posY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop;

}

在上面代码中,先检测 pageX 和 pageY 属性是否存在,如果存在则获取它们的值;如果不存在,则检测并获取 clientX 和 clientY 属性值,然后加上 document.documentElement 和 document.body 对象的 scrollLeft 和 scrollTop 属性值,这样在不同浏览器中就获得了相同的坐标值。

示例2

封装鼠标定位代码。设计思路:能够根据传递的具体对象,以及相对鼠标指针的偏移量,命令该对象能够跟随水保移动。

先定义一个封装函数,设计函数传入参数为对象引用指针、相对鼠标指针的偏移距离,以及事件对象。然后封装函数能够根据事件对象获取鼠标的坐标值,并设置该对象为绝对定位,绝对定位的值为鼠标指针当前的坐标值。

封装代码如下:

var pos = function (o, x, y, event) { //鼠标定位赋值函数

var posX = 0, posY = 0; //临时变量值

var e = event || window.event; //标准化事件对象

if (e.pageX || e.pageY) { //获取鼠标指针的当前坐标值

posX = e.pageX;

posY = e.pageY;

} else if (e.clientX || e.clientY) {

posX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;

posY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop;

}

o.style.position = "absolute"; //定义当前对象为绝对定位

o.style.top = (posY + y) + "px"; //用鼠标指针的y轴坐标和传入偏移值设置对象y轴坐标

o.style.left = (posX + x) + "px"; //用鼠标指针的x轴坐标和传入偏移值设置对象x轴坐标

}

下面测试封装代码。为 document 对象注册鼠标移动事件处理函数,并传入鼠标定位封装函数,传入的对象为

元素,设置其位置向鼠标指针右下方偏移(10,20)的距离。考虑到 DOM 事件模型通过参数形式传递事件对象,所以不要忘记在调用函数中还要传递事件对象。

鼠标追随

var div1 = document.getElementById("div1");

document.onmousemove = function (event) {

pos (div1, 10, 20, event);

}

示例3

获取鼠标指针在元素内的坐标。使用 offsetX 和 offsetY 属性可以实现这样的目标,但是 Mozilla 浏览器不支持。可以选用 layerX 和 layerY 属性来兼容 Mozilla 浏览器。

设计代码如下:

var event = event || window.event;

if (event.offsetX || event.offsetY) { //适用非Mozilla浏览器

x = event.offsetX;

y = event.offsetY;

} else if (event.layerX || event.layerY) { //兼容Mozilla浏览器

x = event.layerX;

y = event.layerY;

}

但是,layerX 和 layerY 属性是以绝对定位的父元素为参照物,而不是元素自身。如果没有绝对定位的父元素,则会以 document 对象为参照物。为此,可以通过脚本动态添加或者手动添加的方式,设计在元素的外层包围一个绝对定位的父元素,这样可以解决浏览器兼容问题。考虑到元素之间的距离所造成的误差,可以适当减去 1 个或几个像素的偏移量。

完整设计代码如下:

鼠标跟随

var t = document.getElementById("text");

var div1 = document.getElementById("div1");

div1.onmousemove = function (event) {

var event = event || window.event; //标准化事件对象

if (event.offsetX || event.offsetY) {

t.value = event.offsetX + "" + event.offsetY;

} else if (event.layerX || event.layerY) {

t.value = (event.layerX-1) + "" + (event.layerY-1);

}

}

这种做法能够解决在元素内部定位鼠标指针的问题。但是,由于在元素外面包裹了一个绝对定位的元素,会破坏整个页面的结构布局。在确保这种人为方式不会导致结构布局混乱的前提下,可以考虑选用这种方法。

js 获取鼠标在画布的位置_JS获取鼠标位置(鼠标坐标)相关推荐

  1. js 如何拿到后天的时间_js获取日期及日期相关js方法 积累总结

    js获取日期 常用如下: var date = new Date();//中国标准时间 var year = date.getFullYear();//获取完整的年份(4位) var month = ...

  2. js 如何拿到后天的时间_js 获取前天、昨天、今天、明天、后天的时间-阿里云开发者社区...

    js获取日期:前天.昨天.今天.明天.后天 - Liehuo.Net function GetDateStr(AddDayCount) { var dd = new Date(); dd.setDat ...

  3. js判断时间是早上还是下午_JS获取时间显示上午,下午 | 学步园

    时间显示  站长学院 www.pigzz.com var timerID = null; var timerRunning = false; function stopclock (){ if(tim ...

  4. 获取某个输入框的字符长度_js获取及控制文本框的字符长度

    html: 最多输入500字,目前已经输入0字 TextMode="MultiLine" Height="72px" style="WORD-BREA ...

  5. js 获取鼠标在画布的位置_云凤蝶如何打造媲美 sketch 的自由画布

    在 Design Tools 中,组件间的对齐与吸附功能是否好用是决定其画布是否可以高效进行产品设计的关键因素.云凤蝶作为一款快速制作高品质中后台应用的 hpaPaaS 平台,同样拥有自由拖拽的可视化 ...

  6. WPF 获取鼠标屏幕位置、窗口位置、控件位置

    原文:WPF 获取鼠标屏幕位置.窗口位置.控件位置 public struct POINT{public int X;public int Y;public POINT(int x, int y){t ...

  7. JS在页面渲染一个div,用鼠标点击鼠标随意拖动该元素,当鼠标松开时,该元素会停在鼠标松开的页面位置。

    <style>#goods {width: 100px;height: 100px;border-radius: 50%;position: fixed;background-color: ...

  8. js鼠标移动到指定位置_Python: pyautogui模块之鼠标控制

    文章背景:PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以用程序自动控制鼠标和键盘操作,利用它可以实现自动化任务.pyautogui模块中包含了一些函数,可以模拟鼠标移动.按键和 ...

  9. js 获取当前gmt时间_js获取当前时区GMT

    1:js获取当前时区GMT 首先引入插件: // 获取当前时区GMT var timezone = jstz.determine(); var Asia = timezone.name(); 2:字符 ...

最新文章

  1. 下一代构建工具 Gradle ,比 Maven 强在哪里!
  2. linux doc下生成学号,linux的.doc
  3. “复制粘贴”发明人,竟是物理学博士转行做程序媛!
  4. 20155308 《信息安全系统设计基础》课程总结
  5. OpenGL multiviewport多个视口的实例
  6. 烂泥:【解决】word复制windows live writer没有图片
  7. 让你成为高效的Web开发者的10个步骤
  8. 2021大二实训part01
  9. 蓝桥杯 ALGO-66 算法训练 字符串编辑
  10. 测试工程师在软件测试阶段依据,北京软件测试工程师建立软件测试管理与评判体系...
  11. JVM运行机制理解整理
  12. 通过jQuery的比较来认识AngularJS
  13. Android 四大组件学习之Service四
  14. 产品经理必须要掌握的数据分析能力
  15. 如何使用QT?步骤详解
  16. 天池比赛如何使用docker提交
  17. iOS 自动布局报错:Unable to simultaneously satisfy constraints.
  18. 写给未来的入职为程序员的人工智能专业的高考生的选专业看法
  19. VS2013+Windows+CPU下搭建caffe框架并利用mnist数据集实验
  20. 用EasyX图形库画一个哆啦A梦

热门文章

  1. docker以及docker-compose 使用加速器部署
  2. 非标自动化设备发展现状如何?
  3. Linux修改系统时间、时区
  4. beforeSend 出现跨域问题,header里直接设置token就没问题----Day1
  5. 基础实验——485传感器修改地址
  6. 免费、高清、无版权图片都从哪里找?
  7. 复旦提出ObjectFormer,收录CVPR 2022!图像篡改检测新工作!
  8. 自建免费的代理ip池
  9. api有哪些 javasocket_简单hello/hi程序、分析及Java Socket API与Linux Socket API对比
  10. Windows下tracert命令