2022-04-27
开发杂谈
0
请注意,本文编写于 1156 天前,最后修改于 516 天前,其中某些信息可能已经过时。

我们在浏览购物网站的商品详情页时,通常都会有一个展示商品图片的放大镜,如下所示:

GIF 2022-4-26 17-19-08.gif

下面我们就来仿一下这个功能。

首先是结构的搭建:

html
<div id="container"> <div id="left"> <img src="img.jpg" alt="" style="width: 100%;"> <span></span> </div> <div id="right"> <img style="position: absolute;" src="bigimg.jpg" alt=""> </div> </div>

然后做亿点样式:

css
* { margin: 0; padding: 0; box-sizing: border-box; } #left { left: 50px; top: 50px; position: relative; width: 400px; height: 400px; border: 1px solid black; } #left span { position: absolute; width: 250px; height: 250px; left: 0; top: 0; background-color: rgba(192, 149, 83, .6); } #right { position: absolute; left: 460px; top: 50px; width: 500px; height: 500px; border: 1px solid black; overflow: hidden; }

现在我们的页面是这样:

image.png

接下来将 #left span#right 设置为不显示,display: none;,然后为左边的 div 添加鼠标移入移出事件:

js
let leftDiv = document.getElementById('left') let rightDiv = document.getElementById('right') let span = document.querySelector('#left span') let bigImg = document.querySelector('#right img') leftDiv.onmouseover = () => { span.style.display = 'block' rightDiv.style.display = 'block' } leftDiv.onmouseout = () => { span.style.display = 'none' rightDiv.style.display = 'none' }

这样,当鼠标悬浮于 leftDiv 时,spanrightDiv 便会显现。

下面为leftDiv添加 onmousemove 事件:

js
leftDiv.onmousemove = (e) => { let spanLeft = e.clientX - leftDiv.offsetLeft - span.offsetWidth / 2 let spanTop = e.clientY - leftDiv.offsetTop - span.offsetHeight / 2 let maxLeft = leftDiv.offsetWidth - span.offsetWidth let maxTop = leftDiv.offsetHeight - span.offsetHeight spanLeft = spanLeft < 0 ? 0 : (spanLeft > maxLeft ? maxLeft : spanLeft) spanTop = spanTop < 0 ? 0 : (spanTop > maxTop ? maxTop : spanTop) span.style.left = spanLeft + 'px' span.style.top = spanTop + 'px' let imgLeft = spanLeft * (bigImg.width - 500) / (400 - 250) let imgTop = spanTop * (bigImg.height - 500) / (400 - 250) bigImg.style.left = -imgLeft + 'px' bigImg.style.top = -imgTop + 'px' }

最后为span更换一下指针样式,与购物网站更接近:

css
#left span:hover { cursor: move; }

效果如下:

最终效果展示

完整代码:

html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>仿购物网站放大</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } #left { left: 50px; top: 50px; position: relative; width: 400px; height: 400px; border: 1px solid black; } #left span { position: absolute; width: 250px; height: 250px; left: 0; top: 0; background-color: rgba(192, 149, 83, .6); display: none; } #left span:hover { cursor: move; } #right { display: none; position: absolute; left: 460px; top: 50px; width: 500px; height: 500px; border: 1px solid black; overflow: hidden; } </style> </head> <body> <div id="container"> <div id="left"> <img src="img.jpg" alt="" style="width: 100%;"> <span></span> </div> <div id="right"> <img style="position: absolute;" src="bigimg.jpg" alt=""> </div> </div> <script> let leftDiv = document.getElementById('left') let rightDiv = document.getElementById('right') let span = document.querySelector('#left span') let bigImg = document.querySelector('#right img') leftDiv.onmouseover = () => { span.style.display = 'block' rightDiv.style.display = 'block' } leftDiv.onmouseout = () => { span.style.display = 'none' rightDiv.style.display = 'none' } leftDiv.onmousemove = (e) => { let spanLeft = e.clientX - leftDiv.offsetLeft - span.offsetWidth/2 let spanTop = e.clientY - leftDiv.offsetTop - span.offsetHeight/2 let maxLeft = leftDiv.offsetWidth - span.offsetWidth let maxTop = leftDiv.offsetHeight - span.offsetHeight spanLeft = spanLeft < 0 ? 0 : (spanLeft > maxLeft ? maxLeft : spanLeft) spanTop = spanTop < 0 ? 0 : (spanTop > maxTop ? maxTop : spanTop) span.style.left = spanLeft + 'px' span.style.top = spanTop + 'px' let imgLeft = spanLeft * (bigImg.width - 500) / (400 -250) let imgTop = spanTop * (bigImg.height - 500) / (400 -250) bigImg.style.left = -imgLeft + 'px' bigImg.style.top = -imgTop + 'px' } </script> </body> </html>

本文作者:Morales

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 License 许可协议。转载请注明出处!