一、盒子获取+对应显示
盒子获取
小盒子——右侧排列图片——small
中盒子——左侧标准图片——middle
大盒子——经过放大图片——large
<script>
// 1. 获取三个小盒子
// 小盒子
const small = document.querySelector('.small')
// 中盒子
const middle = document.querySelector('.middle')
// 大盒子
const large = document.querySelector('.large')
</script>
1.经过小盒子显示中盒子
思路:
- 监听对象e 判断 经过元素是否为图片
- 若为图片,在其父元素上添加 ‘.active’
- 获取 ‘.active’ 图片的路径
- 将 middle 图片的 src 更换为对应 small 图片的 src
<script>
// 2. 鼠标经过小盒子显示对应中盒子
small.addEventListener('mouseover', function(e) {
// 监听对象e —— 图片
// 判断触发的是否为图片
if(e.target.tagName === 'IMG'){
// console.log(111) //测试经过后是否有回应
// 排他思想,先删除后添加
// this 指向 small 中对应 ul 的 li 中 img 图片
this.querySelector('.active').classList.remove('active')
// 给当前元素 img 的父级 li 添加active
e.target.parentNode.classList.add('active')
// console.log(e.target.src) // 测试拿到小图片的 src
// 将 中等盒子 src 更改为 小盒子的 src
middle.querySelector('img').src = e.target.src
// 大盒子更换背景图片
large.style.backgroundImage = `url(${e.target.src})`
}
})
</script>
2.经过中盒子显示/隐藏大盒子
思路:
- 写出显示函数、隐藏函数(通过更改属性值)
- 隐藏函数 设置延迟200ms的定时器
- 显示函数 设置清除定时器效果(防止多次触发)
- 鼠标经过、离开时,分别调用:显示函数和隐藏函数
<script>
// 3. 鼠标经过中等盒子,显示隐藏大盒子
middle.addEventListener('mouseenter', show)// 显示函数
middle.addEventListener('mouseleave', hide)// 隐藏函数
let timeId = null
// 显示函数 —— 显示大盒子
function show() {
// 清除定时器 : 防止多次触发
clearInterval(timeId)
// 更改属性值,显示图片
large.style.display = 'block'
}
// 隐藏函数 —— 隐藏大盒子 (延迟200ms后)
function hide() {
timeId = setInterval(function() {
// 更改属性值,隐藏图片
large.style.display = 'none'
}, 200)
}
</script>
<script>
// 4. 鼠标经过大盒子, 显示隐藏 大盒子
large.addEventListener('mouseenter', show)
large.addEventListener('mouseleave', hide)
</script>
二、移动放大遮罩层
1.遮罩层的显示/隐藏
思路:
- 获取遮罩层
- 写出显示函数、隐藏函数
<script>
// 5. 鼠标经过中等盒子,显示隐藏黑色遮罩层
// 获取遮罩层
const layer = document.querySelector('.layer')
// 显示函数
middle.addEventListener('mouseenter', function() {
layer.style.display = 'block'
})
// 隐藏函数
middle.addEventListener('mouseleave', function() {
layer.style.display = 'none'
})
</script>
2.遮罩层的移动
思路:
- 算法:鼠标在middle盒子中的坐标 = 鼠标在页面中的坐标 - middle盒子的坐标 (y轴要减去页面滚动的距离)
- 为了让遮罩层在盒子内,限制遮罩层的移动范围
- 注:遮罩层不移动的情况
- 大盒子的背景图片要跟随 中等盒子移动 存在的关系是 2倍
- 鼠标移动方向与图片移动方向的关系:方向相反
<script>
// 6. 移动黑色遮罩盒子
middle.addEventListener('mousemove', function(e) {
// console.log(111) // 测试鼠标移动反应回馈
// console.log(e.pageX) // 测试鼠标坐标
// console.log(middle.getBoundingClientRect()) // 测试middle坐标
// 引入算法
let x = e.pageX - middle.getBoundingClientRect().left
let y = e.pageY - middle.getBoundingClientRect().top - document.documentElement.scrollTop // y要减去滚动的距离
// 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倍
// 修改背景图片的位置 —— Position
// 鼠标向右移,大盒子中图片相对原来位置向左 (方向相反)
large.style.backgroundPositionX = -2 * mx + 'px'
large.style.backgroundPositionY = -2 * my + 'px'
}
})
</script>