You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器窗口调整致JS图片缩放错位,如何让imageZoom感知尺寸变化?

解决图片缩放窗口调整后错位的问题

问题根源是原imageZoom()函数仅在页面加载时计算一次图片尺寸、偏移量等关键参数,窗口调整后图片因百分比设置改变尺寸,但参数未同步更新,导致缩放镜头错位。

解决步骤

  1. 将参数初始化逻辑从imageZoom中抽离为独立函数,方便重复调用更新参数
  2. 给窗口添加resize事件监听,结合防抖避免频繁触发,每次窗口变化时重新初始化参数

修改后的完整代码示例

<!DOCTYPE html>
<html>
<head>
<style>
* {box-sizing: border-box;}

.img-zoom-container {
  position: relative;
}

.img-zoom-lens {
  position: absolute;
  border: 1px solid #d4d4d4;
  width: 40px;
  height: 40px;
}

.img-zoom-result {
  border: 1px solid #d4d4d4;
  width: 300px;
  height: 300px;
}
</style>
</head>
<body>

<h1>图片缩放效果</h1>
<p>鼠标悬停在图片上查看缩放效果:</p>

<div class="img-zoom-container">
  <img id="myimage" src="img_girl.jpg" width="50%" height="50%">
  <div id="myresult" class="img-zoom-result"></div>
</div>

<script>
// 全局存储关键参数
let img, lens, result, cx, cy;

// 初始化/更新缩放参数
function initZoomParams() {
  img = document.getElementById("myimage");
  result = document.getElementById("myresult");
  lens = document.querySelector(".img-zoom-lens");
  
  // 动态创建镜头元素(如果不存在)
  if (!lens) {
    lens = document.createElement("DIV");
    lens.setAttribute("class", "img-zoom-lens");
    img.parentElement.insertBefore(lens, img);
  }

  // 计算缩放比例
  cx = result.offsetWidth / lens.offsetWidth;
  cy = result.offsetHeight / lens.offsetHeight;
  
  // 更新结果容器的背景图尺寸
  result.style.backgroundImage = `url('${img.src}')`;
  result.style.backgroundSize = `${img.width * cx}px ${img.height * cy}px`;
}

function imageZoom() {
  initZoomParams();
  
  // 绑定镜头移动事件
  lens.addEventListener("mousemove", moveLens);
  img.addEventListener("mousemove", moveLens);
  lens.addEventListener("touchmove", moveLens);
  img.addEventListener("touchmove", moveLens);

  function moveLens(e) {
    e.preventDefault();
    const pos = getCursorPos(e);
    
    // 限制镜头在图片范围内移动
    let x = pos.x - lens.offsetWidth / 2;
    let y = pos.y - lens.offsetHeight / 2;
    x = Math.max(0, Math.min(x, img.width - lens.offsetWidth));
    y = Math.max(0, Math.min(y, img.height - lens.offsetHeight));
    
    // 更新镜头位置和放大区域
    lens.style.left = `${x}px`;
    lens.style.top = `${y}px`;
    result.style.backgroundPosition = `-${x * cx}px -${y * cy}px`;
  }

  function getCursorPos(e) {
    e = e || window.event;
    const imgRect = img.getBoundingClientRect();
    // 计算鼠标相对图片的坐标
    let x = e.pageX - imgRect.left - window.pageXOffset;
    let y = e.pageY - imgRect.top - window.pageYOffset;
    return {x: Math.max(0, x), y: Math.max(0, y)};
  }
}

// 防抖函数:减少resize事件触发频率
function debounce(func, delay = 200) {
  let timer;
  return () => {
    clearTimeout(timer);
    timer = setTimeout(func, delay);
  }
}

// 页面加载初始化缩放
window.addEventListener("load", imageZoom);
// 窗口调整时重新更新参数
window.addEventListener("resize", debounce(initZoomParams));
</script>

</body>
</html>

关键修改说明

  • 抽离initZoomParams函数,负责初始化/更新图片尺寸、缩放比例等核心参数
  • 加入防抖函数,避免窗口调整过程中频繁执行参数更新,优化性能
  • 全局存储核心变量,确保参数更新后能被镜头移动逻辑实时使用

内容的提问来源于stack exchange,提问作者Harry Kuril

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:30:59