首页IT科技react滚动组件(React实现多个场景下鼠标跟随提示框详解)

react滚动组件(React实现多个场景下鼠标跟随提示框详解)

时间2025-08-04 23:11:11分类IT科技浏览5028
导读:前言 鼠标跟随框的作用如下图所示,可以在前端页面上,为我们后续的鼠标操作进行提示说明,提升用户的体验。本文将通过多种方式去实现,从而满足不同场景下的需求。...

前言

鼠标跟随框的作用如下图所示               ,可以在前端页面上                       ,为我们后续的鼠标操作进行提示说明        ,提升用户的体验                。本文将通过多种方式去实现               ,从而满足不同场景下的需求                       。

实现原理

实现鼠标跟随框的原理很简单                       ,就是监听鼠标在页面上的坐标        ,然后利用相对定位(position: relative;)               、绝对定位(position: absolute;)和固定定位(position: fixed;)等相关知识       。

本文是利用的 React       ,但只要知道原理                       ,技术栈什么的问题都不大        。具体怎么实现                ,咱接着往下看                       。

固定定位实现

固定定位的好处是       ,相对于浏览器窗口定位                      ,而鼠标跟随框的通用场景就是跟随鼠标移动               。

MousePositionDemo

我们先写一个页面                ,用来引入鼠标跟随框:

index.tsx

import React, { useEffect, useState } from react; import ./index.less; import { Button } from antd; import MousePositionModal from ./MousePositionModal; const MousePositionDemo = () => { const [visible, setVisible] = useState(false); return ( <div id="mouse-position-demo" className="mouse-position-demo"> <Button onClick={() => { setVisible(true) }}>点击显示</Button> <Button onClick={() => { setVisible(false) }}>点击关闭</Button> {/* 鼠标跟随框 */} <MousePositionModal visible={visible} content="鼠标跟随" defaultPosition={{ x: 32, y: 32 }} /> </div> ) } export default MousePositionDemo;

index.less

.mouse-position-demo { margin: 0 auto; height: 500px; width: 500px; background-color: #fff; padding: 24px 24px; }

MousePositionModal

这里我们首先通过 clientX, clientY 来返回当事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平和垂直坐标        。

当然,仅这样可能是不够的                      ,我们会发现在鼠标靠近浏览器页面最右侧的时候                       ,鼠标跟随框的部分页面会被隐藏掉                       。为了能够完整的展示鼠标跟随框中的信息,我们需要进行一个简单的计算               ,当 鼠标位置的横坐标 > 鼠标位置横坐标 - 鼠标选择框的宽度 时                       ,就让 鼠标跟随框的横坐标 = 鼠标位置横坐标 - 鼠标选择框的宽度               。

鼠标跟随框的具体实现如下:

index.tsx

import React, { useState, useEffect } from react; import ./index.less; interface IMousePositionModal { visible: boolean; content: string; defaultPosition: { x: number, y: number } } const MousePositionModal = (props: IMousePositionModal) => { const { visible, content, defaultPosition } = props; const [left, setLeft] = useState(defaultPosition.x); const [top, setTop] = useState(defaultPosition.y); useEffect(() => { if (visible) { show(); } }, [visible]); const show = () => { const modal = document.getElementById(mouse-position-modal); if (modal) { document.onmousemove = (event) => { const { clientX, clientY } = event || window.event; const clientWidth = document.body.clientWidth || document.documentElement.clientWidth; const { offsetWidth } = modal; let x = clientX + 18; const y = clientY + 18; if (x >= clientWidth - offsetWidth) { x = clientWidth - offsetWidth; } setLeft(x); setTop(y); }; } }; return ( <div id="mouse-position-modal" className="mouse-position-modal" style={{ left: `${left}px`, top: `${top}px`, visibility: `${visible ? visible : hidden}`}} > <div className="mouse-position-modal-content">{content}</div> </div> ); }; export default MousePositionModal;

这里有两个地点需要注意:一是给鼠标跟随框设置固定定位        ,二是要将 z-index 的值设置的足够大               ,不然有可能会被页面上的其他元素遮住。

index.less

.mouse-position-modal { min-width: 240px; height: 57px; background: #fff; box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15); border-radius: 4px; position: fixed; z-index: 2000; padding: 8px 12px; .mouse-position-modal-content { font-size: 16px; color: #262626; } }

绝对定位(相对于整个浏览器窗口)

利用绝对定位我们可以实现和上面固定定位相似的效果                       ,但是有个隐患需要注意        ,如果鼠标跟随框的某个相近的父元素用了相对定位       ,那鼠标跟随框的实际位置就可能会乱套了                       。

绝对定位不仅要考虑可视范围内的位置                       ,还需要考虑浏览器页面滚动的距离                      。

具体实现如下:

MousePositionDemo

和固定定位一样

MousePositionModal

index.tsx

import React, { useState, useEffect } from react; import ./index.less; interface IMousePositionModal { visible: boolean; content: string; defaultPosition: { x: number, y: number } } const MousePositionModal = (props: IMousePositionModal) => { const { visible, content, defaultPosition } = props; const [left, setLeft] = useState(defaultPosition.x); const [top, setTop] = useState(defaultPosition.y); useEffect(() => { if (visible) { show(); } }, [visible]); const show = () => { const modal = document.getElementById(mouse-position-modal); if (modal) { document.onmousemove = (event) => { const { clientX, clientY, pageX, pageY } = event || window.event; const sl = document.body.scrollLeft || document.documentElement.scrollLeft; const st = document.body.scrollTop || document.documentElement.scrollTop; const clientWidth = document.body.clientWidth || document.documentElement.clientWidth; const { offsetWidth } = modal; let x = (pageX || clientX + sl) + 18; const y = (pageY || clientY + st) + 18; if (x >= clientWidth - offsetWidth) { x = clientWidth - offsetWidth; } setLeft(x); setTop(y); }; } }; return ( <div id="mouse-position-modal" className="mouse-position-modal" style={{ left: `${left}px`, top: `${top}px`, visibility: `${visible ? visible : hidden}`}} > <div className="mouse-position-modal-content">{content}</div> </div> ); }; export default MousePositionModal;

index.less

.mouse-position-modal { min-width: 240px; height: 57px; background: #fff; box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15); border-radius: 4px; position: absolute; z-index: 2000; padding: 8px 12px; .mouse-position-modal-content { font-size: 16px; color: #262626; } }

绝对定位和相对定位(相对于鼠标跟随框的父元素)

有时候我们可能并不需要在整个页面进行鼠标跟随框的提示                ,在某些情况下只需要鼠标在进入页面的部分区域才进行提示。

如下图所示:

这个时候就需要同时用到绝对定位和相对定位以及 offsetX 和 offsetY                。

offsetX: 规定了事件对象与目标节点的内填充边(padding edge)在 X 轴方向上的偏移量 offsetY: 规定了事件对象与目标节点的内填充边(padding edge)在 Y 轴方向上的偏移量

具体实现如下:

MousePositionDemo

index.tsx

import React, { useEffect, useState } from react; import ./index.less; import { Button } from antd; import MousePositionModal2 from ./MousePositionModal2; // 兼容offsetX const getOffsetX = (e: any) =>{ const event = e || window.event; const srcObj = e.target || e.srcElement; if (event.offsetX){ return event.offsetX; }else{ const rect = srcObj.getBoundingClientRect(); const clientx = event.clientX; return clientx - rect.left; } } // 兼容offsetY const getOffsetY = (e: any) => { const event = e || window.event; const srcObj = e.target || e.srcElement; if (event.offsetY){ return event.offsetY; }else{ const rect = srcObj.getBoundingClientRect(); const clientx = event.clientY; return clientx - rect.top; } } const MousePositionDemo = () => { const [visible, setVisible] = useState(false); const [defaultPosition, setDefaultPosition] = useState({ x: 32, y: 32 }) useEffect(() => { const ele = document.getElementById(mouse-position-demo) as HTMLElement; ele.addEventListener(mouseenter, show) ele.addEventListener(mousemove, mouseMove) ele.addEventListener(mouseleave, hide) return () => { ele.removeEventListener(mouseenter, show) ele.removeEventListener(mousemove, mouseMove) ele.removeEventListener(mouseleave, hide) } }, []) const show = () => { setVisible(true) } const hide = () => { setVisible(false) } const mouseMove = (e: MouseEvent) => { let x = getOffsetX(e) + 18; const y = getOffsetY(e) + 18; setDefaultPosition({ x, y }); } return ( <div id="mouse-position-demo" className="mouse-position-demo"> <MousePositionModal2 visible={visible} content="鼠标跟随" defaultPosition={defaultPosition} /> </div> ) } export default MousePositionDemo;

注意要将这里 position 设置为 relative                       。

index.less

.mouse-position-demo { margin: 0 auto; height: 500px; width: 500px; background-color: #fff; padding: 24px 24px; position: relative; }

MousePositionModal2

index.tsx

import React, { useState, useEffect } from react; import ./index.less; interface IMousePositionModal { visible: boolean; content: string; defaultPosition: { x: number, y: number } } const MousePositionModal2 = (props: IMousePositionModal) => { const { visible, content, defaultPosition } = props; const { x, y } = defaultPosition; return ( <div id="mouse-position-modal" className="mouse-position-modal" style={{ left: `${x}px`, top: `${y}px`, visibility: `${visible ? visible : hidden}` }} > <div className="mouse-position-modal-content">{content}</div> </div> ); }; export default MousePositionModal2;

注意要将这里 position 设置为 absolute        。

index.less

.mouse-position-modal { min-width: 240px; height: 57px; background: #fff; box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.15); border-radius: 4px; position: absolute; z-index: 2000; padding: 8px 12px; .mouse-position-modal-content { font-size: 16px; color: #262626; } }

最后

本文结合实例       ,详细的介绍了鼠标跟随框在三种场景下的三种具体实现的方法

以上就是React实现多个场景下鼠标跟随提示框详解的详细内容                      ,更多关于React鼠标跟随提示框的资料请关注本站其它相关文章!

声明:本站所有文章                ,如无特殊说明或标注,均为本站原创发布                。任何个人或组织                      ,在未征得本站同意时                       ,禁止复制                       、盗用        、采集               、发布本站内容到任何网站                       、书籍等各类媒体平台                       。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理       。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
织梦使用教程(织梦调用当前会员发布的文章总数)