JavaScript日期操作与DOM节点管理:构建动态网页的核心技术

在现代前端开发中,JavaScript的日期对象和DOM节点操作是构建交互式网页的两大核心技术。本文将通过多个实际案例,深入探讨这些技术的应用场景和实现方法。

日期对象:网页时间的掌控者

日期对象基础

JavaScript中的Date对象用于处理日期和时间。通过实例化Date对象,我们可以获取当前时间或指定时间:

javascript

复制下载

javascript 复制代码
// 获取当前时间
const date = new Date();
console.log(date);

// 获取指定时间
const date1 = new Date('2022-5-1 08:30:00');
console.log(date1);

Date对象提供了丰富的方法来获取时间的各个组成部分:

  • getFullYear(): 获取年份
  • getMonth(): 获取月份(0-11)
  • getDate(): 获取日期(1-31)
  • getDay(): 获取星期(0-6)
  • getHours(): 获取小时(0-23)
  • getMinutes(): 获取分钟(0-59)
  • getSeconds(): 获取秒数(0-59)

实时时钟的实现

利用Date对象和定时器,我们可以轻松实现一个实时更新的时钟:

html

复制下载运行

xml 复制代码
<!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>
    div {
      width: 300px;
      height: 40px;
      border: 1px solid pink;
      text-align: center;
      line-height: 40px;
    }
  </style>
</head>
<body>
  <div></div>
  <script>
    const div = document.querySelector('div')
    function getMyDate() {
      const date = new Date()
      let h = date.getHours()
      let m = date.getMinutes()
      let s = date.getSeconds()
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      return `今天是: ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}号 ${h}:${m}:${s}`
    }

    div.innerHTML = getMyDate()
    setInterval(function () {
      div.innerHTML = getMyDate()
    }, 1000)
  </script>
</body>
</html>

这段代码创建了一个实时更新的时钟,通过setInterval函数每秒更新一次显示内容。注意在处理小时、分钟和秒数时,我们使用了三元运算符确保单位数时间前面补零,使显示更加美观。

倒计时功能的实现

倒计时是网站中常见的功能,如促销活动、限时抢购等场景。以下是一个下班倒计时的实现:

html

复制下载运行

xml 复制代码
<!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>
    /* 样式代码 */
  </style>
</head>
<body>
  <div class="countdown">
    <p class="next">今天是2222年2月22日</p>
    <p class="title">下班倒计时</p>
    <p class="clock">
      <span id="hour">00</span>
      <i>:</i>
      <span id="minutes">25</span>
      <i>:</i>
      <span id="scond">20</span>
    </p>
    <p class="tips">18:30:00下课</p>
  </div>
  <script>
    // 目标时间
    const last = +new Date('2025-11-12 16:30:00');

    fn(); // 先调用一次,填补空白期
    setInterval(fn, 1000);

    const next = document.querySelector('.next');
    next.innerHTML = `今天是${new Date().getFullYear()}年${new Date().getMonth() + 1}月${new Date().getDate()}日`;

    // 倒计时函数
    function fn() {
      // 现在时间
      const now = +new Date();
      // 倒计时时间差
      const time = last - now;

      // 计算离目标时间有多少小时、分、秒
      let h = parseInt(time / 1000 / 60 / 60 % 24);
      let m = parseInt(time / 1000 / 60 % 60);
      let s = parseInt(time / 1000 % 60);
      h = h < 10 ? '0' + h : h;
      m = m < 10 ? '0' + m : m;
      s = s < 10 ? '0' + s : s;

      document.querySelector('#hour').innerHTML = h;
      document.querySelector('#minutes').innerHTML = m;
      document.querySelector('#scond').innerHTML = s;
    }
  </script>
</body>
</html>

这个倒计时功能的关键点在于:

  1. 使用+new Date()获取时间戳,便于计算时间差
  2. 通过数学运算将毫秒差转换为小时、分钟和秒
  3. 使用setInterval实现每秒更新
  4. 初始调用一次函数,避免等待第一秒时的空白期

DOM节点操作:动态网页的基石

DOM节点基础

文档对象模型(DOM)将HTML文档表示为树形结构,允许JavaScript动态访问和更新文档内容、结构和样式。

节点查找

DOM提供了多种查找节点的方法:

  • 父节点:parentNode

  • 子节点:

    • childNodes - 获取所有子节点,包括文本节点、注释节点
    • children - 仅获得所有元素节点,返回一个伪数组
  • 兄弟节点:

    • nextSibling / previousSibling - 获取上下兄弟节点,包括文本节点
    • nextElementSibling / previousElementSibling - 获取上下兄弟元素节点

点击关闭广告案例

html

复制下载运行

xml 复制代码
<!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>
    /* 样式代码 */
  </style>
</head>
<body>
  <div class="box">
    我是广告1
    <div class="box1">X</div>
  </div>
  <div class="box">
    我是广告2
    <div class="box1">X</div>
  </div>
  <div class="box">
    我是广告3
    <div class="box1">X</div>
  </div>
  <script>
    // 方法1: 通过父节点删除
    const closeBtn = document.querySelectorAll('.box1')
    for (let i = 0; i < closeBtn.length; i++) {
      closeBtn[i].addEventListener('click', function () {
        // 关闭我的爸爸 所以只关闭当前的父元素
        this.parentNode.style.display = 'none'
      })
    }

    // 方法2: 事件委托
    // const parents = document.querySelectorAll('.box');
    // for(let i = 0;i<parents.length;i++){
    //   parents[i].addEventListener('click',function(){
    //     this.style.display = 'none';
    //   })
    // }

    // 方法3: 普通方法
    // const closeBtn = document.querySelectorAll('.box1');
    // const parents = document.querySelectorAll('.box');
    // for(let i = 0;i<closeBtn.length;i++){
    //   closeBtn[i].addEventListener('click',function(){
    //     parents[i].style.display = 'none';
    //   })
    // }
  </script>
</body>
</html>

这个案例展示了三种实现关闭功能的方法:

  1. 父节点方法 :通过this.parentNode直接获取关闭按钮的父元素,简单直接
  2. 事件委托:将事件绑定到父元素,利用事件冒泡机制,适合动态添加的元素
  3. 普通方法:通过索引关联关闭按钮和对应的广告容器

节点创建与添加

动态创建课程列表

html

复制下载运行

xml 复制代码
<!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>学车在线首页</title>
    <link rel="stylesheet" href="./css/style.css">
</head>
<body>
    <div class="box w">
        <div class="box-hd">
            <h3>精品推荐</h3>
            <a href="#">查看全部</a>
        </div>
        <div class="box-bd">
            <ul class="clearfix">
                <!-- 动态生成的内容 -->
            </ul>
        </div>
    </div>
    <script>
        let data = [
            {
                src: 'images/course01.png',
                title: 'Think PHP 5.0 博客系统实战项目演练',
                num: 1125
            },
            // ... 更多数据
        ];
       
        //根据数据的个数,创建对应的小li
        const ul = document.querySelector('.box-bd ul');
        for(let i = 0 ;i<data.length;i++){
            const li = document.createElement('li');
            //追加小li
            ul.appendChild(li);
            //渲染内容
            li.innerHTML = `
                <a href="#">
                    <img src=${data[i].src} alt="">
                    <h4>${data[i].title}</h4>
                    <div class="info">
                        <span>高级</span> • <span>${data[i].num}</span>人在学习
                    </div>
                </a>
            `
        }
    </script>
</body>
</html>

这个案例展示了如何根据数据动态生成页面内容:

  1. 使用document.createElement创建新的li元素
  2. 使用appendChild将新元素添加到DOM树中
  3. 使用模板字符串动态生成HTML内容
  4. 通过循环遍历数据数组,为每个数据项创建对应的页面元素

克隆节点

克隆节点是创建相似元素的便捷方法:

html

复制下载运行

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>
    const ul = document.querySelector('ul');
    //克隆节点 元素.cloneNode(true)
    const li1 = ul.children[0].cloneNode(true);
    //追加
    li1.innerHTML = '4';
    ul.appendChild(li1);
  </script>
</body>
</html>

克隆节点有两种方式:

  • 元素.cloneNode(true): 深克隆,包括所有子节点
  • 元素.cloneNode(false): 浅克隆,仅克隆元素本身

综合案例:学生信息管理系统

学生信息管理系统综合运用了DOM操作和事件处理:

html

复制下载运行

xml 复制代码
<!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>学生信息管理</title>
  <link rel="stylesheet" href="css/index.css" />
</head>
<body>
  <h1>新增学员</h1>
  <form class="info" autocomplete="off">
    姓名:<input type="text" class="uname" name="uname" />
    年龄:<input type="text" class="age" name="age" />
    性别:
    <select name="gender" class="gender">
      <option value="男">男</option>
      <option value="女">女</option>
    </select>
    薪资:<input type="text" class="salary" name="salary" />
    就业城市:<select name="city" class="city">
      <option value="北京">北京</option>
      <option value="上海">上海</option>
      <option value="广州">广州</option>
      <option value="深圳">深圳</option>
      <option value="曹县">曹县</option>
    </select>
    <button class="add">录入</button>
  </form>

  <h1>就业榜</h1>
  <table>
    <thead>
      <tr>
        <th>学号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>性别</th>
        <th>薪资</th>
        <th>就业城市</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <!-- 动态内容 -->
    </tbody>
  </table>
  <script>
    //获取元素
    const uname = document.querySelector('.uname');
    const age = document.querySelector('.age');
    const gender = document.querySelector('.gender');
    const salary = document.querySelector('.salary');
    const city = document.querySelector('.city');
    const tbody = document.querySelector('tbody');
    //定义一个数组
    const arr = [];
    
    // 1.录入模块
    const info = document.querySelector('.info');
    info.addEventListener('submit', function (e) {
      //阻止默认行为
      e.preventDefault();
      //进行表单验证,获取所有带name属性的元素
      const names = document.querySelectorAll('[name]');
      for(let i = 0;i<names.length;i++){
        if(names[i].value === ''){
          alert('请填写完整信息');
          return;
        }
      }
      //创建对象
      const obj = {
        stuId: arr.length + 1,
        uname: uname.value,
        age: age.value,
        gender: gender.value,
        salary: salary.value,
        city: city.value,
      }
      arr.push(obj);

      //清空表单 reset重置
      this.reset();

      //清空tbody
      tbody.innerHTML = '';
      //调用渲染函数
      render();
    })

    //删除 事件委托给tbody
    tbody.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        arr.splice(e.target.dataset.id, 1);
        //重新渲染
        tbody.innerHTML = '';
        render();
      }
    })

    //渲染函数
    function render() {
      for (let i = 0; i < arr.length; i++) {
        const tr = document.createElement('tr');
        tr.innerHTML = `
          <td>${arr[i].stuId}</td>
          <td>${arr[i].uname}</td>
          <td>${arr[i].age}</td>
          <td>${arr[i].gender}</td>
          <td>${arr[i].salary}</td>
          <td>${arr[i].city}</td>
          <td><a href="javascript:" data-id=${i}>删除</a></td>
        `
        tbody.appendChild(tr);
      }
    }
  </script>
</body>
</html>

这个综合案例包含了以下关键技术点:

  1. 表单提交处理 :使用submit事件和preventDefault()阻止默认提交行为
  2. 表单验证:检查所有必填字段是否已填写
  3. 数据管理:使用数组存储学生信息
  4. 动态渲染:根据数组数据动态生成表格行
  5. 事件委托:将删除事件委托给tbody,处理动态添加的元素
  6. 数据属性 :使用data-id存储数据索引,便于删除操作

总结

JavaScript的日期对象和DOM操作是前端开发中不可或缺的核心技术。通过本文的多个案例,我们可以看到:

  1. 日期对象使我们能够处理各种时间相关需求,从简单的时钟显示到复杂的倒计时功能
  2. DOM节点操作允许我们动态创建、修改和删除页面内容,实现丰富的交互体验
  3. 事件处理让我们能够响应用户操作,创建响应式的用户界面
  4. 数据驱动的页面生成方式提高了代码的可维护性和可扩展性
相关推荐
xjt_090112 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农13 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king13 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳13 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵14 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星14 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_14 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝14 小时前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions14 小时前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发14 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法