<body>
<div class="xtx-product-info">
<div class="left">
<div class="pictrue">
<div class="middle">
<img src="./images/1.jpg" alt="">
<div class="layer"></div>
</div>
<div class="small">
<ul>
<li class="active"><img src="./images/1.jpg" alt=""></li>
<li><img src="./images/2.jpg" alt=""></li>
<li><img src="./images/3.jpg" alt=""></li>
<li><img src="./images/4.jpg" alt=""></li>
<li><img src="./images/5.jpg" alt=""></li>
</ul>
</div>
<div class="large"></div>
</div>
</body>
<style>
.xtx-product-info {
background: #fff;
display: flex;
min-height: 580px;
}
.xtx-product-info .left {
width: 580px;
padding: 30px 50px;
}
.xtx-product-info .left .pictrue {
width: 480px;
height: 400px;
display: flex;
position: relative;
}
.xtx-product-info .left .pictrue .middle {
width: 400px;
height: 400px;
position: relative;
}
.xtx-product-info .left .pictrue .middle .layer {
display: none;
width: 200px;
height: 200px;
background-color: rgba(0,0,0,0.3);
position: absolute;
left: 0;
top: 0;
cursor: move;
}
.xtx-product-info .left .pictrue .large {
width: 400px;
height: 400px;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
position: absolute;
left: 412px;
top: 0;
z-index: 999;
background-color: #fff;
display: none;
background-size: 800px 800px;
background-image: url(./images/1.jpg);
}
.xtx-product-info .left .pictrue .middle img {
width: 100%;
height: 100%;
}
.xtx-product-info .left .pictrue .small {
width: 80px;
height: 400px;
}
.xtx-product-info .left .pictrue .small ul li {
width: 68px;
height: 68px;
margin-bottom: 15px;
margin-left: 12px;
border: 2px solid transparent;
}
.xtx-product-info .left .pictrue .small ul li img {
width: 100%;
height: 100%;
}
.xtx-product-info .left .pictrue .small ul li.active, .xtx-product-info .left .pictrue .small ul li:hover {
border-color: #27BA9B;
}
.xtx-product-info .left .other {
margin-top: 20px;
}
.xtx-product-info .left .other ul {
display: flex;
width: 400px;
}
.xtx-product-info .left .other ul li {
flex: 1;
text-align: center;
position: relative;
line-height: 32px;
}
.xtx-product-info .left .other ul li::before {
content: "";
position: absolute;
top: 15px;
right: 0;
height: 70px;
border-right: 1px solid #e4e4e4;
}
.xtx-product-info .left .other ul li:last-child::before {
display: none;
}
.xtx-product-info .left .other ul li p:first-child {
color: #999;
}
.xtx-product-info .left .other ul li p:nth-child(2) {
color: #CF4444;
}
</style>
<script>
// 1. 获取三个盒子
// 2. 小盒子 图片切换效果
const small = document.querySelector('.small')
// 中盒子
const middle = document.querySelector('.middle')
// 大盒子
const large = document.querySelector('.large')
// 2. 事件委托
small.addEventListener('mouseover', function (e) {
if (e.target.tagName === 'IMG') {
// console.log(111)
// 排他 干掉以前的 active li 上面
this.querySelector('.active').classList.remove('active')
// 当前元素的爸爸添加 active
e.target.parentNode.classList.add('active')
// 拿到当前小图片的 src
// console.log(e.target.src)
// 让中等盒子里面的图片,src 更换为 小图片src
middle.querySelector('img').src = e.target.src
// 大盒子更换背景图片
large.style.backgroundImage = `url(${e.target.src})`
}
})
// 3. 鼠标经过中等盒子, 显示隐藏 大盒子
middle.addEventListener('mouseenter', show)
middle.addEventListener('mouseleave', hide)
let timeId = null
// 显示函数 显示大盒子
function show() {
// 先清除定时器
clearTimeout(timeId)
large.style.display = 'block'
}
// 隐藏函数 隐藏大盒子
function hide() {
timeId = setTimeout(function () {
large.style.display = 'none'
}, 200)
}
// 4. 鼠标经过大盒子, 显示隐藏 大盒子
large.addEventListener('mouseenter', show)
large.addEventListener('mouseleave', hide)
// 5. 鼠标经过中等盒子,显示隐藏 黑色遮罩层
const layer = document.querySelector('.layer')
middle.addEventListener('mouseenter', function () {
layer.style.display = 'block'
})
middle.addEventListener('mouseleave', function () {
layer.style.display = 'none'
})
// 6.移动黑色遮罩盒子
middle.addEventListener('mousemove', function (e) {
// let x = 10, y = 20
// console.log(11)
// 鼠标在middle 盒子里面的坐标 = 鼠标在页面中的坐标 - middle 中等盒子的坐标
// console.log(e.pageX)鼠标在页面中的坐标
// middle 中等盒子的坐标
// console.log(middle.getBoundingClientRect().left)
let x = e.pageX - middle.getBoundingClientRect().left
let y = e.pageY - middle.getBoundingClientRect().top - document.documentElement.scrollTop
// console.log(x, y)
// 黑色遮罩移动 在 middle 盒子内 限定移动的距离
if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {
// 黑色盒子不是一直移动的
// 声明2个变量 黑色盒子移动的 mx my变量
let mx = 0, my = 0
if (x < 100) mx = 0
if (x >= 100 && x <= 300) mx = x - 100
if (x > 300) mx = 200
if (y < 100) my = 0
if (y >= 100 && y <= 300) my = y - 100
if (y > 300) my = 200
layer.style.left = mx + 'px'
layer.style.top = my + 'px'
// 大盒子的背景图片要跟随 中等盒子移动 存在的关系是 2倍
large.style.backgroundPositionX = -2 * mx + 'px'
large.style.backgroundPositionY = -2 * my + 'px'
}
})
</script>
最后效果图