本章目标
DOM
DOM 简介
DOM 概念
DOM 是 JavaScript 操作网页的接口API,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。
节点
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。节点也是对象。
常用的 DOM 操作
获取元素
// 根据id获取一个DOM对象let div = document.querySelector('#box')// 根据类选择器获取一些DOM元素let list = document.querySelectorAll('.item')// 遍历list中的每一个 DOM 元素list.forEach(function (item) {console.log(item)})
设置属性
// 根据id获取一个DOM对象let div = document.querySelector('#box')// 设置div之间的内容div.textContent = '疫情封城去哪买菜?'// 设置图片let img = document.querySelector('.image')img.src = 'images/01.jpg'let btn = document.querySelector('.btn')// 禁用按钮btn.disabled = true
事件机制
let btn = document.querySelector('.btn')// 给按钮注册点击事件btn.onclick = function () {console.log('别点我,疼')}
定时器
window 对象提供了两种类型的定时器,分别是可以实现在指定时间后执行特点操作,也可以让代码每隔一段时间执行一次,实现间隔执行操作。
延迟执行定时器
如果我们要实现购买成功之后,延迟 5s 之后跳转到其它页面,这个时候可以使用延迟执行的定时。
setTimeout() 方法可以创建一个定时器,让代码延迟一段时间执行。
下面先来介绍 setTimeout() 的语法:
const timerId = window.setTimeout(func[, delay]);
- 参数:
- 第一个参数 func,时间到达之后执行的函数
- 第二个参数 delay,延迟的毫秒数(一秒等于1000毫秒),如果省略该参数默认为0,表示马上、尽可能快的执行。
浏览器中调用定时器的最小时间间隔是4毫秒
- 返回值:
- 返回值 timerId 是一个正整数,表示定时器的编号。这个值可以传递给 clearTimeout() 来取消该定时器
定时器在时间为到达的时候可以通过 clearTimeout() 取消定时器的执行,下面来演示定时器的用法:
const timerId = setTimeout(print, 5000);function print() {console.log('时间到达5秒')}btn.onclick = function () {// 取消定时器clearTimeout(timerId);};
从上面代码可以看出 setTimeout() 在等待5秒后会执行一次操作然后停止定时器。
模拟商品购买成功后,5s 跳转到其它页面:
setTimeout(function () {location.href = 'index.html';}, 5000);
间隔执行定时器
setInterval() 是间隔执行定时器,会间隔指定时间重复执行操作,使用方式和 setTImeout() 相似。网页上显示的倒计时效果、包括一些 JavaScript 实现的动画效果都离不开 setInterval()。
下面来样式 setInterval() 的用法:
const timerId = window.setInterval(func, delay);
- 参数:
- 第一个参数 func,时间到达指定毫秒数后重复执行的函数
- 每次延迟的毫秒数 (一秒等于1000毫秒),函数的每次调用会在该延迟之后发生。和setTimeout一样,实际的延迟时间可能会稍长一点。这个时间计算单位是毫秒(千分之一秒),这个定时器会使指定方法或者代码段执行的时候进行时间延迟。如果这个参数值小于10,则默认使用值为10。请注意,真正延迟时间或许更长
- 返回值:
- 返回值 timerId 是一个非零数值,用来标识通过 setInterval()创建的计时器,这个值可以用来作为 clearInterval() 的参数来清除对应的计时器
和 setTimeout 类似,可以通过 clearInterval() 终止定时器的执行,下面来演示 setInterval() 的使用:
const timerId = setInterval(print, 2000);function print() {console.log('两秒钟打印一次');}btn.onclick = function () {clearInterval(timerId);}
打地鼠游戏
页面搭建
网页背景
* {margin: 0;padding: 0;}html,body {height: 100%;}body {background: #ebf9ff url(./images/bg.jpg) no-repeat center center;/* overflow: hidden; */}
顶部说明
<div class="top"><h4>游戏说明:</h4><p>点击“开始游戏”按钮,在下图中随机产生老鼠,老鼠消失前单击老鼠进行击打,打中一次即可获得100的积分。快快行动吧,考验您的反应和眼力!</p></div>
.top {width: 50%;color: #666;margin: 0 auto;padding-top: 20px;}
得分情况
<div class="main"><div class="sidebar"><p>游戏时间: <input type="text" id="game" value="1"> 分钟</p><p>间隔时间: <input type="text" id="interval" value="1"> 秒数</p><p>停留时间: <input type="text" id="stay" value="1"> 秒数</p><p>倒计时间: <span id="count">60</span> 秒</p><div class="score">得分情况:<div><p>打中:<span id="dz">0</span>只 漏掉:<span id="ld">0</span>只</p><p>总分:<span id="zf">0</span>分 得分:<span id="df">0</span>分</p></div></div><p class="btn-wrap"><input type="button" id="btnStart" value="开始游戏"><input type="button" id="btnStop" value="停止游戏"></p></div></div>
.main {width: 750px;margin: 80px auto;color: #333;}.main .sidebar {float: left;}.main .sidebar .score {color: red;}.main .sidebar .btn-wrap {text-align: center;}
游戏区域
<div class="main">……<div class="game"><div class="box"><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div><div class="item"><img src="" alt="" class="image"></div></div></div></div>
.main .game {float: left;width: 360px;height: 360px;margin-left: 40px;}.main .game .item {box-sizing: border-box;float: left;width: 70px;height: 70px;padding-top: 3px;border: 1px solid #eee;background-color: #c6db56;text-align: center;}.main .game .item .image {cursor: pointer;}
打地鼠游戏实现
定义变量
// 时间let gameTime, intervalTime, stayTime, count// 分数let sumNumber, numberlet timerId, currentIndex// 按钮let btnStart, btnStopbtnStart = document.querySelector('#btnStart')btnStop = document.querySelector('#btnStop')btnStop.disabled = true
初始化
function init () {// 文本框const game = document.querySelector('#game')const interval = document.querySelector('#interval')const stay = document.querySelector('#stay')// 倒计时,游戏时间倒计const countSpan = document.querySelector('#count')game.disabled = trueinterval.disabled = truestay.disabled = true// 秒gameTime = game.value * 60// 毫秒intervalTime = interval.value * 1000stayTime = stay.value * 1000count = gameTime// 倒计时时间countSpan.textContent = gameTimebtnStart.disabled = truebtnStop.disabled = false}
点击开始按钮
btnStart.onclick = function () {init()startGame()}
function startGame() {random()// 开启定时器timerId = setInterval(() => {// 时间到达后停止count--random()const countSpan = document.querySelector('#count')countSpan.textContent = countif (count == 1) {// stopGame()alert('游戏结束')}}, intervalTime);}
// 随机位置function random () {currentIndex = parseInt(Math.random() * 25)const images = document.querySelectorAll('.game .image')const img = images[currentIndex]img.src = 'images/01.jpg'// 1秒后清除clearImage(img)}
function clearImage (img) {setTimeout(() => {img.src = ''// -100 防止两次随机数字相同,这样的话第二次的地鼠看不到}, intervalTime - 100);}
计算得分
// 计算分数function setScore () {const dz = document.querySelector('#dz')const ld = document.querySelector('#ld')const zf = document.querySelector('#zf')const df = document.querySelector('#df')dz.textContent = numberld.textContent = sumNumber - numberzf.textContent = sumNumber * 100df.textContent = sumNumber * 100}
// startGame 中调用function startGame() {sumNumber = 0number = 0setScore()……// 开启定时器timerId = setInterval(() => {……// 计算分数sumNumber++setScore()……}, intervalTime);}
停止游戏
btnStop.onclick = function () {stopGame()}
function stopGame () {if (!timerId) returnbtnStart.disabled = falsebtnStop.disabled = trueconst game = document.querySelector('#game')const interval = document.querySelector('#interval')const stay = document.querySelector('#stay')game.disabled = falseinterval.disabled = falsestay.disabled = falsecount.textContent = gameTimeclearInterval(timerId)}
打地鼠
// 给所有img注册事件// 给所有的imgs注册点击事件const images = document.querySelectorAll('.box .image')images.forEach(item => {item.onclick = function () {const src = this.srcif (src !== '') {this.src = './images/02.jpg'number++setTimeout(() => {this.src = ''}, 500)}}})
