前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JavaScript 获取鼠标及元素在页面上的位置

JavaScript 获取鼠标及元素在页面上的位置

作者头像
HTML5学堂
发布于 2018-03-13 05:48:18
发布于 2018-03-13 05:48:18
3.6K00
代码可运行
举报
文章被收录于专栏:HTML5学堂HTML5学堂
运行总次数:0
代码可运行

HTML5学堂:JavaScript获取鼠标的位置,大家会想到clientX/Y等属性,灵活的获取鼠标的位置信息,能够便于我们实现各种复杂的页面交互效果,到底还有哪些属性可以获取鼠标的位置信息?另外,还有哪些能快速获取标签在页面中的位置信息?

在书写一些“拖拽”页面交互效果,比如常见的拖拽效果、自定滚动条、放大镜等效果,都需要用到了鼠标或元素在页面上的位置信息。为了能够快速、灵活的获取鼠标位置信息,今天要带着大家来接触的不是利用clientX/Y获取鼠标的位置信息,而是利用了大家可能比较少用的两个属性layerX/Y和offsetX/Y,它们与clientX/Y有着很大的差别。另外,也要跟大家分享一个方法,它能快速的获取元素在页面上的位置信息,不同于之前学过的offsetLeft等属性,它就是——getBoundingClientRect()方法

回顾clientX/Y获取鼠标位置的方式

虽然clientX/Y是比较常用的属性,但是咱们还是再回顾一下吧,方便于区分下面要给大家介绍的属性。

代码实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5Course - 独行冰海、梦幻雪冰 | HTML5学堂</title>
    <link rel="stylesheet" href="reset.css">
    <script type="text/javascript" src="jquery-1.8.3.min.js"></script>
    <style>
        .wrap {
            width: 200px;
            height: 200px;
            margin: 50px;
            padding: 40px;
            border: 1px solid blue;
        }
        .outer {
            width: 150px;
            height: 150px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="outer" id="outerBox">
        </div>
    </div>
    <script type="text/javascript">
        var outerEle = document.getElementById('outerBox');
 
        outerEle.onclick = function(e) {
            console.log(e.clientX);
        }
    </script>
</body>
</html>

代码解析:

  1. 从代码中可以看出,clientX/Y属性是事件对象(e)里面的一个属性;
  2. clientX/Y属性获取的鼠标位置是相对于浏览器可视区域的左上角的距离。咱们都知道浏览器的可视区域位置是固定的不发生滚动的,所以,clientX/Y属性获取的鼠标位置不会随页面滚动而改变;
  3. 兼容性:所有浏览器都能支持。

可以简单的对clientX/Y属性进行概括,它所获取的鼠标位置参考的原点就是浏览器可视区域的左上角。就是这一点,导致我们使用起来灵活性不高,不是所有页面交互效果用到的鼠标位置都是参考浏览器可视区域的左上角,有可能是参考自身元素的左上角,那么clientX/Y属性能否胜任呢?于是开始“度娘”、“谷哥”……终于发现了两个不是很起眼的属性:layerX/Y和offsetX/Y属性。

layerX/Y和offsetX/Y属性

这两个属性跟clientX/Y属性一样,也是事件对象里面的一个属性,但是它们有何区别呢?别急,咱们一个一个的来分析

layerX/Y属性的说明

layerX/Y获取到的鼠标位置是参考被触发元素左上角的距离

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
outerEle.onclick = function(e) {
    // 处理事件对象兼容
    var e = e || window.event;
 
    console.log(e.layerX);
}

在click事件中把e.clientX换成e.layerX,然后进行测试。你是不是有疑问了,想跟堡堡说:我测试出来跟e.clientX没啥区别啊。没错,如果你觉得没啥区别才是对的。layerX/Y属性有点坑,如果想让鼠标的位置参考的是自身元素的左上角,需要给自身元素设置position(属性值不能是static | inherit),否则默认参考document文档区域的左上角。

在outer选择器里面添加position属性,具体属性值根据需求来进行设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.outer {
    position: relative;
    width: 150px;
    height: 150px;
    background-color: skyblue;
}

添加完了代码,再测试一下,是不是达到你想要的效果了~

可是,可是,它的浏览器支持程度会让你有一种淡淡的忧伤,堡堡心理苦,但是堡堡不说~

兼容性:IE6/7/8不支持,IE9+和Chrome、Safari、Firefox都支持

友情提醒:在IE10+的浏览器,获取到的鼠标位置会存在一堆的小数,如39.66999816894531这样。

我们真的要放弃了IE6/7/8不可,于是来尝试一下offsetX|Y属性,看这个属性会不会更强大?

offsetX/Y属性的说明

offsetX/Y获取到鼠标位置也是参考被触发元素的左上角

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
outerEle.onclick = function(e) {
    // 处理事件对象兼容
    var e = e || window.event;
 
    console.log(e.offsetX);
}

在click事件中把e.layerX换成e.offsetX,然后进行测试。发现这个属性还真不错,还能兼容IE6/7/8。

堡堡在网上看到很多博客中写道offsetX/Y属性火狐浏览器不支持,但是自己去测试了一下火狐浏览器,火狐浏览器是可以支持该属性,并不是网上说的那样。导致这种状况发生的原因可能是现在火狐浏览器开始支持该属性了,另外也要告诉大家——实践是检验真理的唯一标准。

兼容性:IE和Chrome、Safari均完美支持,Firefox也能支持(具体需要看浏览器的版本)

虽然它兼容性挺完美的,但是还有一点点的瑕疵。在outer选择器里面,设置border,并进行测试,查看结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.outer {
    width: 150px;
    height: 150px;
    border: 10px solid gray;
    background-color: skyblue;
}

如果鼠标在边框上触发会返回负值,内容区以内为正值,换句话说鼠标位置是参考自身元素内容区域的左上角(不包括border)。

简要概括这两个属性

当触发元素设置了position属性(属性值不能是static | inherit),layerX/Y和offsetX/Y就成为了友好的朋友,基本上相同,唯一不同的是,layerX/Y属性是以border左上角为原点,offsetX/Y属性是以内容左上角为原点

用getBoundingClientRect()获取页面元素位置信息

大家估计会经常用到offsetLeft、offsetTop等属性来获取元素的尺寸、位置等信息,想具体了解的可以回复“元素信息”到HTML5学堂公众号。

今天要给大家分享的是另外一种快速获取元素在页面上的位置,赶紧尝试书写一下下面的实例

代码实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5Course - 独行冰海、梦幻雪冰 | HTML5学堂</title>
    <link rel="stylesheet" href="reset.css">
    <script type="text/javascript" src="jquery-1.8.3.min.js"></script>
    <style>
        .wrap {
            width: 200px;
            height: 200px;
            margin: 50px;
            padding: 40px;
            border: 1px solid blue;
        }
        .outer {
            width: 150px;
            height: 150px;
            border: 10px solid gray;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="outer" id="outerBox">
        </div>
    </div>
    <script type="text/javascript">
        // 通过ID的方式获取标签
        var outerEle = document.getElementById('outerBox');
 
        console.log(outerEle.getBoundingClientRect());
    </script>
</body>
</html>

代码解析:

  1. 使用getBoundingClientRect()方法。它返回一个对象,其中包含了left、right、top、bottom四个属性,这四个属性分别代表什么含义,具体来看下面的分析图
  1. 兼容性:IE、Firefox、Chrome都支持该方法 看到它的支持程度算是挺完美的,但是总会有一点点的瑕疵,在IE中,默认参考原点是从(2,2)开始计算,导致最终距离会比其它浏览器多出两个像素,因此咱们需要对它进行兼容处理了。
  2. 在IE中有一个小问题,在非IE浏览器下document.documentElement.clientTop/left值为0,而在在IE中document.documentElement.clientTop/left并不为0,而是2(尽管对html、body设置了margin和padding都为0),所以为了让getBoundingClientRect()方法兼容性更好,在IE中需要减去document.documentElement.clientTop/left的值,这样就更完美了。

完整代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML5Course - HTML5学堂 | 独行冰海、梦幻雪冰</title>
    <link rel="stylesheet" href="reset.css">
    <script type="text/javascript" src="jquery-1.8.3.min.js"></script>
    <style>
        .wrap {
            width: 200px;
            height: 200px;
            margin: 50px;
            padding: 40px;
            border: 1px solid blue;
        }
        .outer {
            width: 150px;
            height: 150px;
            border: 10px solid gray;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="outer" id="outerBox">
        </div>
    </div>
    <script type="text/javascript">
        var outerEle = document.getElementById('outerBox');
 
        /*
         * [getBoundingClientRect 获取页面元素的位置]
         * @param  {[obj]} ele [目标元素]
         * @return {[obj]}     [对象]
         * @author HTML5学堂 | 刘国利、陈能堡
         */
        function getBoundingClientRect(ele) {
            var top     = document.documentElement.clientTop, 
                left    = document.documentElement.clientLeft,
                rect    = ele.getBoundingClientRect();
 
            // document.documentElement.clientTop/Left在IE下获取到的值为2,非IE获取到的值为0;
            // 这样保证在各个浏览器的效果都是一致的
 
            // 分别减去多出来的2px
            return {
                top: rect.top - top,
                right: rect.right - left,
                bottom: rect.bottom - top,
                left: rect.left - left
            }
        }
 
        // 调用方法
        console.log(getBoundingClientRect(outerEle));
    </script>
</body>
</html>

HTML5学堂小编-堡堡,耗时5h。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-07-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 懂点君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何用 Python 和循环神经网络预测严重交通拥堵?
本文为你介绍,如何从 Waze 交通事件开放数据中,利用序列模型找到规律,进行分类预测。以便相关部门可以未雨绸缪,提前有效干预可能发生的严重拥堵。
王树义
2018/12/25
1.6K0
Deep learning with Python 学习笔记(5)
用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一样,深度学习模型不会接收原始文本作为输入,它只能处理数值张量。文本向量化(vectorize)是指将文本转换为数值张量的过程。它有多种实现方法
范中豪
2019/09/10
6940
Deep learning with Python 学习笔记(5)
递归模型的语言处理入门:双向rnn,编码器和词嵌入
双向RNN是RNN的一种变体,它对于自然语言处理任务特别有用,并且有时可以提高性能。
deephub
2021/03/25
5480
递归模型的语言处理入门:双向rnn,编码器和词嵌入
手把手教你在Python中实现文本分类(附代码、数据集)
文本分类是商业问题中常见的自然语言处理任务,目标是自动将文本文件分到一个或多个已定义好的类别中。文本分类的一些例子如下:
数据派THU
2018/07/30
12.7K2
手把手教你在Python中实现文本分类(附代码、数据集)
深度学习多分类案例:新闻文本分类
之前介绍过一个单分类的问题。当每个数据点可以划分到多个类别、多个标签下,这就是属于多分类问题了。
皮大大
2022/04/02
1.6K0
深度学习多分类案例:新闻文本分类
关于深度学习系列笔记十五(循环神经网络)
‰ 提取单词或字符的 n-gram,并将每个 n-gram 转换为一个向量。n-gram 是多个连续单词或字符的集合(n-gram 之间可重叠)。
python与大数据分析
2022/03/11
6370
关于深度学习系列笔记十五(循环神经网络)
Keras文本数据预处理范例——IMDB影评情感分类
本文将以IMDB电影评论数据集为范例,介绍Keras对文本数据预处理并喂入神经网络模型的方法。
lyhue1991
2020/07/20
1.3K0
利用RNN进行中文文本分类(数据集是复旦中文语料)
数据预处理参考利用TfidfVectorizer进行中文文本分类(数据集是复旦中文语料) ,现在我们有了分词后的train_jieba.txt和test_jieba.txt,看一下部分内容:
西西嘛呦
2020/10/28
1.2K0
利用RNN进行中文文本分类(数据集是复旦中文语料)
Python人工智能 | 二十一.CNN和Word2Vec中文文本分类详解及与机器学习分类对比
从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前一篇文章分享了Keras实现RNN和LSTM的文本分类算法,并与传统的机器学习分类算法进行对比实验。这篇文章我们将继续巩固文本分类知识,主要讲解CNN实现中文文本分类的过程,并与贝叶斯、决策树、逻辑回归、随机森林、KNN、SVM等分类算法进行对比。注意,本文以代码为主,文本分类叙述及算法原理推荐阅读前面的文章。基础性文章,希望对您喜欢~
Eastmount
2023/02/28
3.3K0
Python人工智能 | 二十一.CNN和Word2Vec中文文本分类详解及与机器学习分类对比
RNN,具有记忆功能神经网络的理解与实现
我们当前掌握的网络类型,统称为feed forward网络。这种网络的特点是,当我们把很多条数据输入网络进行训练时,网络没有“记忆性”,也就是网络认为前一条输入的数据与下一条输入的数据之间没有任何联系。然而在实际运用中,输入的数据间往往存在着强联系,特别是在自然语言处理中。
望月从良
2018/09/29
1.3K0
RNN,具有记忆功能神经网络的理解与实现
中文NLP笔记:8. 基于LSTM的文本分类
  有些句子即使把词的顺序打乱,还是可以看懂这句话在说什么,有时候词的顺序打乱,句子意思就变得面目全非
杨熹
2019/02/20
3.6K0
中文NLP笔记:8. 基于LSTM的文本分类
使用预先训练好的单词向量识别影评的正负能量
上一节我们讨论路单词向量化的算法原理。算法的实现需要有大量的数据,一般而言你要收集到单词量在四十亿左右的文本数据才能通过上一节的算法训练处精准的单词向量,问题在于你很难获取如此巨量的数据来训练单词向量,那你该怎么办呢?
望月从良
2018/09/29
7150
使用预先训练好的单词向量识别影评的正负能量
Keras文本分类实战(下)
在上一节Keras文本分类实战(上),讲述了关于NLP的基本知识。这部分,将学会以不同方式将单词表示为向量。
用户3578099
2019/08/15
1.2K0
教程 | 用TensorFlow Estimator实现文本分类
选自ruder.io 作者:Sebastian Ruder 机器之心编译 参与:Geek AI、张倩 本文探讨了如何使用自定义的 TensorFlow Estimator、嵌入技术及 tf.layers 模块来处理文本分类任务,使用的数据集为 IMDB 评论数据集。通过本文你将学到如何使用 word2vec 词嵌入和迁移学习技术,在有标签数据稀缺时获得更好的模型性能。 本文主要内容如下: 使用 Datasets 装载数据 使用预封装好的评估器(estimator)构建基线 使用词嵌入技术 通过卷积层和 LS
机器之心
2018/06/08
2K0
文本挖掘(四)python电影评论情感分类模型 -- 基于keras的全连接神经网络
  使用消极、积极两类电影评论集,构建对情感分类模型,并后续用于预测。由于只有两类,因此是一个二分类模型。
forxtz
2021/04/01
1.2K0
文本挖掘(四)python电影评论情感分类模型 -- 基于keras的全连接神经网络
使用CNN,RNN和HAN进行文本分类的对比报告
你好,世界!!我最近加入Jatana.ai 担任NLP研究员(实习生and),并被要求使用深度学习模型研究文本分类用例。在本文中,我将分享我的经验和学习,同时尝试各种神经网络架构。我将介绍3种主要算法,例如:
银河1号
2019/04/12
1.3K0
使用CNN,RNN和HAN进行文本分类的对比报告
用于NLP的Python:使用Keras的多标签文本LSTM神经网络分类
在本文中,我们将看到如何开发具有多个输出的文本分类模型。我们将开发一个文本分类模型,该模型可分析文本注释并预测与该注释关联的多个标签。多标签分类问题实际上是多个输出模型的子集。在本文结尾,您将能够对数据执行多标签文本分类。
拓端
2020/09/25
3.5K0
使用TensorFlow 2.0的LSTM进行多类文本分类
关于NLP的许多创新都是如何将上下文添加到单词向量中。常用的方法之一是使用递归神经网络。以下是递归神经网络的概念:
代码医生工作室
2019/12/19
4.3K0
使用TensorFlow 2.0的LSTM进行多类文本分类
RNN示例项目:详解使用RNN撰写专利摘要
我第一次尝试研究RNN时,我试图先学习LSTM和GRU之类的理论。在看了几天线性代数方程之后(头疼的要死),我在Python深度学习中发生了以下这段话:
AiTechYun
2018/12/12
1.8K0
RNN示例项目:详解使用RNN撰写专利摘要
深度学习文本分类实战报告:CNN, RNN &amp; HAN
本文为 AI 研习社编译的技术博客,原标题 : Report on Text Classification using CNN, RNN & HAN 翻译 | 小猪咪、莫尔•约瑟夫、M.Y. Li
AI研习社
2018/12/05
1.3K0
推荐阅读
相关推荐
如何用 Python 和循环神经网络预测严重交通拥堵?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验