原生 JavaScript + Vue + React 三种方案实现放大镜效果

原生 JavaScript + Vue + React 三种方案实现放大镜效果_第1张图片


电商类的网站为了让顾客更加清晰的看见商品图片,一般会提供放大镜效果。

今天我们就使用三种方法来实现一下这个效果

说是三种,其实就一种,框架就是在原生的基础上适配一下语法
原生 JavaScript + Vue + React 三种方案实现放大镜效果_第2张图片

我主要是为了方便使用框架的同学
原生 JavaScript + Vue + React 三种方案实现放大镜效果_第3张图片
啥?为啥没有 angular,因为我不会

原生 JavaScript + Vue + React 三种方案实现放大镜效果_第4张图片

不皮了,正文开始


  1. 获取页面元素
let smallImg = document.getElementById("smallImg");
let smallDiv = document.getElementById("smallDiv");
let bigDiv = document.getElementById("bigDiv");
let bigImg = document.getElementById("bigImg");
  1. 当鼠标移入小图片区域时,证明我们需要使用放大镜效果。此时,应该让小图片上的 smallDiv 显示,并且放大的图片也应该显示。
smallImg.onmouseover = function () {
  smallDiv.style.display = 'block';
  bigDiv.style.display = 'block';
}
  1. 鼠标移出,效果消失
smallImg.onmouseout = function () {
  smallDiv.style.display = 'none';
  bigDiv.style.display = 'none';
}

原生 JavaScript + Vue + React 三种方案实现放大镜效果_第5张图片
ok,差不多实现了一点点

smallDiv 移动方向和大图(bigImg)移动方向是相反的。核心:整个放大镜功能存在一个比例,分析:尺寸大小——>结论:3倍——>才是移动的距离

小div / 小图 = 大div / 大图
100 / 300 = 300 / 900

  1. 先完成鼠标绑定遮挡层。当鼠标移动距离大于遮挡层的移动距离,进行边界判断。把 小div 和大图进行移动。
smallImg.onmousemove = function (e) {
  let e = e || window.event;
  let x = e.clientX - 50;
  let y = e.clientY - 50;
  // 对移动范围进行判断
  if (x >= 200) {
    x = 200;
  }
  if (x <= 0) {
    x = 0;
  }
  if (y >= 200) {
    y = 200;
  }
  if (y <= 0) {
    y = 0;
  }
  smallDiv.style.left = x + 'px';
  smallDiv.style.top = y + 'px';
  bigImg.style.left = -3 * x + 'px';
  bigImg.style.top = -3 * y + 'px';
}

React

为了省事,直接将原生的 html 结构复制粘贴,将 class 改为 className

  1. smallImg,添加鼠标事件监听。
<div
  className="smallImg"
  onMouseOver={smallImgMouseOver}
  onMouseLeave={smallImgMouseLeave}
  onMouseMove={smallImgMouseMove}
>div>
  1. smallDivbigDiv 添加动态 style,在onMouseOveronMouseLeave 事件发生时,改变 isDivShow 的值,使其显示在页面中。
<div
  className="smallDiv"
  style={{
    display: (isDivShow) ? 'block' : 'none',
  }}
>div>
<div
  className="bigDiv"
  style={{
    display: (isDivShow) ? 'block' : 'none',
  }}>div>
const [isDivShow, setIsDivShow] = useState(false)

const smallImgMouseOver = () => {
  setIsDivShow(true)
}
const smallImgMouseLeave = () => {
  setIsDivShow(false)
}
  1. 鼠标移动时,处理放大逻辑,并对相应的值进行赋值
const smallImgMouseMove = (e) => {
  e = e || window.event
  let x = e.clientX - 50
  let y = e.clientY - 50
  if (x >= 200) {
    x = 200;
  }
  if (x <= 0) {
    x = 0;
  }
  if (y >= 200) {
    y = 200;
  }
  if (y <= 0) {
    y = 0;
  }
  setdistanceX(x)
  setdistanceY(y)
}
<div
  className="smallDiv"
  style={{
    display: (isDivShow) ? 'block' : 'none',
    left: `${distanceX}px`,
    top: `${distanceY}px`
  }}
>div>
<img
  src="https://cdn.pixabay.com/photo/2021/07/01/08/57/safari-6378792_960_720.jpg" 
  alt=""
  className="bigImg"
  style={{
    left: `${-3 * distanceX}px`,
    top: `${-3 * distanceY}px`
  }}
/>

Vue

Vue 的逻辑也是同样的,只是语法上有些不同。这里就不在分析了。

源代码在此

<template>
  <div class="fang">
    <div
      class="smallImg"
      @mouseover="smallImgMouseOver"
      @mouseout="smallImgMouseOut"
      @mousemove="smallImgMouseMove"
    >
      <div class="smallDiv" :style="{ display: isDivShow, left: `${distanceX}px`, top: `${distanceY}px` }"></div>
    </div>

    <div class="bigDiv" :style="{ display: isDivShow }">
      <img
        src="https://cdn.pixabay.com/photo/2021/07/03/23/24/chamomile-6385050__340.jpg"
        alt=""
        class="bigImg"
        :style="{left: `${-3 * distanceX}px`, top: `${-3 * distanceY}px`}"
      />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isDivShow: "none",
      distanceX: 0,
      distanceY: 0
    };
  },
  methods: {
    smallImgMouseOver() {
      this.isDivShow = "block";
    },
    smallImgMouseOut() {
      this.isDivShow = "none";
    },
    smallImgMouseMove(e) {
      e = e || window.event;
      let x = e.clientX - 50;
      let y = e.clientY - 50;
      if (x >= 200) {
        x = 200;
      }
      if (x <= 0) {
        x = 0;
      }
      if (y >= 200) {
        y = 200;
      }
      if (y <= 0) {
        y = 0;
      }

      this.distanceX = x
      this.distanceY = y
    },
  },
};
</script>

<style lang="css">
* {
  margin: 0;
  padding: 0;
}

.smallImg {
  width: 300px;
  height: 300px;
  background-image: url("https://cdn.pixabay.com/photo/2021/07/03/23/24/chamomile-6385050__340.jpg");
  background-size: cover;
}

.smallDiv {
  width: 100px;
  height: 100px;
  background-color: rgba(255, 0, 0, 0.2);
  display: none;
  position: absolute;
}

.bigDiv {
  width: 300px;
  height: 300px;
  /* border: 1px solid red; */
  position: absolute;
  left: 300px;
  top: 0px;
  overflow: hidden;
  display: none;
}

.bigImg {
  width: 900px;
  height: 900px;
  position: absolute;
}
</style>

react 代码:

import { useState } from 'react';
import './App.css';

function App() {

  const [isDivShow, setIsDivShow] = useState(false)
  const [distanceX, setdistanceX] = useState(0)
  const [distanceY, setdistanceY] = useState(0)

  const smallImgMouseOver = () => {
    setIsDivShow(true)
  }

  const smallImgMouseLeave = () => {
    setIsDivShow(false)
  }

  const smallImgMouseMove = (e) => {
    e = e || window.event
    let x = e.clientX - 50
    let y = e.clientY - 50
    if (x >= 200) {
      x = 200;
    }
    if (x <= 0) {
      x = 0;
    }
    if (y >= 200) {
      y = 200;
    }
    if (y <= 0) {
      y = 0;
    }

    setdistanceX(x)
    setdistanceY(y)
  }

  return (
    <>
      <div className="fang">
        <div
          className="smallImg"
          onMouseOver={smallImgMouseOver}
          onMouseLeave={smallImgMouseLeave}
          onMouseMove={smallImgMouseMove}
        >
          <div
            className="smallDiv"
            style={{
              display: (isDivShow) ? 'block' : 'none',
              left: `${distanceX}px`,
              top: `${distanceY}px`
            }}
          ></div>
        </div>
        <div
          className="bigDiv"
          style={{
            display: (isDivShow) ? 'block' : 'none',
          }}>
          <img
            src="https://cdn.pixabay.com/photo/2021/07/01/08/57/safari-6378792_960_720.jpg" alt=""
            className="bigImg"
            style={{
              left: `${-3 * distanceX}px`,
              top: `${-3 * distanceY}px`
            }}
          />
        </div>
      </div>
    </>
  );
}

export default App;

原生 JavaScript:


<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Documenttitle>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    #smallImg {
      width: 300px;
      height: 300px;
      background-image: url(./lou.jpg);
      background-size: cover;
    }

    #smallDiv {
      width: 100px;
      height: 100px;
      background-color: rgba(255, 0, 0, .2);
      display: none;
      position: absolute;
    }

    #bigDiv {
      width: 300px;
      height: 300px;
      /* border: 1px solid red; */
      position: absolute;
      left: 300px;
      top: 0px;
      overflow: hidden;
      display: none;
    }

    #bigImg {
      width: 900px;
      height: 900px;
      position: absolute;
    }
  style>
head>

<body>

  <div class="fang">
    <div id="smallImg">
      <div id="smallDiv">div>
    div>

    <div id="bigDiv">
      <img src="./lou.jpg" alt="" id="bigImg">
    div>
  div>


  <script>

    let smallImg = document.getElementById("smallImg");
    let smallDiv = document.getElementById("smallDiv");
    let bigDiv = document.getElementById("bigDiv");
    let bigImg = document.getElementById("bigImg");

    smallImg.onmouseover = function () {
      smallDiv.style.display = 'block';
      bigDiv.style.display = 'block';
    }
    smallImg.onmouseout = function () {
      smallDiv.style.display = 'none';
      bigDiv.style.display = 'none';
    }

    smallImg.onmousemove = function (e) {
      e = e || window.event;
      let x = e.clientX - 50;
      let y = e.clientY - 50;
      // 对移动范围进行判断
      if (x >= 200) {
        x = 200;
      }
      if (x <= 0) {
        x = 0;
      }
      if (y >= 200) {
        y = 200;
      }
      if (y <= 0) {
        y = 0;
      }

      smallDiv.style.left = x + 'px';
      smallDiv.style.top = y + 'px';

      bigImg.style.left = -3 * x + 'px';
      bigImg.style.top = -3 * y + 'px';
    }
  script>

body>

html>

你可能感兴趣的:(JavaScript,React,vue,vue.js,reactjs,javascript,放大镜效果)