JS考核复写

1.页面返回顶部

要求: 点击按钮之后可以由快到慢地回到顶部,处于顶部位置时按钮消 失,按钮位于页面的右下方

解:1.绑定滚动事件

(1)获取页面高度;(2)设置if语句显示/隐藏按钮

2.绑定点击事件

(1)设置滚动位置;(2)设置滚动方式

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      height: 1000px;
    }
    button {
      /* 固定按钮在视口的一个位置 */
      position: fixed;
      right: 10px;
      bottom: 10px;
    }
  </style>
</head>
<body>
  <button style="display: none;">返回</button>
  <script>
    // 获取元素
    const btn = document.querySelector('button')
    // 绑定滚动事件
    window.addEventListener('scroll', function () {
      // 获取页面高度
      const n = document.documentElement.scrollTop
      // 判断页面高度大于100px就显示按钮,否则就隐藏
      if (n >=100) {
        btn.style.display = 'block'
      } else {
        btn.style.display = 'none'
      }
    })
    // 绑定点击事件
    btn.addEventListener('click', function () {
      // 设置滚动模式
      scrollTo({
        top:0,
        style:'smooth'
      })
    })
  </script>
</body>
</html>

瀑布流布局

要求: 多个等宽的图片进行穿插排序成六列,并且在目前显示的最后一张 图片显示之后,再进行下拉时能够在进行加载其他图片,每次下拉 显示20-30张图片。

解:1.先设置一个页面加载事件

2.设瀑布流函数

(1)获取子元素,视口宽度,再设置列数和容器宽度;

(2)把图片的高度放进一个数组中

(3)遍历数组找到高度最小的图片,将下一张放在其下方,最后更新高度

3.加载锁:防止滚动时重复触发加载

4.设置生成新图片的函数

5.绑定滚动事件

(1)获取容器距离顶部的距离,容器自身高度,视口高度;

(2)滚动至底部触发加载,用模拟异步加载

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
   img {
    width: 200px;
   }
   .box1 {
    width: 100%;
    position: relative;
    margin: auto;
   }
   .box2 {
    position: absolute;
    float: left;
    
   }
  </style>
</head>
<body>
  <div class="box1">
    <div class="box2">
      <img src="./image/1.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/2.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/3.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/4.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/5.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/6.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/7.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/8.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/9.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/10.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/10.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/11.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/12.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/13.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/14.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/15.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/16.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/17.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/18.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/19.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/20.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/1.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/2.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/3.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/4.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/5.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/6.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/7.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/8.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/9.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/10.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/10.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/11.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/12.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/13.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/14.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/15.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/16.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/17.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/18.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/19.jpg" alt="">
    </div>
    <div class="box2">
      <img src="./image/20.jpg" alt="">
    </div>
  </div>
  <script>
    // 页面加载完成事件(当页面加载完成,才执行大括号的回调函数)
    // 必须要这样写,因为后面还要调用,绑定事件不好再调用
    window.onload = function () {
      waterFull()
    }
    
    function waterFull () {
      // 获取函数
      const box1 = document.querySelector('.box1')
      const box2 = document.querySelectorAll('.box2')
      // 单个子元素的宽度
      let width = box2[0].offsetWidth
      // 获取浏览器视口宽度
      let clientWidth = document.documentElement.clientWidth
      // 设置瀑布流的列数
      let columnCount = 6
      // 设置容器宽度:列数X子元素宽度
      box1.style.width = width*columnCount + 'px'
      // 创建一个空数组,储存每列的当前高度
      let arr = []
      for (let i = 0;i < box2.length; i++) {
        // 第一行
        if (i < columnCount) {
          box2[i].style.top = '0px' // 第一行六个元素放在对应列的顶部
          box2[i].style.left = i*width + 'px' // 实现瀑布流的一列一个,横向平铺
          arr.push(box2[i].offsetHeight) // 在空数组增加第一行每列的高度
        } else {// 第二排往后元素,放在"当前最矮列"的下方
          // 找到数组里的最小值
          let min = Math.min(...arr)
          // 找到最小值的索引
          let index = arr.indexOf(min)
          // 把接下来的图片放在高度最小的图片下面
          box2[i].style.top = min + 'px'
          // 对齐高度最小的水平位置
          box2[i].style.left = box2[index].offsetLeft + 'px'
          // 更新该列的总高度
          arr[index] += box2[i].offsetHeight
        }
      }
    }
    // 加载锁:防止滚动时重复触发加载
    let isloading = false
    // 生成更多图片的函数
    function moreimage () {
      // 创建一个空图片数组
      let image = []
      // 随机生成10-20个图片元素
      for(let i = 1; i < Math.floor(Math.random() * 11) + 10; i++) {
        // 创建一个指定的元素
        let img = document.createElement('img')
        // 图片路径
        img.src = `./image/${i}.jpg`
        // 给新图片添加图片的class
        img.classList.add('box2')
        // 添加图片到空图片数组里
        image.push(img)
      }
      return image
    }
    // 滚动事件:判断是否到页面底部
    window.addEventListener('scroll', function () {
      const box1 =document.querySelector('.box1')
      // 容器距离页面顶部的距离
      let box1Top = box1.offsetTop
      // 容器自身高度
      let box1Height = box1.offsetHeight
      // 视口高度
      let clientHeight = document.documentElement.clientHeight
      // 滚动到容器底部时触发加载
      if (box1Height + box1Top - clientHeight <= 0 && !isloading) {
        isloading =true // 锁定加载状态
        // 模拟异步加载(加入图片,达到无限循环的效果)
        setTimeout(function () {
          // 生成新图片元素数组
          let moreimages = moreimage() 
          const box1 = document.querySelector('.box1')
          // 遍历数组,把图片加到容器中
          moreimages.forEach(box2 => {box1.appendChild(box2)})
          waterFull() // 重新布局瀑布流
          isloading = false // 解锁加载状态
        })
      }
    })
  </script>
</body>
</html>

3.随机点名

要求: 分为上下两个部分,上方为显示区域,下方为控制区域。显示区域显示五十位群成员的学号和姓名,控制区域由开始和结束两个按钮 组成。点击开始按钮,显示区域里的内容开始滚动,点击结束按钮,内容滚动停止,随机显示一位成员的学号和姓名。

解:1.设置数组

(那个展示区好像是可以不用写的qwq)

2.存储定时器,用于后续清除

3.存储随机的学生索引

4.获取元素

5.绑定开始键的点击事件

(1)清除定时器;(2)启动定时器;(3)剩余一个学生的时候禁用button

5.绑定结束键的点击事件

(1)同上(1);(2)移除当前选中的学生(当数组中有学生时)

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    h2 {
      text-align: center;
    }
    .screen {
      width: 500px;
      height: 300px;
      border: 1px solid black;
      text-align: center;
      align-content: center;
      font-size: 36px;
      margin: 0 auto;
    }
    .btns {
     text-align: center;
     margin-top: 10px;
    }
    button {
      width: 100px;
    }
  </style>
</head>
<body>
  <h2>随机点名</h2>
  <div class="screen">学号 姓名</div>
  <div class="btns">
    <button class="start">开始</button>
    <button class="end">结束</button>
  </div>
  <script>
    // 设置数组
    const arr = [
      {
        num: 1,
        name: '灰太狼'
      },
      {
        num: 2,
        name: '红太狼'
      },
      {
        num: 3,
        name: '黄太狼'
      },
      {
        num: 4,
        name: '夜太狼'
      },
      {
        num: 5,
        name: '灰二太太狼'
      },
      {
        num: 6,
        name: '银太狼'
      },
      {
        num: 7,
        name: '白眼狼'
      },
      {
        num: 8,
        name: '拳击狼'
      },
      {
        num: 9,
        name: '武太狼'
      },
      {
        num: 10,
        name: '焦太狼'
      },
      {
        num: 11,
        name: '灰太狼'
      },
      {
        num: 12,
        name: '红太狼'
      },
      {
        num: 13,
        name: '黄太狼'
      },
      {
        num: 14,
        name: '夜太狼'
      },
      {
        num: 15,
        name: '灰二太太狼'
      },
      {
        num: 16,
        name: '银太狼'
      },
      {
        num: 17,
        name: '白眼狼'
      },
      {
        num: 18,
        name: '拳击狼'
      },
      {
        num: 19,
        name: '武太狼'
      },
      {
        num: 20,
        name: '焦太狼'
      },
    ]
    // 存储定时器ID,用于后续清除
    let time = 0
    // 存储随机选中的学生索引
    let random = 0
    // 获取元素
    const screen = document.querySelector('.screen')
    const start = document.querySelector('.start')
    const end = document.querySelector('.end')
    // 给start绑定点击事件
    start.addEventListener('click', function () {
      // 先清除之前的定时器(防止重复启动)
      clearInterval(time)
      // 启动定时器
      time = setInterval(function () {
        // 随机选中
        random = parseInt(Math.random()*arr.length)
        // 在screen上显示选中的学生信息
        screen.innerHTML = `学号:${arr[random].num}
        姓名:${arr[random].name}`
      },100)
      // 判断,若剩余最后一个学生则禁用开始键和结束键
      if (arr.length === 1) {
        start.disabled = end.disabled = true
      }
    })
    // 给end绑定点击事件
    end.addEventListener('click', function () {
      // 清除之前的定时器
      clearInterval(time)
      // 如果数组有学生,就从数组中删除选中的学生
      if (arr.length > 0) {
        arr.splice(random, 1)
      }
    })
  </script>
</body>
</html>

4.Tab选项卡

要求: 1.选项卡由英雄联盟、DOTA、风暴英雄、300英雄四块组成; 2.未选择时,默认选中第一个标签页;3.选择某一选项后,下方跳出对应游戏的相关介绍内容。

解:1.获取元素

2.遍历<a>标签

3.绑定鼠标移入事件

(1)取消导航栏当前激活的active;(2)给鼠标移入的a 添加active

(3)内容区同上(1)(2)【添加第 i+1 个.item】

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .tab {
      width: 500px;
      height: 300px;
      margin: 20px;
      border: 1px solid black;
    }
    .tab-nav {
      width: 100%;
      height: 60px;
      line-height: 60px;
      display: flex;
      justify-content: space-between;
    }
    ul {
      list-style: none;
      display: flex;
      /* margin-left: flex-end; */
    }
    li {
      margin: 0 20px;
      font-size: 14px;
    }
    a {
      text-decoration: none;
      /* border: 2px solid transparent; */
      color: #333;
    }
    a.active {
      /* border-color: #e1251b; */
      color: #e1251b;
    }
    .content {
      padding: 0 16px;
    }
    .item {
      display: none;
    }
    .content .item.active {
      display: block;
    }
  </style>
</head>
<body>
  <div class="tab">
    <div class="tab-nav">
      <ul>
        <li><a href="javascript:;" class="active">英雄联盟</a></li>
        <li><a href="javascript:;">DOTA</a></li>
        <li><a href="javascript:;">风暴英雄</a></li>
        <li><a href="javascript:;">300英雄</a></li>
      </ul>
    </div>
    <div class="content">
      <div class="item active">这是英雄联盟游戏</div>
      <div class="item">这是DOTA游戏</div>
      <div class="item">这是风暴英雄游戏</div>
      <div class="item">这是300英雄游戏</div>
    </div>
  </div>
  <script>
    // 获取元素
    const a = document.querySelectorAll('a')
    for (let i = 0;i <a.length;i++) {
      // 给a绑定鼠标移入事件
      a[i].addEventListener('mouseenter', function () {
        // 取消导航栏当前激活的active(移除'active'类)
        document.querySelector('.tab-nav .active').classList.remove('active')
        // 给鼠标移入的a添加active
        this.classList.add('active')
        // 取消内容区当前激活的active(移除'active'类)
        document.querySelector('.content .active').classList.remove('active')
        // 给内容区中第i+1个.item,添加active(显示当前标签)
        document.querySelector(`.content .item:nth-child(${i + 1})`).classList.add('active')
      })
    }
  </script>
</body>
</html>

动态表格

要求:

1.表格由专业班级学号1-10号同学的信息组成,包括:学号、姓 名、性别、二级学院、班级、专业、辅导员;

2.表格的奇数行字体为黑色,底色为白色;偶数行字体为白色,底 色为黑色;

3.表格的每一行后有一个删除按钮,点击后会跳出提示弹窗,确认后删除该行的内容,并且删除后上述的颜色规律保持不变:

4.表格的右上方有一个添加按钮,点击后跳出一个表单弹窗,可以填加新的学生的信息。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .box {
      position: relative;
    }
    table {
      border-spacing: 0;
    }
    td,th {
      border: 1px solid black;
      width: 150px;
      text-align: center;
    }
    a {
      cursor: pointer;
      text-decoration: none;
      color: inherit;
    }
    .box tbody tr:nth-child(2n) {
      color: white;
      background-color: black;
    }
    .box tbody tr:nth-child(2n-1) {
      color: black;
      background-color: white;
    }
    button {
      display: inline-block;
      width: 80px;
      line-height: 24px;
      position: fixed;
      right: 20px;
    }
    .box1 {
      width: 100%;
      height: 30px;
    }
    .box input {
      display: inline-block;
      width: 150px;
      height: 20px;
      border: none;
      text-align: center;
      font-size: 16px;
      background-color: inherit;
      color: inherit;
    }
  </style>
</head>
<body>
  <form action="" id="addFrom">
    <div class="box">
      <div class="box1">
        <table>
          <thead>
            <tr>
              <th>学号</th>
              <th>姓名</th>
              <th>性别</th>
              <th>二级学院</th>
              <th>班级</th>
              <th>专业</th>
              <th>辅导员</th>
              <th>删除</th>
            </tr>
          </thead>
          <tbody>

          </tbody>
        </table>
        <button>添加</button>
      </div>
    </div>
  </form>
  <script>
    window.addEventListener('load', function () {
      let content = [
         {
          num: 1,
          name: "灰太狼",
          gender: "男",
          school: "计算机工程学院",
          class: "3",
          subject: "计算机科学与技术",
          teacher: "xxx"
        },
        {
          num: 2,
          name: "红太狼",
          gender: "女",
          school: "计算机工程学院",
          class: "1",
          subject: "软件工程",
          teacher: "xxx"
        },
        {
          num: 3,
          name: "喜羊羊",
          gender: "男",
          school: "通信工程学院",
          class: "5",
          subject: "通信工程",
          teacher: "xxx"
        },
        {
          num: 4,
          name: "美羊羊",
          gender: "女",
          school: "电气工程学院",
          class: "1",
          subject: "计算机科学与技术",
          teacher: "xxx"
        },
        {
          num: 5,
          name: "懒洋洋",
          gender: "男",
          school: "计算机工程学院",
          class: "3",
          subject: "计算机科学与技术",
          teacher: "xxx"
        },
        {
          num: 6,
          name: "灰太狼",
          gender: "男",
          school: "计算机工程学院",
          class: "3",
          subject: "计算机科学与技术",
          teacher: "xxx"
        },
        {
          num: 7,
          name: "红太狼",
          gender: "女",
          school: "计算机工程学院",
          class: "1",
          subject: "软件工程",
          teacher: "xxx"
        },
        {
          num: 8,
          name: "喜羊羊",
          gender: "男",
          school: "通信工程学院",
          class: "5",
          subject: "通信工程",
          teacher: "xxx"
        },
        {
          num: 9,
          name: "美羊羊",
          gender: "女",
          school: "电气工程学院",
          class: "1",
          subject: "计算机科学与技术",
          teacher: "xxx"
        },
        {
          num: 10,
          name: "懒洋洋",
          gender: "男",
          school: "计算机工程学院",
          class: "3",
          subject: "计算机科学与技术",
          teacher: "xxx"
        }
      ]
      const tbody = document.querySelector('tbody')
      const btn = document.querySelector('button')
      for (let i = 0;i< content.length; i++) {
        const tr = document.createElement('tr')
        tr.innerHTML = `
        <td>${content[i].num}</td>
        <td>${content[i].name}</td>
        <td>${content[i].gender}</td>
        <td>${content[i].school}</td>
        <td>${content[i].class}</td>
        <td>${content[i].subject}</td>
        <td>${content[i].teacher}</td>
        <td>
          <a href="javascript:" data-id=${i}>删除</a>
        </td>
        `
        tbody.appendChild(tr)
      }
      const a = document.querySelectorAll('a')
      for (let i = 0; i < a.length;i++) {
        a[i].addEventListener('click', function () {
          alert('你确定要删除吗?')
          tbody.removeChild(this.parentNode.parentNode)
        })
      }
      btn.addEventListener('click', function (e) {
        e.preventDefault()
        const tr = document.createElement('tr')
        tbody.appendChild(tr)
        for (let k in content[1]) {
          const td = document.createElement("td")
          td.innerHTML = `<input type="text">`
          tr.appendChild(td)
        }
        const td = document.createElement('td')
        td.innerHTML = `<a href="#">删除</a>`
        tr.appendChild(td)
        const a = document.querySelectorAll('a')
        for (let i = 0; i < a.length; i++) {
          a[i].addEventListener('click', function () {
            alert('你确定要删除吗?')
            tbody.removeChild(this.parentNode.parentNode)        
          })
        }
      })
    })
  </script>
</body>
</html>

6.电子时钟的时间需与北京时间实时对应。

解:1.获取元素

2.定义时间更新函数

(1)创建Date对象;(2)得到当前时间;(3)个位数补零;(4)渲染给页面

3.页面加载后立即执行(初始化)

4.定时更新

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<style>

body {

display: flex;

}

.box1 {

display: flex;

width: 200px;

height: 200px;

border: 1px solid black;

font-size: 150px;

justify-content: center;

align-items: center;

}

.mask {

font-size: 150px;

display: flex;

margin-top: -20px;

}

</style>

</head>

<body>

<div class="box1" id="h"></div>

<div class="mask">:</div>

<div class="box1" id="m"></div>

<div class="mask">:</div>

<div class="box1" id="s"></div>

<script>

// 获取元素

const hour = document.querySelector('#h')

const min = document.querySelector('#m')

const sec = document.querySelector('#s')

// 定义时间更新函数

function getNowTime() {

let date = new Date() // 创建Date对象,获取当前系统的时间

let h = date.getHours() // 得到当前小时

let m = date.getMinutes() // 得到当前分钟

let s = date.getSeconds() // 得到当前秒

// 个位数前补0

h = h < 10 ? '0' + h : h

m = m < 10 ? '0' + m : m

s = s < 10 ? '0' + s : s

// 渲染给页面

hour.innerHTML = h

min.innerHTML = m

sec.innerHTML = s

}

getNowTime() // 页面加载后立即执行,确保打开页面就显示当前时间

setInterval(getNowTime, 1000) // 定时更新

</script>

</body>

</html>

7.表单验证码

1.表单需包含昵称、姓名、QQ、手机号、邮箱、密码、确认密码以 发送验证码及提交和重置按钮;

2.点击表单里的输入框,隐藏提示文字;

3.点击提交和重置按钮时,都需要有相应的提示;

4.在表单提交是,需要进行验证验证填写内容是否合理:昵称不超 过10个字、姓名不超过4个字、QQ号为长度小于等于10大于5位的数字、手机号为长度11位的数字、密码由字母和数字组成且大于8位小于16位、密码和确认密码需相同。

5.发送验证码按钮点击后,会被禁用;发送验证码按钮被点击后,按钮里面的内容会变化成1分钟的倒计时;待发送验证码按钮被触发后才可以点击提交按钮,需在验证码框里填写 0505,用弹窗提示成功。

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<div class="container">

<div class="card">

<form class="form">

<div data-prop="username" class="form-item">

<span class="zhanghao1"></span>

<input type="text" name="username" placeholder="设置昵称">

<span class="msg"></span>

</div>

<div data-prop="realname" class="form-item">

<span class="realname1"></span>

<input type="text" name="realname" placeholder="输入真实姓名">

<span class="msg"></span>

</div>

<div data-prop="QQ" class="form-item">

<span class="QQ1"></span>

<input type="text" name="QQ" placeholder="QQ号">

<span class="msg"></span>

</div>

<div data-prop="phone" class="form-item">

<span class="phone1"></span>

<input type="text" name="phone" placeholder="输入手机号码">

<span class="msg"></span>

</div>

<div data-prop="email" class="form-item">

<span class="email1"></span>

<input type="text" name="email" placeholder="输入邮箱">

<span class="msg"></span>

</div>

<div data-prop="password" class="form-item">

<span class="password1"></span>

<input type="password" name="password" placeholder="设置密码">

<span class="msg"></span>

</div>

<div data-prop="confirm" class="form-item">

<span class="confirm1"></span>

<input type="password" name="confirm" placeholder="确认密码">

<span class="msg"></span>

</div>

<div data-prop="code" class="form-item">

<span class="code1"></span>

<input type="text" name="code" placeholder="短信验证码">

<span class="msg"></span>

<button id="getcode">发送验证码</button>

</div>

<button class="submit">提交</button>

<button class="again">重置</button>

</form>

</div>

</div>

<script>

// 获取元素

const inp = document.querySelectorAll('input')

const submit = document.querySelector('.submit')

const again = document.querySelector('.again')

// username

const username =document.querySelector('[name=username]')

// 绑定change事件(失去焦点且内容发生改变的)

username.addEventListener('change', verifyUserName)

function verifyUserName() {

// 获取输入框的下一个兄弟元素(用来展示错误提示的<span>)

const span = username.nextElementSibling

// 定义正则规则:匹配"1~10个任意字符"

const reg = /^.{1,10}$/

// 校验输入值:不满足规则

if (!reg.test(username.value)) {

span.innerText = '昵称不超过10个字' // 显示错误提示

return false // 表示验证不通过

}

else {

span.innerText = '' // 清空提示

return true // 表示验证通过

}

}

// realname

const realname =document.querySelector('[name=realname]')

realname.addEventListener('change', verifyRealName)

function verifyRealName() {

const span = realname.nextElementSibling

const reg = /^.{1,4}$/

if (!reg.test(realname.value)) {

span.innerText = '姓名不超过4个字'

return false

}

else {

span.innerText = ''

return true

}

}

// qq

const QQ = document.querySelector('[name=QQ]')

QQ.addEventListener('change', verifyQQ)

function verifyQQ() {

const span = QQ.nextElementSibling

const reg = /^\d{6,10}$/

if(!reg.test(QQ.value)) {

span.innerText = '长度小于等于10大于5位的数字'

return false

}

span.innerText = ''

return true

}

// Phone

const phone = document.querySelector('[name=phone]')

phone.addEventListener('change', verifyPhone)

function verifyPhone() {

const span = phone.nextElementSibling

const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/

if(!reg.test(phone.value)) {

span.innerText = '请输入正确的11位手机号码'

return false

}

span.innerText = ''

return true

}

// password

const password = document.querySelector('[name=password]')

password.addEventListener('change', verifyPwd)

function verifyPwd() {

const span = password.nextElementSibling

const reg = /^[a-zA-Z0-9-_]{9,16}$/

if(!reg.test(password.value)) {

span.innerText = '密码由字母和数字组成且大于8位小于16位'

return false

}

span.innerText = ''

return true

}

// 输入框点击交互

inp.forEach(function(input) {

input.addEventListener('click',function () {

this.placeholder = '' // 用户点击输入框时,清空该输入框的placeholder

})

})

// 表单重置按钮

again.addEventListener('click', function () {

alert('您确定要重置吗?')

inp.forEach(function (input) {

input.value = ''

})

})

// 表单提交按钮

submit.addEventListener('click', function () {

alert('您确定要提交吗?')

const inpCode = document.querySelector('[name=code]')

// 除去内容前后空格

const inpValue = inpCode.value.trim()

// 校验验证码是否是"0505"

if(inpValue !== "0505") {

alert('请输入正确的验证码')

}

else {

alert('成功')

}

Pass () // 调用密码一致性校验函数

// 清空所有输入框

inp.forEach(function(input) {

input.value = ''

})

})

let flag = true // 控制验证码按钮是否可点击的标记

const code = document.querySelector('#getcode')

code.addEventListener('click', function (e) {

e.preventDefault() // 阻止按钮默认行为

if(flag) {

// 倒计时开始,标记为"不可点击"

flag =false

let i = 60

code.innerHTML = `${i}秒后重新获取`

// 启动定时器,每一秒执行一次

let timerId = setInterval(function () {

i--

code.innerHTML = `${i}秒后重新获取`

// 倒计时结束

if (i === 0) {

clearInterval(timerId) // 清除定时器

code.innerHTML = `重新获取`

flag = true // 标记为可点击

}

}, 1000)

}

})

function Pass () {

// 获取元素

const password = document.querySelector('[name=password]').value

const confirm = document.querySelector('[name=confirm]').value

// 校验两次输入的密码是否一致

if(password !== confirm) {

alert('两次密码输入不一致,请再次输入')

return false

}

else {

return true

}

}

</script>

</body>

</html>

8.滚动弹幕

1.页面上漂浮字体大小不一、颜色不一,从左向右滚动的弹幕;

2.底部中间有一个发送功能,可以发送新的弹幕;

3.底部的发送部分可以向下收起和弹出。

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<style>

.view {

position: relative;

width: 100%;

height: 400px;

border: 1px solid black;

}

.page {

position: fixed;

bottom: 0;

left: 0;

width: 100%;

background-color: rgb(139, 139, 139);

padding: 10px;

display: flex;

justify-content: center;

align-items: center;

transition: all 0.3s ease;

}

.inner {

width: 300px;

padding: 5px;

margin-right: 10px;

}

.send {

padding: 5px 10px;

}

.up {

position: absolute;

bottom: 10px;

left: 10px;

}

</style>

</head>

<body>

<div class="view"></div>

<div class="page">

<input type="text" placeholder="输入弹幕" class="inner">

<button class="send">发送</button>

</div>

<button class="up">收起/弹出</button>

<script>

// 获取元素

const view = document.querySelector('.view')

const page = document.querySelector('.page')

const inner = document.querySelector('.inner')

const send = document.querySelector('.send')

const up = document.querySelector('.up')

// 用于记录 "输入框是否被隐藏" 的状态 ------ 初始时输入框是显示的

let isInputHidden = false

// 创建并返回一个包含该文本的弹幕 DOM 元素

function createDanmuElement(text) {

const danmu = document.createElement('div')

danmu.textContent = text // 文本内容

danmu.style.position = 'absolute' // 文本定位

danmu.style.left = '-200px' // 弹幕进入

// 高度随机

danmu.style.top = Math.floor(Math.random() * (view.clientHeight - 30)) + 'px'

// 颜色随机

danmu.style.color = `rgb({Math.floor(Math.random() \* 256)}, {Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`

// 大小随机

danmu.style.fontSize = Math.floor(Math.random() * 20) + 12 + 'px'

danmu.style.whiteSpace = 'nowrap' // 弹幕不换行

view.appendChild(danmu) // 添加在后面

return danmu

}

function moveDanmu(danmu) {

// 弹幕初始位置

let left = -200

// 随机速度

const speed = Math.floor(Math.random() * 3) + 1

// 启动定时器:从左到右

const Timer = setInterval(() => {

left += speed // 右移动

danmu.style.left = left + 'px' // 设置弹幕的水平位置

// 当弹幕完全离开视图右侧

if (left > view.clientWidth) {

clearInterval(Timer) // 清除定时器

view.removeChild(danmu) // 清除弹幕

}

}, 10)

}

// 传输弹幕

send.addEventListener('click', function () {

const text = inner.value

// 创建弹幕DOM元素

const danmu1 = createDanmuElement(text)

moveDanmu(danmu1) // 让新创建的弹幕开始移动

inner.value = '' // 清空输入框

})

up.addEventListener('click', function () {

// 切换隐藏状态

isInputHidden =! isInputHidden

if (isInputHidden) {

page.classList.add('hidden') // 给输入区域添加隐藏类

up.textContent = '弹出' // 按钮文字改为弹出

}

else {

page.classList.remove('hidden') // 移除隐藏类,显示输入区域

up.textContent = '收起' // 按钮文字改为收起

}

})

// 弹幕

for (let i = 0; i < 10; i++) {

const text = `我一定会回来的`

const danmu = createDanmuElement(text)

moveDanmu(danmu)

}

</script>

</body>

</html>

1.鼠标移至图片上方,鼠标周围出现黄色的的正方形框,黄色矩形 框会随着鼠标的移动而移动;2.将黄色正方形框里的内容的长和宽均放大2.4倍,并在图片右边进行显示。

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

<style>

.small {

width: 450px;

height: 450px;

border: 1px solid #ccc;

float: left;

position: relative;

margin: 10px;

}

.big {

width: 450px;

height: 450px;

overflow: hidden;

position: relative;

display: none;

}

.mask {

width: 150px;

height: 150px;

background-color: yellow;

position: absolute;

top: 0px;

left: 0px;

opacity: .5;

cursor: move;

display: none;

}

.image {

position: absolute;

width: 450px;

height: 450px;

top: 0px;

left: 0px;

}

.img {

position: absolute;

top: 0px;

left: 0px;

}

</style>

</head>

<body>

<!-- 小图容器 -->

<div class="small">

<img src="./img/course12.png" alt="" class="image">

<!-- 透明图 -->

<div class="mask"></div>

</div>

<!-- 大图容器 -->

<div class="big">

<img src="./img/course12.png" alt="" class="img">

</div>

<script>

// 获取元素

const mask = document.querySelector('.mask')

const small = document.querySelector('.small')

const big = document.querySelector('.big')

const img = document.querySelector('.img')

const smallImg = document.querySelector('.image')

const ZOOM_SCALE = 2.4 // 放大倍数(大图是小图的2.4倍)

// 鼠标进入显示

small.addEventListener('mouseenter', function () {

mask.style.display = 'block'

big.style.display = 'block'

})

// 鼠标离开隐藏

small.addEventListener('mouseleave', function () {

mask.style.display = 'none'

big.style.display = 'none'

})

// 鼠标移动获取位置

small.addEventListener('mousemove', function (e) {

// 计算鼠标在小图容器内的相对位置

let x = e.pageX - this.offsetLeft // 鼠标相当于文档的位置

let y = e.pageY - this.offsetTop

// 让鼠标位于遮挡层中心

let maskX = x - mask.offsetWidth / 2

let maskY = y - mask.offsetHeight / 2

// 限制鼠标遮挡成不超过小图容器

let maskWidth = small.offsetWidth - mask.offsetWidth

let maskHeight = small.offsetHeight - mask.offsetHeight

if (maskX <= 0) {

maskX = 0

}else if (maskX >= maskWidth) {

maskX = maskWidth

}

if (maskY <= 0) {

maskY = 0

}else if (maskY >= maskHeight) {

maskY = maskHeight

}

// 设置者当场位置

mask.style.left = maskX + 'px'

mask.style.top = maskY + 'px'

// 技术按大图的反向移动距离

// 大图移动距离 = 遮罩位置 X (大图尺寸 - 大图容器尺寸) / (小图尺寸 - 遮罩尺寸)

let imgWidth = img.offsetWidth - small.offsetWidth

let imgHeight = img.offsetHeight - small.offsetHeight

let bigX = maskX * imgWidth / maskWidth;

let bigY = maskY * imgHeight / maskHeight;

// 移动大图(反向偏移,实现"跟随放大")

img.style.left = (-bigX) + 'px';

img.style.top = (-bigY) + 'px';

})

// 初始化大图尺寸

function initZoomSize() {

const smallImg = document.querySelector('.image');

const smallWidth = small.offsetWidth;

const smallHeight = small.offsetHeight;

// 设置大图尺寸为小图的2.4倍

img.style.width = (smallWidth * ZOOM_SCALE) + 'px';

img.style.height = (smallHeight * ZOOM_SCALE) + 'px';

}

</script>

</body>

</html>

11.省市区三级联动

通过三个下拉菜单的联动来实现,第一级下拉菜单为省级,第二级 下拉菜单为市级,第三级下拉菜单为区级。当点击第一级下拉菜 单,第二级菜单的内容会自动匹配;选择第二级菜单时,第三级菜单会自动生成。当我取消上一级菜单的选项时,次一级选项会自动消失。

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Document</title>

</head>

<body>

<!-- 三个下拉框 -->

<select name="" id="province">

<option value="">请选择省份</option>

</select>

<select name="" id="city">

<option value="">请选择城市</option>

</select>

<select name="" id="area">

<option value="">请选择区县</option>

</select>

<script>

// 数据定义:

const provinces = ['福建','江苏','河北']

const cities = [

'漳州市', '厦门市'\], \['南京市', '苏州市'\], \['石家庄市', '秦皇岛市'

]

const areas = [

\['芗城区','龙文区'\], \['思明区','同安区'\]\], \[\['玄武区','秦淮区'\], \['姑苏区','吴中区'\]\], \[\['桥西区','新华区'\], \['海港区','山海关区'\]

]

// 获取DOM元素

const provinceSelect = document.querySelector('#province')

const citySelect = document.querySelector('#city')

const areaSelect = document.querySelector('#area')

//动态填充选项函数

function creatOptions(select, data) {

select .options.length = 1 // 清空原有选项

data.forEach((item, index) => {

// 将新选项添加到下拉框中

select.options.add(new Option(item, index))

})

}

// 初始化省份下拉框

creatOptions(provinceSelect, provinces)

// 省份变化时,联动城市下拉

provinceSelect.onchange = function () {

const provinceIndex = this.value

if (provinceIndex >= 0) {

creatOptions(citySelect, cities[provinceIndex]);

areaSelect.options.length = 1 // 清空区域选项

}

}

// 城市变化时,联动区县下拉

citySelect.onchange = function () {

const provinceIndex = provinceSelect.value

const cityIndex = this.value

if (cityIndex >= 0) {

creatOptions(areaSelect, areas[provinceIndex][cityIndex]);

}

}

</script>

</body>

</html>
12.轮播图

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      box-sizing: border-box;
    }
    .box1 {
      width: 560px;
      height: 400px;
      overflow: hidden;
    }
    .box2 {
      width: 100%;
      height: 320px;
    }
    img {
      width: 100%;
      height: 100%;
      display: block;
    }
    .box3 {
      height: 80px;
      background-color: rgb(100.67,68);
      padding: 12px 12px 0 12px;
      position: relative;
    }
    .btn {
      position: absolute;
      right: 0;
      top: 12px;
      display: flex;
    }
    button {
      margin-right: 12px;
      width: 28px;
      height: 28px;
      appearance: none;
      border: none;
      background-color: rgba(255,255,255,0.1);
      color: #fff;
      border-radius: 4px;
      cursor: pointer;
    }
    .next,.prev {
      opacity: 0;
    }
    .box1:hover .next {
      opacity: 1;
    }
    .box1:hover .prev {
      opacity: 1;
    }
     .box3 .btn button:hover {
      background-color: rgba(255,255,255,0.2);
     }
     p {
      margin: 0;
      color: #fff;
      font-size: 18px;
      margin-bottom: 10px;
     }
     .indicator {
      margin: 0;
      padding: 0;
      list-style: none;
      display: flex;
      align-items: center;
     }
     .indicator li {
      width: 8px;
      height: 8px;
      margin: 4px;
      border-radius: 50%;
      background: #fff;
      opacity: 0.4;
      cursor: pointer;
     }
     .indicator li.active {
      width: 12px;
      height: 12px;
      opacity: 1;
     }
  </style>
</head>
<body>
  <div class="box1">
    <div class="box2">
      <img src="./image/1.jpg" alt="">
    </div>
    <div class="box3">
      <p>11111</p>
      <ul class="indicator">
        <li class="active"></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
      <div class="btn">
        <button class="prev">&lt;</button>
        <button class="next">&gt;</button>
      </div>
    </div>
  </div>
</body>
<script>
  // 轮播数据源定义
  const data = [
    { url: './image/1.jpg', title: '111', color: 'green' },
    { url: './image/2.jpg', title: '222', color: 'yellow' },
    { url: './image/3.jpg', title: '333', color: 'blue' },
    { url: './image/4.jpg', title: '444', color: 'pink' },
    { url: './image/5.jpg', title: '555', color: 'red' },
    { url: './image/6.jpg', title: '666', color: 'brown'},
    { url: './image/7.jpg', title: '777', color: 'grey' },
    { url: './image/8.jpg', title: '888', color: 'skyblue' }
  ]
  const img = document.querySelector('img')
  const p = document.querySelector('p')
  const box3 = document.querySelector('.box3')
  const next = document.querySelector('.next')
  const prev = document.querySelector('.prev')
  let i = 0
  // 下一张按钮点击事件 
  next.addEventListener('click', function() {
    // 索引+1,切换到下一项
    i++
    // 边界判断:超过最后一项(索引7),重置为第一项(索引0)
    if(i >=8) {
      i+8
    }
    // 调用更新函数,同步渲染轮播内容
    btn()
  })
  // 上一张按钮点击事件
  prev.addEventListener('click', function () {
    i--
    // 边界判断:小于第一项(索引0),重置为最后一项(索引7)
    if (i < 0) {
      i =7
    }
    btn()
  })
  function btn() {
    img.src = data[i].url// 更新轮播图片路径
    p.innerHTML = data[i].title// 更新标题文本
    box3.style.backgroundColor = data[i].color// 更新box3背景色
    // 指示器高亮切换:先移除原有的active,再给当前项加active
    document.querySelector('.indicator .active').classList.remove('active')
    document.querySelector(`.indicator li:nth-child(${i + 1})`).classList.add('active')
  }
   // 自动轮播:定时实现
  let time = setInterval(function () {
    next.click()
  },1000)
  const box1 = document.querySelector('.box1')
  // 鼠标进入
  box1.addEventListener('mouseenter', function () {
    clearInterval(time)// 清除定时器,暂停轮播
  })
  // 鼠标离开
  box1.addEventListener('mouseleave', function () {
    clearInterval(time)// 先清除旧定时器
    time = setInterval(function () {// 重新创建定时器,恢复轮播
      next.click()
    },1000)
  })
</script>
</html>
相关推荐
玖玖passion7 分钟前
React 常用 Hooks 函数及使用方法完全指南(useState / useEffect / useRef / useContext / useCallback / useMemo / useReducer)
前端·javascript
Awu122712 分钟前
⚡精通Claude第6课-Hooks钩子系统:从前端视角玩转AI自动化工作流
前端·aigc·claude
椰猫子13 分钟前
Spring Framework(Bean)
java·前端·spring
道清茗14 分钟前
【RH294知识点汇总】第 7 章 《 使用角色和 Ansible 内容集合简化 Playbook 》
java·前端·ansible
TechMasterPlus20 分钟前
Hermes 深度解析:React Native 高性能 JavaScript 引擎实践指南
javascript·react native·react.js
前端那点事22 分钟前
彻底弄懂async/await!解决回调地狱,Vue异步开发必备(超全实战)
前端·vue.js
VagueVibes28 分钟前
Openclaw 快速接入 DeepSeek V4 Pro 指南
javascript
A_nanda1 小时前
VS2022安装QT6.5.3后,如何更新项目配置
前端·javascript·vue.js
ZC跨境爬虫1 小时前
UI前端美化技能提升日志day8:(Watch专区字体优化+尺寸校准+视觉重构+结构分层)
前端·ui·重构·html
heyCHEEMS1 小时前
记录一下自动化构建中 SSE 与子进程管理的三个坑
javascript·node.js