最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React實現(xiàn)多個場景下鼠標跟隨提示框詳解

 更新時間:2022年09月30日 14:13:58   作者:xmanlin  
這篇文章主要為大家介紹了React實現(xiàn)多個場景下鼠標跟隨提示框詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

鼠標跟隨框的作用如下圖所示,可以在前端頁面上,為我們后續(xù)的鼠標操作進行提示說明,提升用戶的體驗。本文將通過多種方式去實現(xiàn),從而滿足不同場景下的需求。

實現(xiàn)原理

實現(xiàn)鼠標跟隨框的原理很簡單,就是監(jiān)聽鼠標在頁面上的坐標,然后利用相對定位(position: relative;)、絕對定位(position: absolute;)和固定定位(position: fixed;)等相關知識。

本文是利用的 React,但只要知道原理,技術棧什么的問題都不大。具體怎么實現(xiàn),咱接著往下看。

固定定位實現(xiàn)

固定定位的好處是,相對于瀏覽器窗口定位,而鼠標跟隨框的通用場景就是跟隨鼠標移動。

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 來返回當事件被觸發(fā)時鼠標指針相對于瀏覽器頁面(或客戶區(qū))的水平和垂直坐標。

當然,僅這樣可能是不夠的,我們會發(fā)現(xiàn)在鼠標靠近瀏覽器頁面最右側(cè)的時候,鼠標跟隨框的部分頁面會被隱藏掉。為了能夠完整的展示鼠標跟隨框中的信息,我們需要進行一個簡單的計算,當 鼠標位置的橫坐標 > 鼠標位置橫坐標 - 鼠標選擇框的寬度 時,就讓 鼠標跟隨框的橫坐標 = 鼠標位置橫坐標 - 鼠標選擇框的寬度

鼠標跟隨框的具體實現(xiàn)如下:

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;
  }
}

絕對定位(相對于整個瀏覽器窗口)

利用絕對定位我們可以實現(xiàn)和上面固定定位相似的效果,但是有個隱患需要注意,如果鼠標跟隨框的某個相近的父元素用了相對定位,那鼠標跟隨框的實際位置就可能會亂套了。

絕對定位不僅要考慮可視范圍內(nèi)的位置,還需要考慮瀏覽器頁面滾動的距離。

具體實現(xiàn)如下:

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;
  }
}

絕對定位和相對定位(相對于鼠標跟隨框的父元素)

有時候我們可能并不需要在整個頁面進行鼠標跟隨框的提示,在某些情況下只需要鼠標在進入頁面的部分區(qū)域才進行提示。

如下圖所示:

這個時候就需要同時用到絕對定位和相對定位以及 offsetXoffsetY。

offsetX: 規(guī)定了事件對象與目標節(jié)點的內(nèi)填充邊(padding edge)在 X 軸方向上的偏移量 offsetY: 規(guī)定了事件對象與目標節(jié)點的內(nèi)填充邊(padding edge)在 Y 軸方向上的偏移量

具體實現(xiàn)如下:

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;
  }
}

最后

本文結(jié)合實例,詳細的介紹了鼠標跟隨框在三種場景下的三種具體實現(xiàn)的方法

以上就是React實現(xiàn)多個場景下鼠標跟隨提示框詳解的詳細內(nèi)容,更多關于React鼠標跟隨提示框的資料請關注腳本之家其它相關文章!

相關文章

  • react實現(xiàn)原生下拉刷新

    react實現(xiàn)原生下拉刷新

    這篇文章主要為大家詳細介紹了react實現(xiàn)原生下拉刷新,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React-Router如何進行頁面權限管理的方法

    React-Router如何進行頁面權限管理的方法

    本篇文章主要介紹了React-Router如何進行頁面權限管理的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • react+antd動態(tài)增刪表單方式

    react+antd動態(tài)增刪表單方式

    這篇文章主要介紹了react+antd動態(tài)增刪表單方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • react hook使用useState更新數(shù)組,無法更新問題及解決

    react hook使用useState更新數(shù)組,無法更新問題及解決

    這篇文章主要介紹了react hook使用useState更新數(shù)組,無法更新問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • React報錯之組件不能作為JSX組件使用的解決方法

    React報錯之組件不能作為JSX組件使用的解決方法

    本文主要介紹了React報錯之組件不能作為JSX組件使用的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • React.js源碼解析setState流程

    React.js源碼解析setState流程

    這篇文章主要為大家介紹了React.js源碼解析setState流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 三分鐘搞懂react-hooks及實例代碼

    三分鐘搞懂react-hooks及實例代碼

    React?Hooks是今年最勁爆的新特性真的毫不夸張。如果你也對react感興趣,或者正在使用react進行項目開發(fā),請抽出點時間閱讀下此文
    2022-03-03
  • react項目優(yōu)化配置的操作詳解

    react項目優(yōu)化配置的操作詳解

    這篇文章主要介紹了react項目優(yōu)化配置,主要包括優(yōu)化配置CDN,優(yōu)化路由懶加載,結(jié)合示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 利用React高階組件實現(xiàn)一個面包屑導航的示例

    利用React高階組件實現(xiàn)一個面包屑導航的示例

    這篇文章主要介紹了利用React高階組件實現(xiàn)一個面包屑導航的示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • 詳解React 代碼共享最佳實踐方式

    詳解React 代碼共享最佳實踐方式

    這篇文章主要介紹了React 代碼共享最佳實踐方式,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05

最新評論

武山县| 邹城市| 新龙县| 高淳县| 临澧县| 玛沁县| 类乌齐县| 乐都县| 本溪市| 临城县| 藁城市| 太仆寺旗| 奉化市| 杭锦后旗| 深州市| 太保市| 西充县| 自治县| 平定县| 肇源县| 九江县| 新河县| 寻甸| 武宁县| 柘城县| 天镇县| 仁怀市| 晋中市| 白水县| 巧家县| 印江| 云龙县| 新乡县| 万山特区| 虹口区| 定远县| 芷江| 沿河| 隆德县| 内江市| 浦东新区|