JavaScript Web API入门day7

目录

1.图片切换模块

2.鼠标经过以及离开中等盒子,大盒子的处理

3.黑色遮罩层的位置以及放大功能

4.放大镜的完整代码


1.图片切换模块

效果图:

思路分析:

①:鼠标经过小盒子,左侧中等盒子显示对应中等图片

  1. 获取对应的元素

  2. 采取事件委托的形式,监听鼠标经过小盒子里面的图片, 注意此时需要使用 mouseover 事件,因为需要事件冒泡触发small

  3. 让鼠标经过小图片的爸爸li盒子,添加类,其余的li移除类(注意先移除,后添加)

  4. 鼠标经过小图片,可以拿到小图片的src, 可以做两件事

    • 让中等盒子的图片换成这个 这个小图片的src

    • 让大盒子的背景图片,也换成这个小图片的 src (稍后做)

代码实现:

javascript 复制代码
<script>
        //1.获取对象
    const small = document.querySelector('.small')
    const middle = document.querySelector('.middle')
  
    //2.鼠标经过事件(因为用到事件委托,因此需要用到冒泡,用mouseover)
    small.addEventListener('mouseover', function (e) {
      // console.log(11)
      // 图片生效  
      if (e.target.tagName === 'IMG') {
        //排他思想   查找small下的active,并且移除
        this.querySelector('.active').classList.remove('active')
        //图片对象的父亲 也就是li ,添加active
        e.target.parentNode.classList.add('active')

        // 可以获取到图片地址
        // console.log(e.target.src)
        // 把图片地址赋值给中盒子的图片
        middle.querySelector('img').src = e.target.src
      }

    })
</script>

2.鼠标经过以及离开中等盒子,大盒子的处理

效果图:

思路分析:

②: 鼠标经过中等盒子,右侧大盒子显示

  1. 用到鼠标经过和离开,鼠标经过中盒子,大盒子 利用 display 来显示和隐藏

  2. 鼠标离开不会立马消失,而是有200ms的延时,用户体验更好,所以尽量使用定时器做个延时 setTimeout

  3. 显示和隐藏也尽量定义一个函数,因为鼠标经过离开中等盒子,会显示隐藏,同时,鼠标经过大盒子,也会显示和隐藏

  4. 给大盒子里面的背景图片一个默认的第一张图片

代码实现:

javascript 复制代码
<script>
    //1.获取对象
    const small = document.querySelector('.small')
    const middle = document.querySelector('.middle')
    const large = document.querySelector('.large')

    //2.鼠标经过事件(因为用到事件委托,因此需要用到冒泡,用mouseover)
    small.addEventListener('mouseover', function (e) {
      // console.log(11)
      // 图片生效  
      if (e.target.tagName === 'IMG') {
        //排他思想   查找small下的active,并且移除
        this.querySelector('.active').classList.remove('active')
        //图片对象的父亲 也就是li ,添加active
        e.target.parentNode.classList.add('active')

        // 可以获取到图片地址
        // console.log(e.target.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 timeout = 0
    //定义显示和隐藏函数
    function show() {
      //重置延时器(用户移动速度过快会出现bug)
      clearTimeout(timeout)
      large.style.display = 'block'
    }

    function hide() {
      //延迟器可以让用户体验更好
      timeout = 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'
    })

3.黑色遮罩层的位置以及放大功能

实现效果:

思路分析:

③: 黑色遮罩盒子跟着鼠标来移动

  1. 先做鼠标经过 中等盒子,显示隐藏 黑色遮罩 的盒子

  2. 让黑色遮罩跟着鼠标来走, 需要用到鼠标移动事件 mousemove

  3. 让黑色盒子的移动的核心思想:不断把鼠标在中等盒子内的坐标给黑色遮罩层 let top 值,这样遮罩层就可以跟着移动了

    • 需求

      • 我们要的是 鼠标在 中等盒子内的坐标, 没有办法直接得到

      • 得到1: 鼠标在页面中的坐标

      • 得到2: 中等盒子在页面中的坐标

    • 算法

      • 得到鼠标在页面中的坐标 利用事件对象的 pageX

      • 得到middle中等盒子在页面中的坐标 middle.getBoundingClientRect()

      • 鼠标在middle 盒子里面的坐标 = 鼠标在页面中的坐标 - middle 中等盒子的坐标

      • 黑色遮罩层不断得到 鼠标在middle 盒子中的坐标 就可以移动起来了

      注意 y坐标特殊,需要减去 页面被卷去的头部

      为什么不用 box.offsetLet 和 box.offsetTop 因为这俩属性跟带有定位的父级有关系,很容被父级影响,而getBoundingClientRect() 不受定位的父元素的影响

    • 限定遮罩的盒子只能在middle 内部移动,需要添加判断

      • 限定水平方向 大于等于0 并且小于等于 400

      • 限定垂直方向 大于等于0 并且小于等于 400

    • 遮罩盒子移动的坐标:

      • 声明一个 mx 作为移动的距离

      • 水平坐标 x 如果 小于等于100 ,则移动的距离 mx 就是 0 不应该移动

      • 水平坐标 如果 大于等于100 并且小于300,移动的距离就是 mx - 100 (100是遮罩盒子自身宽度的一半)

      • 水平坐标 如果 大于等于300,移动的距离就是 mx 就是200 不应该在移动了

      • 其实我们发现水平移动, 就在 100 ~ 200 之间移动的

      • 垂直同理

代码实现:

javascript 复制代码
<script>
    //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) {
      // console.log(11)
      // 鼠标距离左侧的位置
      // console.log(e.pageX)

      // 这里用getBoundingClientRect(),不用offset的原因是因为offset会受到定位的影响
      // console.log(this.getBoundingClientRect())

      // 得到黑色盒子相对于中等盒子的位置
      let x = e.pageX - this.getBoundingClientRect().left
      // 注意这里要减去被卷入的长度,不然遮罩会偏位,原因:滚动条滚动,this.getBoundingClientRect().top距离顶部变短
      let y = e.pageY - this.getBoundingClientRect().top - document.documentElement.scrollTop

      // 限定遮罩盒子在中等盒子内
      if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {
        //鼠标动了,黑色盒子不一定要移动
        let mx = 0, my = 0
        // 让遮罩限定在中等盒子内
        if (x < 100) mx = 0
        // 这里减100是因为100以下的不变坐标
        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'

        // 放大镜效果(相反方向)
        large.style.backgroundPositionX = -2 * mx + 'px'
        large.style.backgroundPositionY = -2 * my + 'px'
      }

    })
</script>

4.放大镜的完整代码

代码:

javascript 复制代码
  <script>
    //1.获取对象
    const small = document.querySelector('.small')
    const middle = document.querySelector('.middle')
    const large = document.querySelector('.large')

    //2.鼠标经过事件(因为用到事件委托,因此需要用到冒泡,用mouseover)
    small.addEventListener('mouseover', function (e) {
      // console.log(11)
      // 图片生效  
      if (e.target.tagName === 'IMG') {
        //排他思想   查找small下的active,并且移除
        this.querySelector('.active').classList.remove('active')
        //图片对象的父亲 也就是li ,添加active
        e.target.parentNode.classList.add('active')

        // 可以获取到图片地址
        // console.log(e.target.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 timeout = 0
    //定义显示和隐藏函数
    function show() {
      //重置延时器(用户移动速度过快会出现bug)
      clearTimeout(timeout)
      large.style.display = 'block'
    }

    function hide() {
      //延迟器可以让用户体验更好
      timeout = 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) {
      // console.log(11)
      // 鼠标距离左侧的位置
      // console.log(e.pageX)

      // 这里用getBoundingClientRect(),不用offset的原因是因为offset会受到定位的影响
      // console.log(this.getBoundingClientRect())

      // 得到黑色盒子相对于中等盒子的位置
      let x = e.pageX - this.getBoundingClientRect().left
      // 注意这里要减去被卷入的长度,不然遮罩会偏位,原因:滚动条滚动,this.getBoundingClientRect().top距离顶部变短
      let y = e.pageY - this.getBoundingClientRect().top - document.documentElement.scrollTop

      // 限定遮罩盒子在中等盒子内
      if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {
        //鼠标动了,黑色盒子不一定要移动
        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'

        // 放大镜效果(相反方向)
        large.style.backgroundPositionX = -2 * mx + 'px'
        large.style.backgroundPositionY = -2 * my + 'px'
      }

    })

  </script>
相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax