JavaScript的DOM,BOM简单介绍
# JavaScript能干什么
html:决定网页的结构(脑袋,身体,手脚)
css:决定网页的布局及样式(高矮,胖瘦,黑白)
JavaScript:定义网页的行为(走路,跑步,眨眼)
所以它究竟能干什么?
- 可以添加或删除HTML元素,改变其内容,属性和样式
- 对页面所有的事件作出反应,实现页面与用户之间实时、动态交互,如用户注册,登录验证
- 增强页面动态效果,如下拉菜单,图片轮播,信息滚动
- 可以操作数据库,写动画,写游戏,做一些网页特效
- ......
# DOM(文档对象模型)
当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。HTML DOM模型被构造成对象的树,页面的每一个组成部分都是一种节点,包含不同的数据:
通过DOM树,开发者可以随心所欲地控制网页内容和结构,并轻松地删除、添加、替换、修改节点。
# 节点介绍
- 节点的种类主要分为三种:元素节点,文本节点,属性节点
- 节点关系:兄弟关系,父子关系
# 获取元素节点
<div class="intro" id="box"></div>
1
- 通过元素的id:var x = document.getElementById("box");
- 通过标签名:var y = document.getElementsByTagName("div");
- 通过类名:var z = document.getElementsByClassName("intro");
# 改变元素内容,属性,样式
- 直接向HTML输出流写内容:document.write("想写入的内容");
- 修改HTML内容(要先获取元素):document.getElementById("box").innerHTML = "新文本";
- 修改HTML元素属性:document.getElementById("box").attribute = 新属性值;
- 修改元素样式:document.getElementById(id).style.property = 新样式;
注:
- 所谓的输出流,就是HTML渲染页面,实现输出的过程。HTML的加载过程是由上至下的,当遇到js脚本时,页面加载会被阻塞,浏览器会先去下载js脚本,当js脚本运行完之后,再继续渲染页面。
- 绝对不要在文档(DOM)加载完成之后使用 document.write(),这会覆盖该文档。(文档加载后不是指在文档后使用script标签进行文档内容写入,而是通过按钮响应等方式在全部页面加载完毕之后进行文本写入)
<span>行内元素</span>
<p id="second">我是唯一的</p>
<div class="box">那我加一</div>
<div class="box">那我加一</div>
<div class="box">那我加一</div>
<a onclick="myFunction()">hello</a><br>
<img id="image" src="gz.jpg" alt="" width="200">
<script>
//获取元素
var x = document.getElementById('second');
console.log(x);
var y = document.getElementsByTagName("span");
console.log(y);
console.log(y.length);
//y是HTMLCollection对象,类似包含HTML元素的一个数组,但它并不是数组,你可以通过索引来获取元素,但无法使用数组的方法,如pop(),push()等
var z = document.getElementsByClassName("box");
console.log(z);
// z[1].innerHTML = "新文本";
//修改输出流
document.write("路过");
function myFunction(){
document.write("我会发生覆盖");
}
//修改属性
// document.getElementById('image').src = 'th.jpg';
// 修改样式
// x.style.color = "red";
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# DOM事件
- 鼠标点击,移动事件
- 网页加载完成触发事件
- 当输入字段被改变及表单提交产生的事件等
<p>冬天了,应该多喝热水</p>
<button id="myBtn">点这里</button><br>
<input type="text" id="fname" onchange="upperCase()">
<script>
window.onload = function load(){
alert("加载完成");
}//onload事件在文档加载完成后能立即触发,所以即使是放头部也能执行
console.log(document.getElementsByTagName('p')[0].innerHTML);//如果放头部就会报错
document.getElementById('myBtn').onclick = function(){
document.getElementsByTagName('p')[0].style.backgroundColor = "yellow";
}
function upperCase(){
var fname = document.getElementById('fname');
fname.value = fname.value.toUpperCase();
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# addEventListener()方法
- addEventListener()方法用于向指定元素添加事件句柄
- 语法:element.addEventListener(event, function, useCapture);
- 第一个参数:事件类型,如'click'或'blur'(注意,不能使用"on"前缀)
- 第二个参数:事件触发后调用的函数
- 第三个参数:用于描述事件是冒泡还是捕获(该参数可省略,默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递)
注:
- 该方法可以给一个元素添加多个事件,也可添加多个相同类型的事件,如给一个按钮添加两个"click"事件
- 该方法添加的事件句柄不会覆盖已存在的事件句柄
- 可通过removeEventListener()方法来移除事件的监听
事件传递定义了元素事件触发的顺序。 如果你将 < p > 元素插入到 < div > 元素中,用户点击 < p > 元素, 哪个元素的 "click" 事件先被触发呢
- 冒泡:内部元素的事件会先被触发,然后再触发外部元素,即: < p > 元素的点击事件先触发,然后会触发 < div > 元素的点击事件。
- 捕获:外部元素的事件会先被触发,然后才会触发内部元素的事件,即: < div > 元素的点击事件先触发 ,然后再触发 < p > 元素的点击事件。
<style>
#parent{
background-color: yellow;
width: 500px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
#son{
cursor: pointer;
}
</style>
<div id="parent">
<p id="son">冬天了,应该多喝热水</p>
</div>
<script>
var x = document.getElementById('parent');
var y = document.getElementById('son');
var p1 = 2;
x.addEventListener('click',function(){
console.log('我是一个div');
},true);
y.addEventListener('click',function(){
console.log('我是一个p标签');
},true);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 创建,移除,替换元素(节点)
<div id="box">
<p id="p1">这是一个段落</p>
<p id="p2">这是另一个段落</p>
</div>
<script>
//创建新元素
var para = document.createElement("p");
var node = document.createTextNode("这是一个新文本");
para.appendChild(node);
var divBox = document.getElementById("box");
//在最后加入新元素
//divBox.appendChild(para);
//在指定元素前加入新元素
var child = document.getElementById('p1');
// divBox.insertBefore(para,child);
var secchild = document.getElementById('p2');
// divBox.insertBefore(para,secchild);
// 移除已存在的元素
// divBox.removeChild(child);
//child.parentNode.removeChild(child);
//替换元素
//divBox.replaceChild(para,child);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# BOM介绍
浏览器对象模型(Browser Object Model (BOM))使 JavaScript 有能力与浏览器"对话"。
- 所有浏览器都支持 window 对象。它表示浏览器窗口。
- 全局变量是 window 对象的属性。全局函数是 window 对象的方法。同时HTML DOM 的 document 也是 window 对象的属性之一
# window.location 对象
- 用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。(可不加window前缀)
- location.hostname 返回 web 主机的域名
- location.pathname 返回当前页面的路径和文件名
- location.port 返回 web 主机的端口 (80 或 443)
- location.protocol 返回所使用的 web 协议(http: 或 https:)
- location.replace(url) : 通过加载 URL 指定的文档来替换当前文档 ,这个方法是替换当前窗口页面,前后两个页面共用一个窗口,所以是没有后退返回上一页的
# window.history对象
- 在编写时可不使用 window 这个前缀
- history.back() - 与在浏览器点击后退按钮相同
- history.forward() - 与在浏览器中点击向前按钮相同
# JavaScript弹窗
- JavaScript中三种消息框:警告框(alert),确认框(confirm),提示框(prompt)
# JavaScript计时事件
- setInterval() - 间隔指定的毫秒数不停地执行指定的代码。(循环执行)
- setTimeout() - 在指定的毫秒数后执行指定代码。(延迟执行)
- clearInterval() - 用于停止 setInterval() 方法执行的函数代码。
- clearTimeout() - 用于停止setTimeout()方法执行的函数代码。
<p>页面上显示时钟:</p>
<p id="demo"></p>
<button onclick="stop()">停止</button>
<script>
var cir = setInterval(getTime,1000);
function getTime(){
var t = new Date();
var time = t.toLocaleTimeString();
document.getElementById("demo").innerHTML = time;
}
function stop(){
clearInterval(cir);
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 最后敲个小栗子
todolist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.bigBox input{
outline: none;
}
.bigBox button{
cursor: pointer;
outline: none;
}
.bigBox{
width: 450px;
min-height: 300px;
height: min-content;
background-color: #F2F3F5;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
text-align: center;
padding: .5rem;
box-sizing: border-box;
}
h2{
letter-spacing: 0.1em;
}
.bigBox>input{
width: 60%;
border: 1px solid gray;
padding: .3rem .5rem;
}
#add{
border: none;
color: white;
background-color:#1B8FFB;
padding: .3rem;
border-radius: 5px;
}
#delayadd{
padding:.3rem;
border: 1px solid gray;
border-radius: 5px;
}
#allBox > div{
width: calc(100% - 2rem);
background-color: white;
padding: .5rem;
margin: .5rem;
}
#allBox > div::after{
content: "";
display: block;
clear: both;
}
#allBox label{
position: relative;
float: left;
width: 20px;
height: 20px;
border: 1px solid gray;
}
#allBox label input{
border: none;
-webkit-appearance:none ;
}
#allBox label span{
width: 7px;
height: 14px;
border-bottom: 1px solid black;
border-right: 1px solid black;
transform: rotate(45deg);
position: absolute;
top: 2px;
left: 5px;
opacity: 0;
}
#allBox input:checked ~ span{
opacity: 1;
}
#allBox div>span{
font-size: 1rem;
float: left;
margin-left:.5rem ;
}
#allBox button{
float: right;
color: red;
border-radius: 50%;
border: 1px solid gray;
outline: none;
}
</style>
</head>
<body>
<div class="bigBox">
<h2>Todolist</h2>
<input type="text" id="inputElt" placeholder="请输入待办事项">
<button id="add">+ 新增</button>
<button id="delayadd">+ 延迟新增</button>
<div id="allBox">
<div class="todo">
<label for="1">
<input type="checkbox" id="1" onclick="checkItem(1)">
<span></span>
</label>
<span>吃饭</span>
<button class="btn" onclick="delItem(1)">✖</button>
</div>
</div>
</div>
<script src="demo.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
demo.js
var total = 1;//总条数
var text = [{text:"吃饭",id:1,del:false}];
var box = document.getElementById('allBox');
var todoItem = document.getElementsByClassName("todo");
var inputElt = document.getElementById("inputElt");
var addBtn = document.getElementById("add");
var delayBtn = document.getElementById("delayadd");
var i;
//新增
addBtn.addEventListener('click',()=>{
var text = inputElt.value;
console.log(text);
if(text != ""){
// if(text.replace(/^\s+|\s+$/g,"") != ""){
//匹配头尾的任何空白字符,包括空格、制表符、换页符等等
this.addContent(text);
inputElt.value = "";
}
})
//延迟新增
delayBtn.addEventListener('click',()=>{
var text = inputElt.value;
if(text.replace(/^\s+|\s+$/g,"") != ""){
setTimeout(()=>{
this.addContent(text);
},500);
inputElt.value = "";
}
})
function addContent(text){
this.total++;
console.log(this.total);
this.text.splice(0,0,{text:text,id:total,del:false});
//splice()方法用于添加或删除数组元素
this.add(text,total);
}
//添加待办事项
function add(x,id){
var div = document.createElement('div');
var label = document.createElement('label');
var input = document.createElement('input');
var span = document.createElement('span');
var span1 = document.createElement('span');
var button = document.createElement('button');
input.type = "checkbox";
input.setAttribute("id",id);
input.addEventListener('click',()=>{
checkItem(id);
})
label.appendChild(input);
label.appendChild(span);
// span1.textContent = x;
span1.innerHTML = x;
button.className = "btn";
button.innerHTML = "✖";
//删除
button.addEventListener('click',()=>{
delItem(id);
})
div.appendChild(label);
div.appendChild(span1);
div.appendChild(button);
div.className = "todo";
box.prepend(div);
}
//删除
function delItem(id){
var length = this.text.length;
console.log(this.text);
for(i = length-1;i>=0;i--){
if(this.text[i].id == id)
this.text[i].del = true;
}
for(i = length-1;i>=0;i--){
if(this.text[i].del){
box.removeChild(todoItem[i]);
this.text.splice(i,1);
}
}
}
//勾选删除项
function checkItem(id){
for(i = 0;i<this.text.length;i++){
if(this.text[i].id == id)
this.text[i].del = !this.text[i].del;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91