JavaScript 进阶5:WebAPI:DOM- 网页特效篇

中科蓝讯AB536X/AB892X芯片开发避坑指南:Downloader配置中那些容易忽略的细节 本文详细解析中科蓝讯AB536X/AB892X芯片开发中Downloader配置的关键细节,包括软开关机实现、触摸灵敏度调试、量产校频等常见问题。特别针对无PR口芯片的替代方案、触摸参数优化、校频流程等易忽略环节提供实用解决方案,帮助开发者规避量产风险,提升开发效率。 阅读详情

JavaScript 进阶5:WebAPI:DOM- 网页特效篇

Date: January 28, 2023
Text: 轮播图高级版待解决
滚动事件、加载事件、元素大小和位置(scroll、offset、client)、轮播图案例


目标

  1. 能够制作常见的网页特效
  2. 具备制作常见网页焦点图的能力



滚动事件和加载事件

滚动事件

概念:当页面进行滚动时触发的事件

为什么要学?

很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部

事件名:scroll

监听整个页面滚动:

// 页面滚动事件
window.addEventListener('scroll', function() {})

给 window 或 document 添加 scroll 事件

监听某个元素的内部滚动直接给某个元素加即可

案例:

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            body {
                height: 3000px;
            }
    
            div {
                overflow: auto;
                width: 200px;
                height: 200px;
                background-color: pink;
            }
        </style>
    </head>
    
    <body>
        <div>
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
    
        </div>
        <script>
            let div = document.querySelector('div')
            window.addEventListener('scroll', function () {
                console.log(111)
            })
            // div.addEventListener('scroll', function () {
            //     console.log(111)
            // })
        </script>
    </body>
    
    </html>
    


加载事件

加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

为什么要学?

有些时候需要等页面资源全部处理完了做一些事情

老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到

事件名:load

监听页面所有资源加载完毕:

给 window 添加 load 事件

// 页面加载事件
window.addEventListener('load', function() {
		// 执行的操作
})

注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载

事件名:DOMContentLoaded

监听页面DOM加载完毕:

给 document 添加 DOMContentLoaded 事件

document.addEEventListener('DOMContentLoaded', function () {
		// 执行的操作
})

案例:

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            body {
                height: 3000px;
            }
    
            div {
                overflow: auto;
                width: 200px;
                height: 200px;
                background-color: pink;
            }
        </style>
        <script>
            window.addEventListener('load', function () {
                let div = document.querySelector('div')
                console.log(div)
            })
        </script>
    </head>
    
    <body>
        <div>
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
            我里面可以放很多的文字
    
        </div>
        <script>
            // let div = document.querySelector('div')
    
        </script>
    </body>
    
    </html>
    

总结:

  1. 页面滚动事件如何添加?
    scroll
    监听整个页面滚动给 window 或 document 加

  2. 加载事件有哪两个?如何添加?

    1. load 事件

      监听整个页面资源给 window 加

  3. DOMContentLoaded

    1. 给 document 加,当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载



元素大小和位置

目标:掌握元素大小和位置的获取方法,为后续网页特效打基础

scroll家族

使用场景:

我们想要页面滚动一段距离,比如100px,就让某些元素显示隐藏,那我们怎么知道,页面滚动了

100像素呢?就可以使用scroll 来检测页面滚动的距离~~~

获取宽高:

获取元素的内容总宽高(不包含滚动条)返回值不带单位

scrollWidth和scrollHeight

获取位置:

获取元素内容往左、往上滚出去看不到的距离

scrollLeft和scrollTop

这两个属性是可以修改的

Untitled

div.addEventListener('scroll', function () {
		console.log(this.scrollTop)
})

开发中,我们经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素

// 页面滚动事件
window.addEventListener('scroll', function() {
		// document.documnetElement.scrollTop  获得当前页面被卷去的头部
		let num = document.documentElement.scrollTop
		console.log(num)
		document.documentElement.scrollTop = 500 //注意这里没有单位
}

注意事项:

document.documentElement HTML文档返回对象为HTML元素

Untitled

案例:

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            body {
                height: 3000px;
            }
        </style>
    </head>
    
    <body>
        <script>
            console.log(document.documentElement) // 返回 html 元素
            // 可以修改 但是不要带单位
    
            // 先做页面滚动事件
            window.addEventListener('scroll', function () {
                // console.log(11) 
                // 在得到页面滚动的距离  scrollTop
                console.log(document.documentElement.scrollTop)
                // document.documentElement.scrollTop = 500
            })
    
        </script>
    </body>
    
    </html>
    

总结:

  1. scrollWidth和scrollHeight是得到元素什么的宽高?
    内容
    不包含滚动条

  2. 被卷去的头部或者左侧用那个属性?是否可以读取和修改?

    scrollTop / scrollLeft
    可以读取,也可以修改(赋值)

  3. 检测页面滚动的头部距离(被卷去的头部)用那个属性?

    document.documentElement.scrollTop


案例:页面滚动显示返回顶部按钮

需求:当页面滚动500像素,就显示返回顶部按钮,否则隐藏, 同时点击按钮,则返回顶部

分析:

①:用到页面滚动事件

②:检测页面滚动大于等于100像素,则显示按钮

③:点击按钮,则让页面的scrollTop 重置为 0

https://www.notion.so

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
    
            .content {
                width: 1000px;
                height: 3000px;
                background-color: pink;
                margin: 0 auto;
            }
    
            .backtop {
                display: none;
                width: 50px;
                left: 50%;
                margin: 0 0 0 505px;
                position: fixed;
                bottom: 60px;
                z-index: 100;
            }
    
            .backtop a {
                height: 50px;
                width: 50px;
                background: url(./images/bg2.png) 0 -600px no-repeat;
                opacity: 0.35;
                overflow: hidden;
                display: block;
                text-indent: -999em;
                cursor: pointer;
            }
        </style>
    </head>
    
    <body>
        <div class="content"></div>
        <div class="backtop">
            <img src="./images/close2.png" alt="">
            <a href="javascript:;"></a>
        </div>
        <script>
            // 0 获取元素
            let backtop = document.querySelector('.backtop')
            // 一. 页面滚动事件
            window.addEventListener('scroll', function () {
                // 2. 页面检测滚动的距离
                // console.log(document.documentElement.scrollTop)
                let num = document.documentElement.scrollTop
                // 3. 进行判断显示和隐藏
                if (num >= 500) {
                    //显示那个元素
                    backtop.style.display = 'block'
                } else {
                    // 否则隐藏元素
                    backtop.style.display = 'none'
    
                }
    
            })
    
            // 二、点击链接返回顶部 backtop.children[1]
            backtop.children[1].addEventListener('click', function () {
                // 返回顶部
                // scrollTop 可读写
                document.documentElement.scrollTop = 0
            })
        </script>
    </body>
    
    </html>
    


offset家族

使用场景:

Untitled

前面案例滚动多少距离,都是我们自己算的,最好是页面

滚动到某个元素,就可以做某些事。

简单说,就是通过js的方式,得到元素在页面中的位置

这样我们可以做,页面滚动到这个位置,就可以返回顶部的小盒子显示…

获取宽高:

获取元素的自身宽高、包含元素自身设置的宽高、padding、border

offsetWidth和offsetHeight

获取位置:

获取元素距离自己定位父级元素的左、上距离

offsetLeft和offsetTop 注意是只读属性

Untitled

总结:

  1. offsetWidth和offsetHeight是得到元素什么的宽高?

    内容 + padding + border

  2. offsetTop和offsetLeft 得到位置以谁为准?

    带有定位的父级

    如果都没有则以 文档左上角 为准


案例:仿京东固定导航栏

需求:当页面滚动到秒杀模块,导航栏自动滑入,否则滑出

分析:

①:用到页面滚动事件

②:检测页面滚动大于等于 秒杀模块的位置 则滑入,否则滑出

Untitled

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
    
            .content {
                overflow: hidden;
                width: 1000px;
                height: 3000px;
                background-color: pink;
                margin: 0 auto;
            }
    
            .backtop {
                display: none;
                width: 50px;
                left: 50%;
                margin: 0 0 0 505px;
                position: fixed;
                bottom: 60px;
                z-index: 100;
            }
    
            .backtop a {
                height: 50px;
                width: 50px;
                background: url(./images/bg2.png) 0 -600px no-repeat;
                opacity: 0.35;
                overflow: hidden;
                display: block;
                text-indent: -999em;
                cursor: pointer;
            }
    
            .header {
                position: fixed;
                top: -80px;
                left: 0;
                width: 100%;
                height: 80px;
                background-color: purple;
                text-align: center;
                color: #fff;
                line-height: 80px;
                font-size: 30px;
                transition: all .3s;
            }
    
            .sk {
                width: 300px;
                height: 300px;
                background-color: skyblue;
                margin-top: 600px;
            }
        </style>
    </head>
    
    <body>
        <div class="header">我是顶部导航栏</div>
        <div class="content">
            <div class="sk">秒杀模块</div>
        </div>
        <div class="backtop">
            <img src="./images/close2.png" alt="">
            <a href="javascript:;"></a>
        </div>
        <script>
            let sk = document.querySelector('.sk')
            let header = document.querySelector('.header')
            // 1. 页面滚动事件
            window.addEventListener('scroll', function () {
                // console.log(11)
                // 要检测滚动的距离
                // console.log(document.documentElement.scrollTop)
                // console.log(sk.offsetTop)
                // 2. 要检测滚动的距离 >= 秒杀模块的offsetTop 则滑入
                if (document.documentElement.scrollTop >= sk.offsetTop) {
                    // alert('改吃饭了')
                    header.style.top = '0'
                } else {
                    header.style.top = '-80px'
                }
            })
    
        </script>
    </body>
    
    </html>
    

案例:电梯导航

需求:点击可以页面调到指定效果

分析:

①:点击当前 小导航,当前添加active,其余移除active

②:得到对应 内容 的 offsetTop值

③:让页面的 scrollTop 走到 对应 内容 的 offsetTop

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
    
            body {
                height: 3000px;
            }
    
            .aside {
                position: fixed;
                left: 0;
                top: 50%;
                transform: translateY(-50%);
            }
    
            .item {
                height: 40px;
                line-height: 40px;
                text-align: center;
                padding: 0 10px;
                cursor: pointer;
            }
    
            .active {
                background-color: red;
                color: #fff;
            }
    
            .content {
                width: 660px;
                margin: 400px auto;
            }
    
            .neirong {
                height: 300px;
                margin-bottom: 20px;
                color: #fff;
            }
    
            .content1 {
                background-color: red;
            }
    
            .content2 {
                background-color: blue;
            }
    
            .content3 {
                background-color: orange;
            }
    
            .content4 {
                background-color: yellowgreen;
            }
        </style>
    </head>
    
    <body>
    
        <div class="aside">
            <div class="item active">男装/女装</div>
            <div class="item">儿童服装/游乐园</div>
            <div class="item">电子产品</div>
            <div class="item">电影/美食</div>
        </div>
    
        <div class="content">
            <div class="neirong content1">男装/女装</div>
            <div class="neirong content2">儿童服装/游乐园</div>
            <div class="neirong content3">电子产品</div>
            <div class="neirong content4">电影/美食</div>
        </div>
    
        <script>
    
            // 1. 获元取素  
            let items = document.querySelectorAll('.item')
            // 内容的盒子获取
            let neirongs = document.querySelectorAll('.neirong')
            // 2. 左侧aside 模块 点击谁,谁高亮
            for (let i = 0; i < items.length; i++) {
                items[i].addEventListener('click', function () {
                    // 找到上一个active 移除类
                    document.querySelector('.aside .active').classList.remove('active')
                    // 点击谁谁添加类
                    this.classList.add('active')
                    // 3. 右侧内容跟随走动  让页面滚动到对应的offsetTop值位置
                    // console.log(neirongs[i].offsetTop) 不用给单位
                    document.documentElement.scrollTop = neirongs[i].offsetTop
                })
            }
    
        </script>
    </body>
    
    </html>
    


client家族

获取宽高:

获取元素的可见部分宽高(包含padding,不包含边框,滚动条等)

clientWidth和clientHeight

获取位置:

获取左边框和上边框宽度clientLeft和clientTop 注意是只读属性

Untitled

会在窗口尺寸改变的时候触发事件:resize

window.addEventListener('resize', function () {
		// 执行的代码
})

检测屏幕宽度:

window.addEventListener('resize', funtion () {
		let w = document.documentElement.clientWidth
		console.log(w)
})

总结:

  1. offset家族

获取元素自身大小:包括自身设置的宽高、padding、border

获取元素距离定位父级的左和上距离 只读属性

  1. client家族

获取元素可见区域的大小

获取元素左、上边框距离 只读属性

  1. scroll家族

获取元素内容的总大小

获取元素向左向上滚出去看不见的距离 可读写属性




综合案例

轮播图案例

效果:

Untitled

需求①:小图标鼠标经过事件

鼠标经过小图片,当前高亮,其余兄弟变淡 添加类

需求② :大图片跟随变化

对应的大图片跟着显示,如果想要过渡效果,可以使用opacity效果,可以利用CSS淡入淡出的效果,还是添加类

需求③:右侧按钮播放效果

点击右侧按钮,可以自动播放下一张图片

需要一个变化量 index 不断自增

然后播放下一张图片

如果到了最后一张,必须要还原为第1张图片

教你一招: 索引号 = 索引号 % 数组长度 (放到播放前面)

需求④:解决一个BUG

点击右侧按钮可以实现播放下一张,但是鼠标经过前面的,播放就会乱序
解决方案: 让变化量(索引号) 重新赋值为 当前鼠标经过的索引号

需求⑤:左侧按钮播放效果

点击左侧按钮,可以自动播放上一张图片
需要一个变化量 index 不断自减
然后播放上一张图片
如果到了第一张,必须要从最后一张播放
教你一招: 索引号 = (数组长度 + 索引号) % 数组长度

需求⑥:
因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common

需求⑦:开启定时器

其实定时器自动播放,就相当于点击了右侧按钮,此时只需要, right.click()

需求⑧:

鼠标经过停止定时器 (清除定时器)

鼠标离开开启定时器 (开启定时器)

  • Code:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>QQ音乐轮播图</title>
      <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
        }
    
        li {
          list-style: none;
        }
    
        .main {
          width: 700px;
          margin: auto;
          background: #000;
        }
    
        .slides {
          height: 320px;
          position: relative;
        }
    
        .slides ul li {
          /* display: none; */
          position: absolute;
          top: 0;
          left: 0;
          opacity: 0;
          /* 这里实现淡入淡出的关键 */
          transition: all .3s;
        }
    
        .slides li.active {
          /* display: block; */
          opacity: 1;
        }
    
        .slides .extra {
          width: 700px;
          height: 53px;
          line-height: 53px;
          position: absolute;
          bottom: 0px;
          background-color: rgba(0, 0, 0, 0.8);
          z-index: 10;
        }
    
        .slides .extra h3 {
          width: 82%;
          margin: 0;
          margin-right: 20px;
          padding-left: 20px;
          color: #98E404;
          font-size: 28px;
          float: left;
          font-weight: 500;
          font-family: "Microsoft Yahei", Tahoma, Geneva;
        }
    
        .slides .extra a {
          width: 30px;
          height: 29px;
          display: block;
          float: left;
          margin-top: 12px;
          margin-right: 3px;
          background-image: url(./assets/icon_focus_switch.png);
        }
    
        .slides .extra .prev {
          background-position: 0 0;
        }
    
        .slides .extra .prev:hover {
          background-position: -30px 0;
        }
    
        .slides .extra .next {
          background-position: -60px 0;
        }
    
        .slides .extra .next:hover {
          background-position: -90px 0;
        }
    
        .indicator {
          padding: 10px 0;
        }
    
        .indicator ul {
          list-style-type: none;
          margin: 0 0 0 4px;
          padding: 0;
          overflow: hidden;
        }
    
        .indicator ul li {
          position: relative;
          float: left;
          width: 60px;
          margin: 0 4px 0 5px;
          text-align: center;
    
          cursor: pointer;
        }
    
        .indicator li img {
          display: block;
          border: 0;
          text-align: center;
          width: 60px;
        }
    
        .indicator li .mask {
          width: 60px;
          height: 60px;
          position: absolute;
          top: 0;
          left: 0;
          background-color: rgba(0, 0, 0, 0.4);
        }
    
        .indicator li .border {
          display: none;
          width: 54px;
          position: absolute;
          bottom: 0;
          left: 0;
          z-index: 20;
          border: 3px solid #98E404;
        }
    
        /* li里面的mask 和 border 刚开始都是显示的 */
        /* 我们写一个样式css */
        .indicator .active .mask {
          display: none;
        }
    
        .indicator .active .border {
          display: block;
        }
      </style>
    </head>
    
    <body>
      <div class="main">
        <div class="slides">
          <ul>
            <li class="active"><a href="#"><img src="./assets/b_01.jpg" alt="第1张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_02.jpg" alt="第2张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_03.jpg" alt="第3张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_04.jpg" alt="第4张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_05.jpg" alt="第5张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_06.jpg" alt="第6张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_07.jpg" alt="第7张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_08.jpg" alt="第8张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_09.jpg" alt="第9张图的描述信息"></a></li>
            <li><a href="#"><img src="./assets/b_10.jpg" alt="第9张图的描述信息"></a></li>
          </ul>
    
          <div class="extra">
            <h3>第1张图的描述信息</h3>
            <a class="prev" href="javascript:;"></a>
            <a class="next" href="javascript:;"></a>
          </div>
        </div>
        <div class="indicator">
          <ul>
            <li class="active">
              <img src="assets/s_01.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_02.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_03.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_04.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_05.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_06.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_07.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_08.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_09.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
            <li>
              <img src="assets/s_10.jpg">
              <span class="mask"></span>
              <span class="border"></span>
            </li>
          </ul>
        </div>
      </div>
      <script>
        // 轮播图开始啦
        // 需求①:小图标鼠标经过事件
        //   鼠标经过小图片,当前高亮,其余兄弟变淡  添加类
        let lis = document.querySelectorAll('.indicator li')
        let piclis = document.querySelectorAll('.slides ul li')
        let text = document.querySelector('.extra h3')
        let next = document.querySelector('.next')
        let prev = document.querySelector('.prev')
        let main = document.querySelector('.main')
    
        // 给多个小li绑定事件
        for (let i = 0; i < lis.length; i++) {
          lis[i].addEventListener('mouseenter', function () {
            // 选出唯一的那个active ,删除类
            document.querySelector('.indicator .active').classList.remove('active')
            // 鼠标经过谁,谁加上active 这个类
            this.classList.add('active')
    
            // 需求② :大图片跟随变化  一定要放到鼠标经过事件里面
            // 对应的大图片跟着显示,如果想要过渡效果,可以使用opacity效果,可以利用CSS淡入      淡出的效果,还是添加类
            // 选出唯一的那个active ,删除类
            document.querySelector('.slides ul .active').classList.remove('active')
            // 对应序号的那个 li,谁加上active 这个类
            piclis[i].classList.add('active')
            text.innerHTML = `第${i + 1}张图的描述信息`
    
            // 需求④:解决一个BUG
            // 点击右侧按钮可以实现播放下一张,但是鼠标经过前面的,播放就会乱序
            // 解决方案:  让变化量 index 重新赋值为 当前鼠标经过的索引号
            // 鼠标经过了那个小li 他的索引号就是 i 
            // 右侧按钮是通过 index 来了控制播放的
            index = i
          })
        }
    
        // 需求③:右侧按钮播放效果
        //   点击右侧按钮,可以自动播放下一张图片
        //   需要一个变化量  index 不断自增
        //   然后播放下一张图片
        //   如果到了最后一张,必须要还原为第1张图片
        //   教你一招: 索引号 = 索引号 % 数组长度 (放到播放前面)
        let index = 0  // 全局变量  信号量 控制器 为了给 右侧按钮和左侧按钮同时使用
        next.addEventListener('click', function () {
          index++
          // 选出 index 小图片 做操作
          // console.log(index)
          // if (index === lis.length) {
          //   index = 0
          // }
          index = index % lis.length
          common()
    
        })
    
        // 需求⑤:左侧按钮播放效果
        //   点击左侧按钮,可以自动播放上一张图片
        //   需要一个变化量  index 不断自减
        //   然后播放上一张图片
        //   如果到了第一张,必须要从最后一张播放
        //   教你一招: 索引号 = (数组长度 + 索引号) % 数组长度
        prev.addEventListener('click', function () {
          index--
          // 选出 index 小图片 做操作
          // console.log(index)
          if (index < 0) {
            index = lis.length - 1
          }
          // index = (lis.length + index) % lis.length
          common()
    
        })
    
        // 需求⑥:
        //   因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common
        function common() {
          document.querySelector('.indicator .active').classList.remove('active')
          lis[index].classList.add('active')
          // 选出 index 大图片 做操作
          document.querySelector('.slides ul .active').classList.remove('active')
          piclis[index].classList.add('active')
          text.innerHTML = `第${index + 1}张图的描述信息`
        }
    
        // 需求⑦:开启定时器
        //   其实定时器自动播放,就相当于点击了右侧按钮,此时只需要, next.click()
        let timer = setInterval(function () {
          // 自动调用右侧按钮的点击事件
          next.click()
        }, 1000)
        // 需求⑧:
        //   鼠标经过停止定时器 (清除定时器)
    
        main.addEventListener('mouseenter', function () {
          clearInterval(timer)
        })
        //   鼠标离开开启定时器 (开启定时器)
        main.addEventListener('mouseleave', function () {
          timer = setInterval(function () {
            // 自动调用右侧按钮的点击事件
            next.click()
          }, 1000)
        })
      </script>
    </body>
    
    </html>
    


拓展案例:手风琴

效果:

Untitled

  • Code:

    <!DOCTYPE html>
    <html>
    
    <head lang="en">
      <meta charset="UTF-8">
      <title>手风琴</title>
      <style>
        ul {
          list-style: none;
        }
    
        * {
          margin: 0;
          padding: 0;
        }
    
        div {
          width: 1200px;
          height: 400px;
          margin: 50px auto;
          border: 1px solid red;
          overflow: hidden;
        }
    
        div li {
          width: 240px;
          height: 400px;
          float: left;
          transition: all 500ms;
        }
    
        div ul {
          width: 1200px;
        }
      </style>
    </head>
    
    <body>
      <div id="box">
        <ul>
          <li>
            <a href="#">
              <img src="./images/1.jpg" alt="">
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./images/2.jpg" alt="">
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./images/3.jpg" alt="">
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./images/4.jpg" alt="">
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./images/5.jpg" alt="">
            </a>
          </li>
        </ul>
      </div>
    </body>
    <script>
      // 获取元素
      let box = document.querySelectorAll('li');// lis = [li, li, li, li, li]
      // 分析:
      // 1、鼠标进入显示图片,
      // 鼠标进入li,让当前li变成800,其他的li变成100
      for (let i = 0; i < box.length; i++) {
    
        box[i].addEventListener('mouseenter', function () {
          for (let j = 0; j < box.length; j++) {// 事件触发执行,为了让所有li变成240宽的
            box[j].style.width = '100px';
          }
          this.style.width = '800px'
        })
    
        box[i].addEventListener('mouseleave', function () {
          // 让所有的li变成240
          for (let j = 0; j < box.length; j++) {// 事件触发执行,为了让所有li变成240宽的
            box[j].style.width = '240px';
          }
        })
    
      }
    
    </script>
    
    </html>
    
微信对话开放平台智能对话模块的几个亮点 微信AI首席科学家牛成公布了最新开放方案,并重磅宣布全面开放各层次 NLP 能力。具体说来,微信 AI 迈出了“三大步”: 以硬件合作为核心的智言小微硬件开放平台 2.0 正式亮相; 公开以对话开放能力为核心的微信对话开放平台; 全面开放以自然语言处理能力为核心的 NLP 基础技术平台。 参考:微信9年:张小龙指明方向,微信AI全面开放NLP能力 今天公开课上隆重介绍了... 阅读详情

相关推荐

从爱好者到工程师:如何低成本体验RFSoC ZU47DR?性能实测与避坑指南

本文详细介绍了如何低成本体验赛灵思RFSoC ZU47DR芯片,包括二手开发板选购、租赁服务、精简开发环境搭建等实用方案。通过性能实测与避坑指南,帮助爱好者和工程师在有限预算下充分利用这款集成了ARM处理器和FPGA的高性能芯片,降低开发门槛。

weixin_42525005的博客 221

购物页面点叉号二维码隐藏的做法

隐藏此二维码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <ti.

weixin_51415327的博客 627

Clock Gating设计陷阱:为什么你的ICG cell总是导致setup violation?(附解决方案)

本文深入分析了数字IC设计中ICG(Integrated Clock Gating)单元导致setup时序违规的常见问题,包括时钟偏斜和数据路径过长两大核心原因。通过量化分析影响因素,提供了逻辑重组、寄存器重定时等优化策略,并介绍了预防性设计方法和物理实现阶段的优化技巧,帮助工程师有效解决ICG相关的setup violation问题。

weixin_29168153的博客 206

前端基本功---webAPI(2)案例

1、复习 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="box">123</div> &lt...

魔法革1996 534

Python模拟发送SOME/IP消息(Scapy模块)

SOMEIP提供服务、订阅、响应、通知等Python代码示例

liluo0815481的博客 3069

Python电商网站全站爬虫实战:以京东为例的数据采集与分析

随着电子商务的蓬勃发展,电商数据已成为市场研究、竞争分析和消费者行为研究的重要资源。本文详细介绍了如何使用Python最新技术栈构建一个高效的电商网站全站爬虫,以京东为例实现商品数据的自动化采集。文章涵盖了爬虫的法律与伦理考量、技术选型、反爬虫策略应对、分布式架构设计以及数据存储方案,并提供了完整的代码实现。本爬虫系统采用Scrapy-Redis分布式框架、Selenium动态渲染、智能代理轮换和机器学习验证码识别等先进技术,能够稳定高效地抓取京东全站商品数据,为电子商务研究提供数据支持。关键词。

2201_76125261的博客 415

Jquery:解决鼠标移入移出多次触发的问题

jq的鼠标移入移除事件: mouseover()鼠标移入(移入子元素也触发) mouseout()鼠标移出(离开子元素也触发) mouseenter()鼠标移入(移入子元素不触发) mouseleave()鼠标移出(离开子元素不触发) hover()鼠标移入移出(mouseenter与mouseleave的缩写) 示例代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <

qq_42961150的博客 3860

帆软报表开发-快速入门

数据可视化展示功能特点如下:选择权限管理 > 用户最终权限 > 汤姆(Tom) > 选择图表设计入门 > 打开查看权限。

郭宝的博客 5972

js控制网页动态效果

用原生js实现轮播图、倒计时、元素的显示与隐藏等效果

shenpkun的博客 1527

【国密】基于SM2的协同签名与协同解密方案

两方协同签名指客户端与服务端协同完成签名、验签操作,具体实现方案参考了信工所专利[3]。在业务应用中,两方或多方的协同签名一般采用门限签名方案可以用来构造。门限密码算法在多方协作的相关场景中应用十分广泛,可以实现数据联合授权、认证、密钥安全恢复、密钥安全交换等需求,在诸多分布式多方计算协议中均可见其身影。在上述两方协同签名方案中,最巧妙的地方在于签名值s分量的构造,通过一些列数学变换,得以恢复。以下从两方协同签名方案介绍入手,介绍门限密码在协同签名中的应用。解决上述问题的关键在于门限密码算法的巧妙构造。

听雨草堂 8391

Transformer实战(1)——词嵌入技术详解

词嵌入的核心思想是,通过将词语表示为稠密的向量,使得计算机可以更有效地处理和理解文本中的语义关系。在本节中,我们学习了单词分布式表示的概念及其实现,包括静态嵌入和动态嵌入,实现了 Word2Vec 和 GloVe 模型,并介绍了如何使用 Gensim API 探索嵌入空间。

盼小辉丶的博客 1万+

javascript网页特效(一)

      在制作网页特效可以使用CSS3,也可以编写javascript代码,现在把在工作中常用的有关javascript属性和方法总结一下,希望能对初学者有些帮助。     使用javascript制作网页特效,避免不了要获得元素的大小位置的数据,哪javascript中给我们提供了一些获得宽高位置的属性,主要用的一下家族的属性:       1.offset家族常用属性  2. scroll...

lk_080227的博客 5054

Windows 下 OpenClaw(小龙虾) 安装全记录:从零到一的保姆级图文教程(持续更新中)

本文主要介绍了Windows 下 OpenClaw 安装全记录:从零到一的保姆级图文教程,希望能对学习使用OpenClaw 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 步骤一 安装Node.js 2.2 步骤二:安装并配置OpenClaw 2.3 步骤三:配置模型 2.4 步骤四:对话 3. 后续使用步骤

weixin_43178406的博客 16万+

3.3.2JavaScript网页编程——WebAPI(JS之DOM网页特效篇)

1.scroll家族 获取元素内容的总大小 获取元素向左向上滚出去看不见的距离 可读写属性2.offset家族 获取元素自身大小:包括自身设置的宽高、padding、border 获取元素距离定位父级的左和上距离 只读属性3.client家族 获取元素可见区域的大小 获取元素左、上边框距离 只读属性。

lanmy_dl的博客 491

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

webAPI基础知识

1.前端js的组成部分:ECMAScript(语法), DOM,BOM2.API: application programming interface 应用程序接口生活中的接口:如遥控器程序中的接品:函数(我们学的内置对象函数就是接口),请求地址3.webAPI: 网页API接口,浏览器给我们提供了一些函数,我们只需要用函数1.什么是DOM: document Object Model 文档对象模型2.DOM树:文档,元素,节点 1.2根据 标签名称 找元素 document.getElement

qq_43784866的博客 856

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

JavaScript WebAPI、DOM知识整理

JavaScript WebAPI、DOM知识整理

weixin_52984349的博客 484

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JS_APIs之WebApi基础认知

DOM(Document Object Model--文档对象模型)是用来呈现以及与任意 HTML或 XML文档交互的API。白话文:DOM是浏览器提供的一套专门用来 操作网页内容 的功能DOM作用:开发网页内容特效和实现用户交互标准属性:标签天生自带的属性 比如classid title等,可以直接使用点语法操作比如: disabled、checked、selected自定义属性:- 在html5中推出来了专门的data-自定义属性- 在标签上一律以data-开头。

qq_75073393的博客 871

JavaScript进阶-webapi

复习:splice() 方法用于添加或删除数组中的元素。**注意:**这种方法会改变原始数组。splice(起始位置, 删除的个数)比如:1 添加元素 splice(起始位置,删除个数,添加数组元素) Web APIs - 第1天笔记 知道 ECMAScript 与 JavaScript 的关系 了解 DOM 的相关概念及DOM 的本质是一个对象 掌握查找节点的基本方法 掌握节点属性和文本的操作 能够使用间歇函数创建定时任务 介绍 严格意义上讲,我们在 JavaScript 阶段学习的知识绝大部

weixin_50262663的博客 998

JavaScript进阶篇(DOM BOM)

JavaScript进阶部分(DOM和BOM)是重点部分,跟着b站视频学习自己记的笔记,有不足之处欢迎大家指出。

qq_66193208的博客 3421

JavaScript基础——DOM

文章目录1、Web API2、DOM2.1 DOM 简介2.2 DOM树2.3 DOM对象3、获取DOM元素3.1 根据CSS选择器获取DOM元素3.1.1 选择匹配的第一个元素3.1.2 选择匹配多个元素3.2 其他方法获取DOM元素4、设置DOM元素的内容4.1 document.write()方法4.2 对象.innerText属性4.3 对象.innerHTML属性4.4 区别5、修改DOM元素的内容6、设置、修改元素样式属性6.1 通过style属性操作CSS7、定时器、间歇函数7.1 开启定时器

NGUP_LEE的博客 2027

JavaScript高级开发必备:Bom和Dom全解析

JavaScript BOM(浏览器对象模型)和DOM(文档对象模型)是前端开发中的两个重要概念。BOM是用于操作浏览器窗口、浏览器历史记录和浏览器位置等的API,而DOM则是用于操作HTML和XML文档中的元素和属性的API。通过使用BOM和DOM,开发人员可以创建交互性更强的网页,实现动态效果和用户交互功能。

会思想的苇草i的博客 1301

【前端三剑客三】 JavaScript

目录 1. 初识 JavaScript 1.1 什么是 JavaScript 1.2JavaScript 、HTML 、CSS 之间的关系 1.3JavaScript 的组成 2.JavaScript 的书写形式 2.1 行内式 2.2内嵌式 2.3外部式 3. JavaScript 基本语法 3.1 注释 3.2 输入输出 3.3 变量 3.3.1 变量初始化 3.3.2变量的命名规范 3.4 基本数据类型 3.5 流程控制 3.5.1if 3.5...

澄白易的博客 2580

JavaScript基础+JS API(DOM+BOM)

JavaScript基础一、JS的组成二、JS的基础1. JS输入输出语句2. 变量命名规范3. 数据类型3.1 变量类型简介3.2 数据类型的分类1) 简单数据类型(基本数据类型)① 数字型 Number② 字符串型 String③ 布尔型 Boolean④ 未定义类型 Undefined⑤ 空类型 Null2) 复杂数据类型(引用数字类型)3) 获取变量数据类型① 获取检测变量的数据类型 typeof② 字面量4) 数据类型转换① 转换为字符串类型② 转换为数字型(重点)③ 转换为布尔型5)标志符、关键

weixin_47398531的博客 849

JavaScript+WebAPI——笔记

运行在客户端(浏览器)的编程语言。实现人机交互效果作用:网页特效(监听用户的一些行为让网页作出对应的反馈)表单验证(针对表单数据的合法性进行判断)数据交互(获取后台的数据,渲染到前端服务端编程(node.js)组成ECMAScriptWeb APIsDOMBOM所有标签属性都能在这个对象上面找到修改该对象属性会自动映射到标签上在html5中推出专门的data-自定义属性在DOM对象中一律以dataset对象方式获取事件:编程时系统发生的动作/事情。

m0_73851065的博客 1364

JS-WebAPI-DOM01

DOM元素

m0_61086522的博客 297

Javascript_WebAPI_pink笔记

data -实例化//当前时间 const date = new Date() //指定时间 const date1 = new Date('2022-5-1 08:30:51')方法指定格式。

weixin_44362304的博客 178
上一篇: Web进阶:Day7 响应式、BootStrap、实战演练
下一篇: Hadoop配置手册2: 测试Hdfs和WordCount测试
CaptainDrake
博客等级 码龄6年 5363粉丝 187原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值