JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
$$demo <h1 id="result">总共得分:0</h1> <h1 id="hit" hidden></h1>
<div id="one"> <div id="three"> <div id="five"></div> </div> </div> <script> // model const model = { // 总分 total: 0, // 击中得分 score: 0, // 靶子的坐标 left: 0, top: 0, // 是否显示靶子 isShowTarget: true, // 定时器 id timerID: null, // 更新页面 update() { view.render() }, }
// controller
const controller = {
targetWidth: 0,
targetHeight: 0,
init() {
five.onclick = this.shot(5)
three.onclick = this.shot(3)
one.onclick = this.shot(1)
this.targetWidth = one.clientWidth
this.targetHeight = one.clientHeight
this.run()
},
shot(score) {
return () => {
// 击中得分
model.score = score
// 总分
model.total += score
// 隐藏靶子
model.isShowTarget = false
// 重新定时
// 使得能每次都是同一时间后显示靶子
clearInterval(model.timerID)
this.run()
// 通知数据发生了更新
model.update()
// 阻止冒泡
event.stopPropagation()
}
},
run() {
model.timerID = setInterval(() => {
model.left =
Math.random() *
(document.documentElement.clientWidth - this.targetWidth)
model.top =
Math.random() *
(document.documentElement.clientHeight - this.targetHeight)
// 显示靶子
model.isShowTarget = true
// 通知数据发生了更新
model.update()
}, 1000)
},
}
// view
const view = {
render() {
hit.textContent = `击中${model.score}分`
result.textContent = `总共得分:${model.total}`
one.style.left = `${model.left}px`
one.style.top = `${model.top}px`
// 是否显示靶子
one.hidden = !model.isShowTarget
// 显示靶子则不显示得分
hit.hidden = model.isShowTarget
},
}
window.addEventListener("load", function (event) {
// 在页面初始化后才能获取到靶子的宽高
controller.init()
})
</script> <style> html { min-height: 500px; }
#result,
#hit {
text-align: center;
/* 禁止选中文本 */
user-select: none;
}
#hit {
color: green;
}
#five {
width: 25px;
height: 25px;
border-radius: 50%;
}
#three,
#one {
padding: 25px;
border-radius: 50%;
}
#five {
background-color: #666;
}
#three {
background-color: #999;
}
#one {
background-color: #bbb;
}
#one {
position: fixed;
}
</style>
$$ $$answer
<h1 id="result">总共得分:0</h1>
<h1 id="hit" hidden></h1>
<div id="one">
<div id="three">
<div id="five"></div>
</div>
</div>
<script>
// model
const model = {
// 总分
total: 0,
// 击中得分
score: 0,
// 靶子的坐标
left: 0,
top: 0,
// 是否显示靶子
isShowTarget: true,
// 定时器 id
timerID: null,
// 更新页面
update() {
view.render()
},
}
// controller
const controller = {
targetWidth: 0,
targetHeight: 0,
init() {
five.onclick = this.shot(5)
three.onclick = this.shot(3)
one.onclick = this.shot(1)
this.targetWidth = one.clientWidth
this.targetHeight = one.clientHeight
this.run()
},
shot(score) {
return () => {
// 击中得分
model.score = score
// 总分
model.total += score
// 隐藏靶子
model.isShowTarget = false
// 重新定时
// 使得能每次都是同一时间后显示靶子
clearInterval(model.timerID)
this.run()
// 通知数据发生了更新
model.update()
// 阻止冒泡
event.stopPropagation()
}
},
run() {
model.timerID = setInterval(() => {
model.left =
Math.random() *
(document.documentElement.clientWidth - this.targetWidth)
model.top =
Math.random() *
(document.documentElement.clientHeight - this.targetHeight)
// 显示靶子
model.isShowTarget = true
// 通知数据发生了更新
model.update()
}, 1000)
},
}
// view
const view = {
render() {
hit.textContent = `击中${model.score}分`
result.textContent = `总共得分:${model.total}`
one.style.left = `${model.left}px`
one.style.top = `${model.top}px`
// 是否显示靶子
one.hidden = !model.isShowTarget
// 显示靶子则不显示得分
hit.hidden = model.isShowTarget
},
}
window.addEventListener("load", function (event) {
// 在页面初始化后才能获取到靶子的宽高
controller.init()
})
</script>
<style>
#result,
#hit {
text-align: center;
/* 禁止选中文本 */
user-select: none;
}
#hit {
color: green;
}
#five {
width: 25px;
height: 25px;
border-radius: 50%;
}
#three,
#one {
padding: 25px;
border-radius: 50%;
}
#five {
background-color: #666;
}
#three {
background-color: #999;
}
#one {
background-color: #bbb;
}
#one {
position: fixed;
}
</style>
$$