天天看点

原生JS实现京东放大镜效果

js实现京东放大镜效果

我们经常会在京东、淘宝上看到一个效果

原生JS实现京东放大镜效果

鼠标放到商品图片上会出现一个遮罩框,右侧会显示一个商品的大图细节,今天就来尝试一些自己写一个实现代码:

首先,将实现过程分为三个步骤

  1. 鼠标移入商品时,出现一个放大镜遮罩框;鼠标移出,遮罩框消失
  2. 遮罩框的位置跟随鼠标的移动而移动,但移动范围仅限为放置商品图片的盒子
  3. 右侧的大图随着放大镜的移动而移动,显示当前大图效果

在这里我们对HTML、CSS简单书写,主要对JS代码进行分析:

1.当鼠标移入左侧盒子的时候,出现放大镜以及右侧大图;移除后,放大镜、右侧大图消失

* css部分
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        .phone {
            width: 400px;
            height: 400px;
            margin: 50px 100px;
            position: relative;
            border: 1px solid #ccc;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .phone .mask {
            position: absolute;
            top: 0;
            left: 0;
            display: none;
            width: 200px;
            height: 200px;
            background-color: rgb(245, 221, 101);
            opacity: .5;
            cursor: move;
        }
        .big {
            display: none;
            position: absolute;
            width: 500px;
            height: 500px;
            left: 410px;
            top: 0;
            border: 1px solid #ccc;
            overflow: hidden;
        }
        .big img {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
 * HTML部分
   <div class="phone">
        <img id='small' width='200px' src="ajpg" alt="">
        <div class="mask"></div>
        <div class="big">
            <img class='bigImg' width='1000px' src="big_a.jpg" alt="">
        </div>
    </div>

           

我们主要来看Js部分

  1. 鼠标移入商品时,出现一个放大镜遮罩框;鼠标移出,遮罩框消失
* Js部分
	<script>
		// 获取mask、big元素
		let mask = document.querySelector('.mask')
		let big= document.querySelector('.big')
		let bigImg= document.querySelector('.bigImg')
		
		// 1. 获取phone元素,并为其绑定mouseover、mouseout事件
		let phone = document.querySelector('.phone')
		// 绑定mouseover事件,当鼠标移入时,mask、big显示
		phone.addEventListener('mouseover', function() {
			mask.style.display = 'block'
			big.style.display = 'block'
		})
		// 绑定mouseout事件,当鼠标移出时,mask、big设置为none
		phone.addEventListener('mouseout', function() {
			mask.style.display = 'none'
			big.style.display = 'none'
		})
	</script>
           
  1. 遮罩框的位置跟随鼠标的移动而移动,但移动范围仅限为放置商品图片的盒子
phone.addEventListener('mouseover', function(e) {
	// 1. 获取鼠标在phone元素中的位置
	// 水平位置 = 鼠标相对于页面的水平位置 - phone元素相对于页面的水平位置
	var x = e.pageX - this.offsetLeft
	var y = e.pageY - this.offsetTop
	
	// 将x,y值赋值给mask的left、top属性
	mask.style.left = x + 'px'
	mask.style.top= y + 'px'
})
           

这样就可以实现了第二步,但会发现,鼠标会一直在mask遮罩框的左上角,很不友好,于是我们可以对上面的代码做一些改进,使得鼠标位于遮罩框的中心位置,我们只需要对最后的赋值操作做一些优化

// 将x,y值赋值给mask的left、top属性
	mask.style.left = x - mask.offsetWidth / 2 + 'px'
	mask.style.top= y  - mask.offsetHeight / 2+ 'px'
           

这样,我们将mask分别向左、向上移动自身宽度、高度的1/2,这样鼠标就实现了鼠标mask中心的效果;

  1. 右侧的大图随着放大镜的移动而移动,显示当前大图效果;

    最后一步也是最关键的一步,如何实现右侧大图的同步移动效果,由于左右两个盒子的大小不一致,我们该如何确定右侧大盒子的移动距离呢?

    这里,就用到了等比例的概念:

    遮罩框移动距离 / 遮罩框最大位移 = 大图片移动距离 / 大图片最大位移.这里有4个值,我们能够取得3个值,分别是(以水平方向为例):

    遮罩框移动距离: maskX = e.pageX - phone.offsetLeft

    遮罩框最大位移: maskMaxX = phone.offsetWidth - mask.offsetWidth

    大图片最大位移: bigimgMaxX = bigImg.offsetWidth - big.offsetWidth,

    我们可以根据上面三个值计算大图片的移动距离

    bigimgX = maskX * bigimgMaxX / maskMaxX,只需要将这个值赋值给bigimg的left、top即可

// 这里的 - 很重要哦,不然你会发现很怪异的一件事
   bigimg.style.left = - bigimgX + 'px'
   bigimg.style.top= - bigimgY + 'px'
           

好了,以上就是全部的js代码了,欢迎留言、点赞、关注我哦。

继续阅读