徐州网站建设的特点,做网站手机端需要pc端的源代码吗,wordpress当前分类id,佛山专业网站建设公司推荐前言
鼠标跟随框的作用如下图所示#xff0c;可以在前端页面上#xff0c;为我们后续的鼠标操作进行提示说明#xff0c;提升用户的体验。本文将通过多种方式去实现#xff0c;从而满足不同场景下的需求。 实现原理
实现鼠标跟随框的原理很简单#xff0c;就是监听鼠标在…前言
鼠标跟随框的作用如下图所示可以在前端页面上为我们后续的鼠标操作进行提示说明提升用户的体验。本文将通过多种方式去实现从而满足不同场景下的需求。 实现原理
实现鼠标跟随框的原理很简单就是监听鼠标在页面上的坐标然后利用相对定位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 idmouse-position-demo classNamemouse-position-demoButton onClick{() {setVisible(true)}}点击显示/ButtonButton onClick{() {setVisible(false)}}点击关闭/Button{/* 鼠标跟随框 */}MousePositionModalvisible{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 (dividmouse-position-modalclassNamemouse-position-modalstyle{{ left: ${left}px, top: ${top}px, visibility: ${visible ? visible : hidden}}}div classNamemouse-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 (dividmouse-position-modalclassNamemouse-position-modalstyle{{ left: ${left}px, top: ${top}px, visibility: ${visible ? visible : hidden}}}div classNamemouse-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 idmouse-position-demo classNamemouse-position-demoMousePositionModal2visible{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 (dividmouse-position-modalclassNamemouse-position-modalstyle{{ left: ${x}px, top: ${y}px, visibility: ${visible ? visible : hidden} }}div classNamemouse-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;}
}最后
本文结合实例详细的介绍了鼠标跟随框在三种场景下的三种具体实现的方法。如果大家有好的实现方式或者好的建议欢迎提出来一起交流~