常用页面效果 --- 京东商品图片放大镜效果

1. 效果图

当鼠标悬浮在图片中,会放大图片的细节

2. 素材

3. 实现

1. 鼠标悬浮在右侧小图时,左侧中图显示对应鼠标悬浮的图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            border: 0;
            margin: 0;
        }
        .box .middle{
            width: 350px;
            height: 466px;
            position: relative;
        }
        .box .small{
            width: 100px;
            position: absolute;
            top: 0;
            left: 320px;
        }
        .box .small img{
            width: 90px;
            height: 90px;
            margin-top: 5px;
        }
        .active{
            border: 2px solid red;
        }
        .box .small li img:first-child{
            margin-top: 0;
        }
        li{
            list-style: none;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="middle">
        <img src="jpgs/0.jpg" alt="">
    </div>
    <ul class="small">
        <li class="active"><img src="jpgs/0.jpg" alt=""></li>
        <li><img src="jpgs/1.jpg" alt=""></li>
        <li><img src="jpgs/2.jpg" alt=""></li>
        <li><img src="jpgs/3.jpg" alt=""></li>
        <li><img src="jpgs/4.jpg" alt=""></li>
    </ul>
    <div class="large"></div>
</div>


<script>
    const small = document.querySelector(".box .small")
    const middle = document.querySelector(".box .middle")
    const large = document.querySelector(".box .large")

    // 1. 鼠标悬浮在右侧小图时,左侧中图显示对应鼠标悬浮的图片
    small.addEventListener("mouseover",function (e) {
        if (e.target.tagName === "IMG"){
            // 删除其他元素的选中效果
            this.querySelector(".active").classList.remove("active")
            // 给当前元素加选中效果
            e.target.parentNode.classList.add("active")

            // 换掉中图的img标签的src属性值
            middle.children[0].src = e.target.src
        }
    })
</script>
</body>
</html>

2. 鼠标悬浮在中等盒子,右侧显示大盒子,并且悬浮大盒子时,一样显示大盒子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            border: 0;
            margin: 0;
        }
        .box .middle{
            width: 350px;
            height: 466px;
            position: relative;
        }
        .box .small{
            width: 100px;
            position: absolute;
            top: 0;
            left: 320px;
        }
        .box .small img{
            width: 90px;
            height: 90px;
            margin-top: 5px;
        }
        .active{
            border: 2px solid red;
        }
        .box .small li img:first-child{
            margin-top: 0;
        }
        li{
            list-style: none;
        }
        .large{
            width: 466px;
            height: 466px;
            display: none;
            position: absolute;
            background-size: 700px 932px;
            top: 0;
            left: 350px;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="middle">
        <img src="images/0.jpg" alt="">
    </div>
    <ul class="small">
        <li class="active"><img src="images/0.jpg" alt=""></li>
        <li><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>
    </ul>
    <div class="large"></div>
</div>


<script>
    const small = document.querySelector(".box .small")
    const middle = document.querySelector(".box .middle")
    const large = document.querySelector(".box .large")

    // 1. 鼠标悬浮在右侧小图时,左侧中图显示对应鼠标悬浮的图片
    small.addEventListener("mouseover",function (e) {
        if (e.target.tagName === "IMG"){
            // 删除其他元素的选中效果
            this.querySelector(".active").classList.remove("active")
            // 给当前元素加选中效果
            e.target.parentNode.classList.add("active")

            // 换掉中图的img标签的src属性值
            middle.children[0].src = e.target.src

            // 换掉大盒子的背景图片
            console.log(`url${e.target.src}`)
            large.style.backgroundImage = `url(${e.target.src})`
        }
    })

    // 2. 鼠标悬浮在中等盒子,右侧显示大盒子
    middle.addEventListener("mouseenter",show)
    // 2.1 鼠标离开中等盒子,等200ms隐藏大盒子
    middle.addEventListener("mouseleave",deShow)
    let timerID = null
    function show() {
        if (large.style.backgroundImage){
            clearTimeout(timerID)
            large.style.display = "block"
        }
    }
    function deShow() {
        timerID= setTimeout(function () {
            large.style.display = "none"
        },200)
    }

    // 2. 鼠标悬浮在大盒子,右侧显示大盒子
    large.addEventListener("mouseenter",show)
    // 2.1 鼠标离开大盒子,等200ms隐藏大盒子
    large.addEventListener("mouseleave",deShow)


</script>
</body>
</html>

3. 让黑色遮罩层跟着鼠标走

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            border: 0;
            margin: 0;
        }
        .box {
            height: 2000px;
            position: relative;
            top: 200px;
            left: 200px;
        }
        .box .middle img{
            width: 350px;
            height: 466px;
        }

        .box .small {
            width: 100px;
            position: absolute;
            top: 0;
            left: 320px;
        }

        .box .small img {
            width: 90px;
            height: 90px;
            margin-top: 5px;
        }

        .active {
            border: 2px solid red;
        }

        .box .small li img:first-child {
            margin-top: 0;
        }

        li {
            list-style: none;
        }

        .large {
            width: 466px;
            height: 466px;
            display: none;
            position: absolute;
            background-size: 700px 932px;
            top: 0;
            left: 350px;
        }

        .layer {
            width: 200px;
            height: 200px;
            background-color: gray;
            opacity: .3;
            display: none;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="middle">
        <img src="images/0.jpg" alt="">
        <div class="layer"></div>
    </div>
    <ul class="small">
        <li class="active"><img src="images/0.jpg" alt=""></li>
        <li><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>
    </ul>
    <div class="large"></div>
</div>


<script>
    const small = document.querySelector(".box .small")
    const middle = document.querySelector(".box .middle")
    const large = document.querySelector(".box .large")
    const layer = document.querySelector(".box .middle .layer")

    // 1. 鼠标悬浮在右侧小图时,左侧中图显示对应鼠标悬浮的图片
    small.addEventListener("mouseover", function (e) {
        if (e.target.tagName === "IMG") {
            // 删除其他元素的选中效果
            this.querySelector(".active").classList.remove("active")
            // 给当前元素加选中效果
            e.target.parentNode.classList.add("active")

            // 换掉中图的img标签的src属性值
            middle.children[0].src = e.target.src

            // 换掉大盒子的背景图片
            console.log(`url${e.target.src}`)
            large.style.backgroundImage = `url(${e.target.src})`
        }
    })

    // 2. 鼠标悬浮在中等盒子,右侧显示大盒子
    middle.addEventListener("mouseenter", show)
    // 2.1 鼠标离开中等盒子,等200ms隐藏大盒子
    middle.addEventListener("mouseleave", deShow)

    let timerID = null

    function show() {
        if (large.style.backgroundImage) {
            clearTimeout(timerID)
            large.style.display = "block"
        }
    }

    function deShow() {
        timerID = setTimeout(function () {
            large.style.display = "none"
        }, 200)
    }

    // 2. 鼠标悬浮在大盒子,右侧显示大盒子
    large.addEventListener("mouseenter", show)
    // 2.1 鼠标离开大盒子,等200ms隐藏大盒子
    large.addEventListener("mouseleave", deShow)

    // 3. 中等盒子中的黑色遮罩层
    // 实现思路:
    // 3.1 显示隐藏 黑色遮罩 的盒子
    middle.addEventListener("mouseenter", function () {
        layer.style.display = "block"
    })

    middle.addEventListener("mouseleave", function () {
        layer.style.display = "none"
    })
    // 3.2 让黑色这招跟着鼠标走,需要用到鼠标移动事件 mousemove 让黑色盒子移动的核心思想: 不断的将鼠标在中等盒子内的坐标给黑色遮罩层,这样遮罩层就可以跟着一起移动了

    middle.addEventListener("mousemove", function (e) {
        // 1. 先得到鼠标在整个页面的坐标
        let mouseX = e.pageX
        let mouseY = e.pageY

        // 2. 再得到当前盒子在整个页面的坐标
        let boxX = middle.getBoundingClientRect().left
        let boxY = middle.getBoundingClientRect().top

        let x = mouseX - boxX
        // 3. 盒子距顶部的距离会根据鼠标滚动页面的变化而变化,所以需要减去鼠标滚动的距离
        let y = mouseY - boxY - document.documentElement.scrollTop

        // 4. 不断的将鼠标在中等盒子内的坐标给黑色遮罩层
        // 限定水平方向大于等于0,小于等于350
        // 限定垂直方向大于等于0,小于等于466
        // 水平坐标x,如果小于等于100(阴影遮罩宽度的一半),移动距离固定为0,不应该移动
        // 水平坐标x,如果大于等于100,小于等于350-200(整个遮罩层的宽度),则移动距离为x-100(阴影遮罩宽度的一半)
        // 水平坐标x,如果大于等于250,移动距离固定为350-200(整个遮罩层的宽度),就不应该移动了
        // 垂直坐标y,同理
        if (0<=x<350 && 0<=y<=466){
            let mx=0,my=0
            if (x<=100) mx=0
            if (x>=250) mx=150
            if (x>=100&&x<=250) mx = x - 100
            layer.style.left = mx + "px"

            if (y<=100) my=0
            if (y>=366) my=266
            if (y>=100 && y<=366) my = y -100
            layer.style.top = my + "px"

        }

    })

</script>
</body>
</html>

4. 大盒子的背景图片坐标要跟着鼠标在中等盒子的移动而反向移动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        * {
            border: 0;
            margin: 0;
        }
        .box {
            height: 2000px;
            position: relative;
            top: 200px;
            left: 200px;
        }
        .box .middle img{
            width: 350px;
            height: 466px;
        }

        .box .small {
            width: 100px;
            position: absolute;
            top: 0;
            left: 320px;
        }

        .box .small img {
            width: 90px;
            height: 90px;
            margin-top: 5px;
        }

        .active {
            border: 2px solid red;
        }

        .box .small li img:first-child {
            margin-top: 0;
        }

        li {
            list-style: none;
        }

        .large {
            width: 350px;
            height: 466px;
            display: none;
            position: absolute;
            background-size: 700px 932px;
            top: 0;
            left: 350px;
        }

        .layer {
            width: 200px;
            height: 200px;
            background-color: gray;
            opacity: .3;
            display: none;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>
<div class="box">
    <div class="middle">
        <img src="images/0.jpg" alt="">
        <div class="layer"></div>
    </div>
    <ul class="small">
        <li class="active"><img src="images/0.jpg" alt=""></li>
        <li><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>
    </ul>
    <div class="large"></div>
</div>


<script>
    const small = document.querySelector(".box .small")
    const middle = document.querySelector(".box .middle")
    const large = document.querySelector(".box .large")
    const layer = document.querySelector(".box .middle .layer")

    // 1. 鼠标悬浮在右侧小图时,左侧中图显示对应鼠标悬浮的图片
    small.addEventListener("mouseover", function (e) {
        if (e.target.tagName === "IMG") {
            // 删除其他元素的选中效果
            this.querySelector(".active").classList.remove("active")
            // 给当前元素加选中效果
            e.target.parentNode.classList.add("active")

            // 换掉中图的img标签的src属性值
            middle.children[0].src = e.target.src

            // 换掉大盒子的背景图片
            console.log(`url${e.target.src}`)
            large.style.backgroundImage = `url(${e.target.src})`
        }
    })

    // 2. 鼠标悬浮在中等盒子,右侧显示大盒子
    middle.addEventListener("mouseenter", show)
    // 2.1 鼠标离开中等盒子,等200ms隐藏大盒子
    middle.addEventListener("mouseleave", deShow)

    let timerID = null

    function show() {
        if (large.style.backgroundImage) {
            clearTimeout(timerID)
            large.style.display = "block"
        }
    }

    function deShow() {
        timerID = setTimeout(function () {
            large.style.display = "none"
        }, 200)
    }

    // 2. 鼠标悬浮在大盒子,右侧显示大盒子
    large.addEventListener("mouseenter", show)
    // 2.1 鼠标离开大盒子,等200ms隐藏大盒子
    large.addEventListener("mouseleave", deShow)

    // 3. 中等盒子中的黑色遮罩层
    // 实现思路:
    // 3.1 显示隐藏 黑色遮罩 的盒子
    middle.addEventListener("mouseenter", function () {
        layer.style.display = "block"
    })

    middle.addEventListener("mouseleave", function () {
        layer.style.display = "none"
    })
    // 3.2 让黑色这招跟着鼠标走,需要用到鼠标移动事件 mousemove 让黑色盒子移动的核心思想: 不断的将鼠标在中等盒子内的坐标给黑色遮罩层,这样遮罩层就可以跟着一起移动了

    middle.addEventListener("mousemove", function (e) {
        // 1. 先得到鼠标在整个页面的坐标
        let mouseX = e.pageX
        let mouseY = e.pageY

        // 2. 再得到当前盒子在整个页面的坐标
        let boxX = middle.getBoundingClientRect().left
        let boxY = middle.getBoundingClientRect().top

        let x = mouseX - boxX
        // 3. 盒子距顶部的距离会根据鼠标滚动页面的变化而变化,所以需要减去鼠标滚动的距离
        let y = mouseY - boxY - document.documentElement.scrollTop

        // 4. 不断的将鼠标在中等盒子内的坐标给黑色遮罩层
        // 限定水平方向大于等于0,小于等于350
        // 限定垂直方向大于等于0,小于等于466
        // 水平坐标x,如果小于等于100(阴影遮罩宽度的一半),移动距离固定为0,不应该移动
        // 水平坐标x,如果大于等于100,小于等于350-200(整个遮罩层的宽度),则移动距离为x-100(阴影遮罩宽度的一半)
        // 水平坐标x,如果大于等于250,移动距离固定为350-200(整个遮罩层的宽度),就不应该移动了
        // 垂直坐标y,同理
        if (0<=x<350 && 0<=y<=466){
            let mx=0,my=0
            if (x<=100) mx=0
            if (x>=250) mx=150
            if (x>=100&&x<=250) mx = x - 100
            layer.style.left = mx + "px"

            if (y<=100) my=0
            if (y>=366) my=266
            if (y>=100 && y<=366) my = y - 100
            layer.style.top = my + "px"

            // 3.3 大盒子的背景图片坐标要跟着鼠标在中等盒子的移动而反向移动, 是它的2倍像素
            large.style.backgroundPositionX = -(mx * 2) + "px"
            large.style.backgroundPositionY = -(my * 2) + "px"
        }
    })

</script>
</body>
</html>
posted @ 2024-05-16 17:00  河图s  阅读(46)  评论(0)    收藏  举报