在现代前端开发中,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>
这个倒计时功能的关键点在于:
- 使用
+new Date()获取时间戳,便于计算时间差 - 通过数学运算将毫秒差转换为小时、分钟和秒
- 使用
setInterval实现每秒更新 - 初始调用一次函数,避免等待第一秒时的空白期
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>
这个案例展示了三种实现关闭功能的方法:
- 父节点方法 :通过
this.parentNode直接获取关闭按钮的父元素,简单直接 - 事件委托:将事件绑定到父元素,利用事件冒泡机制,适合动态添加的元素
- 普通方法:通过索引关联关闭按钮和对应的广告容器
节点创建与添加
动态创建课程列表
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>
这个案例展示了如何根据数据动态生成页面内容:
- 使用
document.createElement创建新的li元素 - 使用
appendChild将新元素添加到DOM树中 - 使用模板字符串动态生成HTML内容
- 通过循环遍历数据数组,为每个数据项创建对应的页面元素
克隆节点
克隆节点是创建相似元素的便捷方法:
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>
这个综合案例包含了以下关键技术点:
- 表单提交处理 :使用
submit事件和preventDefault()阻止默认提交行为 - 表单验证:检查所有必填字段是否已填写
- 数据管理:使用数组存储学生信息
- 动态渲染:根据数组数据动态生成表格行
- 事件委托:将删除事件委托给tbody,处理动态添加的元素
- 数据属性 :使用
data-id存储数据索引,便于删除操作
总结
JavaScript的日期对象和DOM操作是前端开发中不可或缺的核心技术。通过本文的多个案例,我们可以看到:
- 日期对象使我们能够处理各种时间相关需求,从简单的时钟显示到复杂的倒计时功能
- DOM节点操作允许我们动态创建、修改和删除页面内容,实现丰富的交互体验
- 事件处理让我们能够响应用户操作,创建响应式的用户界面
- 数据驱动的页面生成方式提高了代码的可维护性和可扩展性