目录
1.操作结点
1.1新增节点
1.1.1. 创建元素节点
1.1.2. 插入节点到 dom 树中
1.2删除节点
2.代码案例: 猜数字
2.1预期效果
2.2代码实现
3.代码案例: 表白墙
3.1预期效果
3.2创建页面布局
3.3调整样式
3.4实现提交
3.5实现点击按钮的动画效果
4.代码案例: 待办事项
4.1预期效果
4.2创建页面布局
4.3实现页面样式
4.4实现页面行为
4.4.1实现新增
4.4.2点击复选框后将元素放到 "已完成"
4.4.3点击删除按钮删除该任务
1.操作结点
1.1新增节点
分成两个步骤
1. 创建元素节点
2. 把元素节点插入到 dom 树中.
第一步相当于生了个娃, 第二步相当于给娃上户口.
1.1.1. 创建元素节点
使用 createElement 方法来创建一个元素. options 参数暂不关注.
var element = document.createElement(tagName[, options]);
代码示例:
<div class="container">
</div>
<script>
var div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
console.log(div);
</script>
此时发现, 虽然创建出新的 div 了, 但是 div 并没有显示在页面上. 这是因为新创建的节点并没有加入到DOM 树中.
上面介绍的只是创建元素节点, 还可以使用:
createTextNode 创建文本节点
createComment 创建注释节点
createAttribute 创建属性节点
我们以 createElement 为主即可.
1.1.2. 插入节点到 dom 树中
1) 使用 appendChild 将节点插入到指定节点的最后一个孩子之后
element.appendChild(aChild)
<div class="container">
</div>
<script>
var div = document.createElement('div');
div.id = 'mydiv';
div.className = 'box';
div.innerHTML = 'hehe';
var container = document.querySelector('.container');
container.appendChild(div);
</script>
2) 使用 insertBefore 将节点插入到指定节点之前.
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
insertedNode 被插入节点(newNode)
parentNode 新插入节点的父节点
newNode 用于插入的节点
referenceNode newNode 将要插在这个节点之前
如果 referenceNode 为 null 则 newNode 将被插入到子节点的末尾.
注意: referenceNode 引用节点不是可选参数
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
</script>
注意1: 如果针对一个节点插入两次, 则只有最后一次生效(相当于把元素移动了)
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
// 此处的 children 里有 4 个元素
container.insertBefore(newDiv, container.children[0]);
// 此处的 children 里有 5 个元素(上面新插了一个), 0 号元素是 新节点,
// 1 号元素是 11, 2号节点是 22, 所以是插入到 22 之前.
container.insertBefore(newDiv, container.children[2]);
</script>
注意2: 一旦一个节点插入完毕, 再针对刚刚的节点对象进行修改, 能够同步影响到 DOM 树中的内容.
<div class="container">
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
</div>
<script>
var newDiv = document.createElement('div');
newDiv.innerHTML = '我是新的节点';
var container = document.querySelector('.container');
console.log(container.children);
container.insertBefore(newDiv, container.children[0]);
// 插入完毕后再次修改 newDiv 的内容
newDiv.innerHTML = '我是新节点2';
</script>
1.2删除节点
使用 removeChild 删除子节点
oldChild = element.removeChild(child);
child 为待删除节点
element 为 child 的父节点
返回值为该被删除节点
被删除节点只是从 dom 树被删除了, 但是仍然在内存中, 可以随时加入到 dom 树的其他位置.
如果上例中的 child节点 不是 element 节点的子节点,则该方法会抛出异常.
2.代码案例: 猜数字
2.1预期效果
2.2代码实现
<button type="button" id="reset">重新开始一局游戏</button>
<br>
请输入要猜的数字:<input type="text" id="number">
<button type="button" id="button">猜</button>
<br>
已经猜的次数:<span id="count">0</span>
<br>
结果:<span id="result"></span>
<script>
var inputE = document.querySelector("#number");
var countE = document.querySelector("#count");
var resultE = document.querySelector("#result");
var btn = document.querySelector("#button");
var resetBtn = document.querySelector("#reset");
// 随机生成一个 1-100 的数字
var guessNumber = Math.floor(Math.random() * 100) + 1// 0 - 1 之间的数
var count = 0;
// on: 当
// click: 点击
// 事件驱动(Event-Drive):只要真正发生了点击事件时,才执行该函数
btn.onclick = function() {
count++;
countE.innerText = count;
var userGuess = parseInt(inputE.value);
if (userGuess == guessNumber) {
resultE.innerText = "猜对了";
resultE.style = "color: gray;";
} else if (userGuess < guessNumber) {
resultE.innerText = "猜小了";
resultE.style = "color: blue;";
} else {
resultE.innerText = "猜大了";
resultE.style = "color: red;";
}
};
resetBtn.onclick = function() {
guessNumber = Math.floor(Math.random() * 100) + 1
count = 0;
countE.innerText = count;
resultE.innerText = "";
inputE.value = "";
}
</script>
3.代码案例: 表白墙
3.1预期效果
3.2创建页面布局
创建 表白墙.html
<h1>表白墙</h1>
<p>输入后点击提交, 会将信息显示在表格中</p>
<span>谁: </span>
<input type="text">
<span>对谁: </span>
<input type="text">
<span>说什么: </span>
<input type="text">
<input type="button" value="提交">
此时效果形如
3.3调整样式
<div class="container">
<h1>表白墙</h1>
<p>输入后点击提交, 会将信息显示在表格中</p>
<div class="row">
<span>谁: </span>
<input class="edit" type="text">
</div>
<div class="row">
<span>对谁: </span>
比特就业课
<input class="edit" type="text">
</div>
<div class="row">
<span>说什么: </span>
<input class="edit" type="text">
</div>
<div class="row">
<input type="button" value="提交" class="submit">
</div>
</div>
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 400px;
margin: 0 auto;
}
h1 {
text-align: center;
padding: 20px 0;
}
p {
color: #666;
text-align: center;
font-size: 14px;
padding: 10px 0;
}
.row {
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
span {
width: 100px;
line-height: 40px;
}
.edit {
width: 200px;
height: 30px;
}
.submit {
width: 304px;
height: 40px;
color: white;
background-color: orange;
border: none;
}
</style>
此时效果形如
3.4实现提交
<script>
//给点击按钮注册点击事件:
var submit = document.querySelector('.submit');
submit.onclick = function() {
//获取到编辑框中的内容:
var edit = document.querySelectorAll('.edit');
var from = edit[0].value;
var to = edit[1].value;
var message = edit[2].value;
console.log(from + "," + to + "," + message);
if(from == "" || to == "" || message == "")
return;
//构造html元素:
var row = document.createElement('div');
row.className = 'row';
row.innerHTML = from + '对' + to + '说:' + message;
//把构造好的元素添加进去:
var container = document.querySelector('.container');
container.appendChild(row);
//清理之前输入框中的内容:
for(var i = 0; i < 3; ++i) {
edit[i].value = '';
}
}
</script>
3.5实现点击按钮的动画效果
需要使用伪类选择器.
伪类选择器种类有很多. 此处的 :active 表示选中被按下的按钮
.submit:active {
background-color: #666;
}
4.代码案例: 待办事项
4.1预期效果
4.2创建页面布局
创建 待办事项.html
<div class="nav">
<input type="text">
<button>新建任务</button>
</div>
<div class="container">
<div class="todo">
<h3>未完成</h3>
<div class="row">
<input type="checkbox">
<span>吃饭</span>
<button>删除</button>
</div>
</div>
<div class="done">
<h3>已完成</h3>
</div>
</div>
4.3实现页面样式
<style>
* {
margin: 0;
padding: 0;
}
.container {
width: 800px;
margin: 0 auto;
display: flex;
}
.todo,
.done {
width: 50%;
height: 100%;
}
.container h3 {
height: 50px;
text-align: center;
line-height: 50px;
background-color: #333;
color: #fff;
}
.nav {
width: 800px;
height: 100px;
margin: 0 auto;
display: flex;
align-items: center;
}
.nav input {
width: 600px;
height: 50px;
}
.nav button {
width: 190px;
height: 50px;
border: none;
background-color: orange;
color: #fff;
margin-left: 5px;
}
.row {
height: 50px;
display: flex;
align-items: center;
}
.row input {
margin: 0 10px;
}
.row span {
width: 300px;
}
.row button {
width: 50px;
height: 40px;
}
</style>
4.4实现页面行为
4.4.1实现新增
<script>
//实现新增任务:
var addTaskButton = document.querySelector('.nav button');
addTaskButton.onclick = function() {
//1.获取到任务内容的输入框:
var input = document.querySelector('.nav input');
//2.获取到输入框的内容:
var taskContent = input.value;
//3.根据内容新增一个元素结点:
var row = document.createElement('div');
row.className = 'row';
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
var span = document.createElement('span');
span.innerHTML = taskContent;
var button = document.createElement('button');
button.innerHTML = '删除';
row.appendChild(checkbox);
row.appendChild(span);
row.appendChild(button);
//4.把新结点插入到todo中
var todo = document.querySelector('.todo');
todo.appendChild(row);
}
</script>
4.4.2点击复选框后将元素放到 "已完成"
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 5. 给 checkbox 注册点击事件
checkbox.onclick = function () {
//
var row = this.parentNode;
// 注意! 是先触发 checked 为 true, 然后再调用 onclick 函数
if (this.checked) {
var target = document.querySelector('.done');
} else {
var target = document.querySelector('.todo');
}
target.appendChild(row);
}
}
注意:
在事件回调函数中使用 this 能够获取到当前处理事件的元素.
通过 this.parentNode 属性能够获取到当前元素的父元素.
点击 checkbox 时, 会先修改 value , 再触发点击事件.
4.4.3点击删除按钮删除该任务
// 修改 addTaskButton.onclick
addTaskButton.onclick = function () {
// 上方的部分不变...
// 6. 给删除按钮注册点击事件
button.onclick = function () {
var row = this.parentNode;
var grandParent = row.parentNode;
grandParent.removeChild(row);
}
}