HTML

html模版格式

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html> 
<html>
<head>
<meta charset="UTF-8">
<title>篮球</title>
</head>
<body>
<font color="red" size="6">喜欢</font>打篮球
</body>
</html>

由html head body三个部分组成
head中需要注意声明utf-8<meta charset="UTF-8">,避免兼容性导致中文乱码问题

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
<!DOCTYPE html> 
<html>
<head>
<!-- 指定html的字符编码 -->
<meta charset="UTF-8">
<title>排版标签</title>
</head>
<body>
静夜思
<br/>
李白
<hr width="50%" size="5px" color="orange" align="left"/>
<!--水平线设置宽度为上层标签的50%,粗细设置为5个相素,颜色黄色,对齐左对齐-->
<br/>
<!-- <br/> 换行,单独一个标签即可,不需要一组 -->
<p align="center">
<!-- <p>这是一个段落。</p>
一组
<p>
内容
</p>
标签说明一个段落 -->
床前明月光
<br/>
疑是地上霜
<br/>
举头望明月
<br/>
低头思故乡
<br/>
</p>
</body>
</html>
排版标签 静夜思
李白

床前明月光
疑是地上霜
举头望明月
低头思故乡

这里使用了很多标签,相关用法如下
1
2
3
4
5
6
7
8
9
10
11
12
1.换行标签:<br/> 一般写单个标签即可 
2.段落标签:<p>文本文字</p> 段与段之间有空行,浏览器会自动在段落的前后添加空行
属性:align:对齐方式(有三个属性值:left center right)
3.水平线标签:<hr/> 一般写单个标签即可
属性:
width:长度
size:粗度
color:颜色
align:对齐方式
尺寸的写法:
(1)像素:500px
(2)百分比:50%,占据上级标签的百分比,会随着上级标签的大小进行变化

标签

标签是一组尖括号以及中间的内容组成的

1
<p>this is a html paragram</p>

有时标签是有属性的,属性可能是ui相关的长度颜色对齐方式之类的,也有可能是一个跳转链接
``link
href="http://openwrt.pan0624.top 就是标签a的属性
link

1
<input type="text" name="username" />

这是一种特殊的标签,叫单标签,这里实现了一个文本输入框,并且把输入框中内容传给了username表单,同样的type=”text” name=”username”是 <input>标签的两个属性

h1~h6标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>

<h1>这是一级标题</h1>
<h2>这是二级标题</h2>
<h3>这是三级标题</h3>
<h4>这是四级标题</h4>
<h5>这是五级标题</h5>
<h6>这是六级标题</h6>

</body>
</html>
Title
<h1>这是一级标题</h1>
<h2>这是二级标题</h2>
<h3>这是三级标题</h3>
<h4>这是四级标题</h4>
<h5>这是五级标题</h5>
<h6>这是六级标题</h6>
h==n==标签实现的是多级标题,与markdown中#号用法相似,注意==成组闭包== `

标题

` ### `

i am not title

` `

paragram

`p标签用于段落,会自适应在界面中换行 ### 超链接
1
<a href="page02-anchor-target.html">点我跳转到下一个页面</a>

相对路径跳转

image|500

1
<a href="../../e/f/z.html">To z.html</a>

这里a的路径是d/c/b

绝对路径

通过IDEA内置服务器或者其他web服务器实现的打开html文件的一种方式

image|500

1
2
3
4
5
6
7
8
<html>
<head>
<title>白色背景图片</title>
</head>
<body style="background-color: white;">
<img src="https://heavy_code_industry.gitee.io/code_heavy_industry/assets/img/img018.1f565e83.png" alt="绝对路径" style="background-color: white;">
</body>
</html>

这里同时展示了一种插入图片并且设置白色背景的方式
使用了img标签和style属性

前面的地址以及端口指向了服务器开放web服务的根路径
后面就是文件在项目中的相对路径

列表

无序列表

1
2
3
4
5
<ul> <!-- 开始无序列表 -->
<li>Apple</li> <!-- 第一个列表项 -->
<li>Banana</li> <!-- 第二个列表项 -->
<li>Cock</li> <!-- 第三个列表项 -->
</ul> <!-- 结束无序列表 -->

有序列表

1
2
3
4
5
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>

有序列表默认为数字编号,也可以选择其他的属性来使用例如大写字母编号之类的
type="A"
type="a"
start="10"

1
2
3
4
5
<div style="border: 1px solid black;width: 100px;height: 100px;">This is a div block</div>
<div style="border: 1px solid black;width: 100px;height: 100px;">This is a div block</div>

<span style="border: 1px solid black;width: 100px;height: 100px;">This is a span block</span>
<span style="border: 1px solid black;width: 100px;height: 100px;">This is a span block</span>
This is a div block
This is a div block

This is a span blockThis is a span block

<div></div>标签前后有换行
<span></span>标签前后无换行

符号转译 HTML实体

通过对应的转译表来使用符号

image|500

表单

form标签 定义表单

1
2
3
<form action="/aaa/pro01-HTML/page05-form-target.html" method="post">

</form>

action属性和method属性

action:服务器能正常接收表单数据的地址
method:提交表单的请求方法,get或者post

name value

name实际上是输入框中文本标识的名字传输到服务器

<input type="text" name="username">
这里就是在提交表单时,将输入框中的文本标识为username传输到服务器
vlaue是表单提交表单元素的默认值
<input type="text" name="username" value="rick">
这里提交表单时username的默认值就是rick,同时输入框内会默认rick

1
2
3
4
<input type="text" name="username"/>
文本输入
<input type="password" name="password"/>
密码输入
1
2
3
4
5
6
你最喜欢的季节是:
<input type="radio" name="season" value="spring" />春天
<input type="radio" name="season" value="summer" checked="checked" />夏天
<input type="radio" name="season" value="autumn" />秋天
<input type="radio" name="season" value="winter" />冬天
单选框,type=“radio”,使用同一个name,传各自默认值,达到单选效果,含checked="checked"属性表示默认选择项

你最喜欢的季节是:
春天
夏天
秋天
冬天

1
2
3
4
5
6
7
你最喜欢的球队是:
<input type="checkbox" name="team" value="Brazil"/>巴西
<input type="checkbox" name="team" value="German" checked="checked"/>德国
<input type="checkbox" name="team" value="France"/>法国
<input type="checkbox" name="team" value="China" checked="checked"/>中国
<input type="checkbox" name="team" value="Italian"/>意大利
多选框type="checkbox"

你最喜欢的球队是:
巴西
德国
法国
中国
意大利

1
2
3
4
5
6
7
8
你喜欢的运动是:
<select name="interesting">
<option value="swimming">游泳</option>
<option value="running">跑步</option>
<option value="shooting" selected="selected">射击</option>
<option value="skating">溜冰</option>
</select>
下拉列表使用select标签,option标签,selecred="selected"表示默认选择项

你喜欢的运动是:

1
2
3
4
5
6
7
8
9
<form id="mySelect" action="/submit" method="post">
<label for="interesting">选择选项:</label>
<select id="interesting" name="interesting">
<option value="option1">选项1</option>
<option value="option2">选项2</option>
<option value="option3">选项3</option>
</select><br>
</form>
这里label标签用于为表单控件提供标签或说明性文本,这里是为了给select下拉列表提供说明性文本:选择选项:

同时在index.js中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 获取下拉列表元素 
const selectElement = document.getElementById('mySelect');
// 创建函数来处理不同的选项值
function handleOption1() {
alert('选项1被选中!');
}
function handleOption2() {
alert('选项2被选中!');
}
function handleOption3() {
alert('选项3被选中!');
}
// 创建一个函数来处理下拉列表变化事件
function handleSelectChange()
{
// 获取所选选项的值
const selectedValue = selectElement.value;
// 根据选项的值调用不同的函数
if (selectedValue === 'option1') { handleOption1(); }
else if (selectedValue === 'option2') { handleOption2(); }
else if (selectedValue === 'option3') { handleOption3(); }
}
// 添加事件监听器,以便在下拉列表值变化时调用handleSelectChange处理函数
selectElement.addEventListener('change', handleSelectChange);

这样监听下拉列表选项的变化来执行对应函数,避免了出现对应上传内容或按钮框内造成代码执行的漏洞(尽可能的避免使用输入框表单传值直接用于函数,可以避免恶意拼接造成的代码执行),这里的监听变化执行处理函数也可以改成按钮执行处理函数,但效率会下降
同时,简单网站的开发,要尽可能的避免传值给函数,宁愿多写函数或者嵌套函数内部传值

按钮

1
2
3
<button type="button">普通按钮</button>
<button type="reset">重置按钮</button>
<button type="submit">提交按钮</button>

这里定义了三种button标签的使用形式,根据type属性的不同完成不同的操作,
type="button"这里使用形式是普通按钮,点击无默认效果,需要通过js绑定对应操作函数
这里用到onclick="run1()"属性来绑定函数,同时onclick=""中也可以直接执行js代码
type="reset"点击重置表单中的所有默认选项,selected="selected"对应选项
type="submit"点击后提交表单

隐藏表单项

1
<input type="hidden" name="userId" value="2233"/>

input标签的type属性等于hidden时,当前表单项对用户隐藏,常用与隐藏一次性token之类的安全相关应用,或者上传userid之类的用户标识信息

1
自我介绍:<textarea name="desc"></textarea>

这里是给出一个输入文本的区域

image.png|300

css

用法

  • 对当前页面有效
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
<!DOCTYPE html>  
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.one {
border: 1px solid black;
width: 100px;
height: 100px;
background-color: lightgreen;
margin-top: 5px;
}
<!--创造长宽为100,垂直间距为5px,黑色边框,填充背景绿色的css样例.one -->
</style>
</head>
<body>

<div style="border: 1px solid black;width: 100px; height: 100px;">&nbsp;</div><!--直接创建div块,设置style属性,这里style属性是包含多个css属性和对应值的字符串 -->

<div class="one">&nbsp;</div>
<div class="one">&nbsp;</div>
<div class="one">&nbsp;</div>
<!--实例化三个one样例-->
</body>
</html>

这样在head中添加的css样例,在当前页面中可使用
在上述示例代码中,一共构建了四个100px * 100px的黑色边框块,只有后面三个为绿色

image.png|400

  • 仅对当前标签有效
1
<div style="border: 1px solid black;width: 100px; height: 100px;">&nbsp;</div>

引入外部css文件

1
2
3
<link rel="stylesheet" type="text/css" href="/aaa/pro01-HTML/style/example.css" />
<!--这里type="text/css"声明了连接资源的属性,text/css指链接资源的类型是css样式表-->
<!--这里link标签的rel="stylesheet"属性,rel声明了被链接的文件是当前文件的样式表-->

可以直接在外部文件中定义css样例,然后通过HTMLhead标签中的link标签引入外部资源,这样来使用css样例,并且避免了在head标签中直接定义,同时便于多个页面的同时引用,现代web界面大多使用这种方法,但是对应的使用会更加复杂

image.png

例如这个ChatGPT的镜像站,对于css样式表都是采取引入外部资源的用法
同时需要注意data-precedence="next"这个自定义属性,表明这个样式表具有较高优先级

1
2
3
4
5
6
7
8
.two {
border: 1px solid black;
width: 100px;
height: 100px;
background-color: yellow;
margin-top: 5px;
}
//这里是two.css文件的内容,放在index.html同路径下
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>  
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="two.css" />
</head>
<body>
<div class="two">&nbsp;</div>
<div class="two">&nbsp;</div>
<div class="two">&nbsp;</div>
</body>
</html>

&nbsp;这里是空格符号实体的html引用

image.png|400

这样通过引用外部css文件的方式实现了三个100px长宽,填充黄色的方框

css代码语法

css代码通常由选择器和声明组成
声明即属性名和对应的属性值

image.png|500

选择器

选择器通常分为以下几种类型:

  • 元素选择器,用于自定义html标签样式
1
2
3
4
p{
color: blue;
font-weight: bold;/*字体加粗*/
}

这样在使用<p></p>标签时,默认字体颜色蓝色,字体加粗

  • 类选择器,通过类名选择元素
1
2
3
.special{
font-size: 20px;
}

这样实现了所有class属性值为==”special”==的元素字体大小设为20px

  • ID选择器,通过id选择元素
1
2
3
#special{
background-color: yellow;
}

这样实现了所有id属性值为==”special”==的元素背景设置为黄色

  • 后代选择器,选择特定元素范围中的后代元素
1
2
3
.container p{
color: blue;
}

这里选择的是class=”container”元素范围中的p标签,并将里面的文本颜色设置为蓝色
需要注意的是这里的后代元素没有任何要求,之前所有的的选择器类型都可以使用
同样的也可以通过多层的嵌套来实现元素的精准选择

🌰如下

1
2
3
4
5
6
7
8
9
10
部分html如下
<div class="container">
<div>
<div>
<p class="special">这是一个特殊的段落。
</p>
</div>
</div>
</div>

1
2
3
4
css样式
.container div div p.special{
background-color: blue;
}

这里的选择器可以改成.container div div .special
在这部分代码中不会引起其他问题

  • 子选择器,选择特定元素的直接子元素
1
2
3
.container > p{
color: blue;
}

其实子选择器的用法和后代选择器的用法大致相同,但是也有区别,子选择器不能嵌套,只能选择一层,而后代选择器可以嵌套多层

JavaScript

按钮弹出helloworld 样例

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HelloWorld</title>
</head>
<body>
<!-- 在HTML代码中定义一个按钮 -->
<button type="button" id="helloBtn">SayHello</button>
</body>

<!-- 在script标签中编写JavaScript代码 -->
<script type="text/javascript">

// document对象代表整个HTML文档
// document对象调用getElementById()方法表示根据id查找对应的元素对象
var btnElement = document.getElementById("helloBtn");

// 给按钮元素对象绑定单击响应函数
btnElement.onclick = function(){

// 弹出警告框
alert("hello");
};
</script>
</html>

这里定义了一个button元素,id为helloBtn,在按钮上显示内容为SayHello

image.png

然后定义了一段js代码块,通过id查找了该button元素,并赋值给变量btnElement,然后通过onclick绑定了按下按钮时执行的函数,这里实际上跟小程序开发中的bindtap属性值等于函数名用法相似
这里执行的函数输出信息时用的弹出警报框的方式,alert函数常用于向用户提供警告消息或提醒,常见的有用户名为空类似消息

js基本语法

js代码的嵌入及文件结构

在html中直接定义js代码块

  • 代码块必须位于script标签中
  • script标签可以位于html代码的任何位置,但是通常为了方便写在body标签后
    样例如下
1
2
3
4
5
6
7
8
9
<!-- 在HBuilderX中,script标签通过打字“sc”两个字母就可以直接完整生成 -->
<script type="text/javascript">

// 下面是同样实现HelloWorld功能的简化版代码
document.getElementById("helloBtn").onclick = function() {
alert("Hello simple");
};

</script>

这里直接通过<script type="text/javascript"></script>标签实现了定位id=helloBtn的按钮元素,并且绑定了按下按钮时弹出警报框显示Hello simple
需要注意的是,为了项目的安全性和可维护性,我们通常不直接使用这种方式写html文件

  • 安全性:这样直接在index.html文件中书写js代码,相当于直接公开了网站是怎么收集利用用户提交的信息的,如果有通过用户提交的参数,特别是文本框参数直接执行命令的,极易收到xss(跨站脚本)攻击,对方可以通过恶意闭包实现自己需要代码的执行,并且扩散到其他站点甚至主机
  • 可维护性:将各种js代码块和css样例表写到其他文件中,这样大幅度的提升了简洁性,同时可以将该项目分包给多个工程师实现不同模块的实现,只需要附上对应接口函数参数需求和使用方法即可

引入外部js文档,并调用文档中已经声明的方法(函数)

这里需要先写一个script标签引用js文件,然后再写一个script标签来调用js中的方法
目录结构

image.png

outter.js内容

1
2
3
function showMessage(){
alert("hello");
}

使用案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
</body>

<!-- 使用script标签的src属性引用外部JavaScript文件,和Java中的import语句类似 -->
<!-- 引用外部JavaScript文件的script标签里面不能写JavaScript代码 -->
<!-- 引用外部JavaScript文件的script标签不能改成单标签 -->
<!-- 外部JavaScript文件一定要先引入再使用 -->
<script src="/pro02-JavaScript/scripts/outter.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">

// 调用外部JavaScript文件中声明的方法
showMessage();
</script>

这样就实现了通过两个script标签定义并使用了showMessage();函数

变量及使用

js中的变量没有严格的定义,而且可以随着代码逐行自动转换数据类型
仅需要注意变量在使用前需要先声明即可
声明可以使用var,let,const
var:全局变量
let:块级作用域变量,即在{},if语句,for循环中有效
const:常量,一次赋值后不可修改

函数

内部函数

  • 弹出警报框
    alert("这是警报内容")
  • 弹出确认框

image.png|600

这里弹出确认框的操作仅仅是confirm函数实现的,他的返回值是布尔类型的ture或者false
这里使用console.log函数,当返回不同布尔值时,写入不同的日志

image.png

  • 打印(写入)日志
1
console.log("日志内容");

声明函数

这里有这两种声明方式

  • 常规函数声明方式,这种方式通过sum(a,b)的形式调用
1
2
3
function sum(a, b) {
return a+b;
}
  • 变量声明方式,因为js的不严格性,可以将整个函数赋值给一个变量,然后通过调用这个变量来调用函数,如下通过total;即可调用
1
2
3
var total = function() {
return a+b;
};

在之前写的案例中也实现了两种方式都可以弹出确认框并写入日志

image.png|600

image.png|600

这段代码中两种方式都实现了相同的功能
无论是哪种方式

1
var result = sum(2, 3);

这种调用函数并传参的方式都是允许的

对象

js中并没有类的概念,对于对象的各个属性,也只需要动态的声明即可
对象的创建方法有两种

  • new方法
1
2
3
4
5
6
7
8
9
10
// 创建对象
var obj01 = new Object();

// 给对象设置属性和属性值
obj01.stuName = "tom";
obj01.stuAge = 20;
obj01.stuSubject = "java";

// 在控制台输出对象
console.log(obj01);

这里首先new了一个Object对象,随后设置属性和属性值实际上是同时进行的,换句话说就是动态进行的声明并赋值

  • {}创建
1
2
3
4
5
6
7
8
9
// 创建对象
var obj02 = {
"soldierName":"john",
"soldierAge":35,
"soldierWeapon":"gun"
};

// 在控制台输出对象
console.log(obj02);

这里创建了对象obj02,在创建的同时就定义了对象的属性和对应值,例如soldierName属性的值为john,这样的对象创建方法更加简单

函数属性

在js对象中,如果需要创建一个函数属性,同样可以使用对象创建时的两种方法
这里给出对应🌰

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 创建对象
var obj01 = new Object();

// 给对象设置属性和属性值
obj01.stuName = "tom";
obj01.stuAge = 20;
obj01.stuSubject = "java";

obj01.study = function() {
console.log(this.stuName + " is studying");
};

// 在控制台输出对象
console.log(obj01);
// 调用函数
obj01.study();

这段代码写了一个日志输出stuName is studying的函数,这种在对象创建号后再动态添加函数的方法实际上用在代码的任何区域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 创建对象
var obj02 = {
"soldierName":"john",
"soldierAge":35,
"soldierWeapon":"gun",
"soldierShoot":function(){
console.log(this.soldierName + " is using " + this.soldierWeapon);
}
};

// 在控制台输出对象
console.log(obj02);
// 调用函数
obj02.soldierShoot();

这里添加函数是在创建对象的定义中实现的,这里的函数并不是动态添加的

this关键字

this指向的内容只有两种

  • 在函数的外面,this指向的是当前窗口
1
2
3
// 直接打印this
console.log(this);
//这里打印了当前浏览器窗口的所有信息
  • 在函数的里面,this指向调用该函数的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 函数中的this
// 1.声明函数
function getName() {
console.log(this.name);
}

// 2.创建对象
var obj01 = {
"name":"tom",
"getName":getName
};
var obj02 = {
"name":"jerry",
"getName":getName
};

// 3.调用函数
obj01.getName();
obj02.getName();

这里分别指向调用函数的对象
实际上来说,js重的this指针是跟其他语言有着很大区别的,主要的原因就是因为js中的this是动态的,会随着函数的调用不停的更新

数组

先给出一个例子

  • new创建
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
// 1.创建数组对象
var arr01 = new Array();

// 2.压入数据
arr01.push("apple");
arr01.push("orange");
arr01.push("banana");
arr01.push("grape");

// 3.遍历数组
for (var i = 0; i < arr01.length; i++) {
console.log(arr01[i]);
}

// 4.数组元素反序
arr01.reverse();
for (var i = 0; i < arr01.length; i++) {
console.log(arr01[i]);
}

// 5.数组元素拼接成字符串
var arrStr = arr01.join(",");//以,为分隔符
console.log(arrStr);

// 6.字符串拆分成数组
var arr02 = arrStr.split(",");//以,切割字符串
for (var i = 0; i < arr02.length; i++) {
console.log(arr02[i]);
}

// 7.弹出数组中最后一个元素
var ele = arr01.pop();
console.log(ele);

这里发现js中的数组有着一部分栈的属性,主要是因为js数组对象中,索引和长度等信息是作为数组对象的属性存储在栈内存中的,这样实现了对数组的快速访问和操作
同时js数组中的元素的实际值是存放在堆中的,这样由于堆内存是动态分配的,所以数组的大小是动态的,同时这里数组中元素的实际值是作为对象的属性存放在堆中的,所以数组元素中的值可以是任何类型
这里数组与栈和堆的关系实际上也体现了js的内核,动态性,弱类型

  • []创建
1
2
3
// 8.使用[]创建数组
var arr03 = ["cat","dog","tiger"];
console.log(arr03);

JSON

json格式的数据,常用于跨平台传输数据

格式

  • =={}==定义JSON对象
1
{key:value,key:value,...,key:value}
  • ==[]==定义JSON数组
1
[value,value,...,value]

由于JSON中的value部分可以继续使用json对象或者数组,所以JSON是可以多层嵌套的
对于复杂的数据,通常直接使用多层嵌套解决

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
{
"stuId":556,
"stuName":"carl",
"school":{
"schoolId":339,
"schoolName":"atguigu"
},
"subjectList":[
{
"subjectName":"java",
"subjectScore":50
},
{
"subjectName":"PHP",
"subjectScore":35
},
{
"subjectName":"python",
"subjectScore":24
}
],
"teacherMap":{
"aaa":{
"teacherName":"zhangsan",
"teacherAge":20
},
"bbb":{
"teacherName":"zhangsanfeng",
"teacherAge":108
},
"ccc":{
"teacherName":"zhangwuji",
"teacherAge":25
}
}
}

之前做的微信小程序抓包的时候有抓到对应的json内容

JOSN格式的互相转换

1
2
3
var jsonObj = {"stuName":"tom","stuAge":20};
var jsonStr = JSON.stringify(jsonObj);
jsonObj = JSON.parse(jsonStr);

DOM

包含了所有标签对象的整个树形结构对象
就是JavaScript中的一个可以直接使用的内置对象:document
实际上就是html标签树,也就是说例如index.html这样的一个文档,整个文档就是一个document

DOM操作

在实际的js开发中,常使用document对象的各种方法来实现功能

在整个文档中查找元素节点

  • 根据id属性值查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script type="text/javascript">  

// document对象代表整个HTML文档
// document对象调用getElementById()方法表示根据id查找对应的元素对象
var btnElement = document.getElementById("helloBtn");

// 给按钮元素对象绑定单击响应函数
btnElement.onclick = function(){

// 弹出警告框
alert("hello");
};
console.log(this);
</script>

这里使用了DOM对象的getElementById()方法,通过id属性值来对应查找元素对象并赋值给一个变量,实现点击元素弹出警告框

  • 根据标签名查找元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<body>

<h1>DOM操作实例</h1>

<div class="container">
<p>这是一个段落。</p>
<p>这是另一个段落。</p>
</div>

<script>
// 获取所有的 <p> 元素
var paragraphs = document.getElementsByTagName("p");

// 遍历所有的 <p> 元素并修改其内容
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].innerHTML = "这是修改后的段落 " + (i+1);
}
</script>

</body>
</html>

document.getElementsByTagName("p");实现了查找文档中的所有段落标签包含内容,返回的值是HTMLCollection类型,实际上就是html中的动态数组,赋值给paragraphs变量,实现内容修改HTMLCollection类型的数组是不可修改的
需要注意的是

  • 根据name属性值查询
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
<!DOCTYPE html>
<html>
<body>

<h1>DOM操作实例</h1>

<form>
<label for="name">姓名:</label>
<input type="text" name="name" id="nameInput">
<br>
<label for="email">邮箱:</label>
<input type="email" name="email" id="emailInput">
<br>
<input type="submit" value="提交">
</form>

<script>
// 获取 name 属性为 "name" 的所有元素
var elements = document.getElementsByName("name");

// 修改第一个匹配元素的值
elements[0].value = "John Doe";

// 修改第一个匹配元素的样式
elements[0].style.border = "2px solid red";
</script>

</body>
</html>

这里document.getElementsByName("name");方法,返回的同样是的动态数组

在指定元素节点范围内查找子节点

  • 查找所有子节点 element.childNodes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="parent">
<p>这是一个段落。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
</div>

<script>
var parent = document.getElementById("parent");
var childNodes = parent.childNodes;
console.log(childNodes);
</script>

这里返回的动态数组共五个节点

1
2
3
4
5
0 个节点是一个文本节点,它包含了父元素中第一个子元素之前的空白字符。
1 个节点是一个 `p` 元素,它是父元素的第一个子元素。
2 个节点是一个文本节点,它包含了 `p` 元素和 `ul` 元素之间的空白字符。
3 个节点是一个 `ul` 元素,它是父元素的第二个子元素。
4 个节点是一个文本节点,它包含了父元素中最后一个子元素之后的空白字符。

查找第一个子节点 element.firstChild

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>获取第一个列表项的文本内容</title>
</head>
<body>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
<script>
// 获取第一个列表项的文本内容
const ul = document.querySelector('ul');
const firstItem = ul.firstChild;
const textContent = firstItem.textContent;
console.log(textContent); // 输出:列表项1
</script>
</body>
</html>

这里获取了列表项的第一个子节点li,并且读取了该子节点中的文本内容

查找最后一个子节点 element.lastChild

用法和查找第一个子节点完全一致

查找指定元素的父节点 element.parentNode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>获取元素的父节点文本内容</title>
</head>
<body>
<div>
<p>这是一个段落</p>
</div>
<script>
// 获取元素的父节点文本内容
const p = document.querySelector('p');
const parent = p.parentNode;
const textContent = parent.textContent;
console.log(textContent); // 输出:这是一个段落
</script>
</body>
</html>

这里输出的内容和p元素内容一致,因为div标签只有当前p标签一个子标签

  • 查找兄弟节点
    前一个兄弟节点 node.previousSibling
    后一个兄弟节点 node.nextSibling

  • 修改文本内容

1
element.firstChild.nodeValue=新文本值

DOM的增删改

  • 增加元素到DOM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOM 增删改操作示例</title>
</head>
<body>
<div id="container">
<h1>DOM 增删改操作示例</h1>
</div>
<script>
// 创建一个新的段落元素
const p = document.createElement('p');
// 创建一个包含文本内容的文本节点
const text = document.createTextNode('这是一个新的段落。');
// 将文本节点添加到段落元素中
p.appendChild(text);
// 将段落元素添加到容器元素中
const container = document.getElementById('container');
container.appendChild(p);
</script>
</body>
</html>

createTextNodecreateElement不会自动添加到文档,需要使用container.appendChild(p);来添加容器的子节点从而添加到文档

  • 删除指定子节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOM 增删改操作示例</title>
</head>
<body>
<div id="container">
<h1>DOM 增删改操作示例</h1>
<p>这是一个要删除的段落。</p>
</div>
<script>
// 获取要删除的段落元素
const p = document.querySelector('p');
// 获取该元素的父节点
const parent = p.parentNode;
// 从父节点中删除该元素
parent.removeChild(p);
</script>
</body>
</html>
// querySelector('p');获取该元素
// parent.removeChild(p);删除p
  • 修改指定元素文本内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOM 增删改操作示例</title>
</head>
<body>
<div id="container">
<h1>DOM 增删改操作示例</h1>
<p>这是一个要修改的段落。</p>
</div>
<script>
// 获取要修改的段落元素
const p = document.querySelector('p');
// 修改该元素的文本内容
p.innerHTML = '这是修改后的文本内容。';
</script>
</body>
</html>
//querySelector('p');选中p
//.innerHTML修改对应文本内容

JavaScript事件驱动

JavaScript 事件驱动模型是指 JavaScript 运行时环境(如浏览器)在执行 JavaScript 代码时,会不断地监听各种事件,如鼠标点击、键盘输入、页面加载完成等,当事件发生时,会触发相应的事件处理函数来响应事件。
这里给出两个例子

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#eventArea {
border: 1px solid black;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<!-- 用div作为鼠标移动区域 -->
<div id="eventArea"></div>

<!-- 在p标签内显示鼠标坐标 -->
<p id="showData"></p>
</body>
<script type="text/javascript">

// 根据id找到div标签对应的元素对象
var divEle = document.getElementById("eventArea");

// 根据id找到p标签对应的元素对象
var pEle = document.getElementById("showData");

// 声明事件响应函数
function whenMouseMove(event){
pEle.innerText = event.clientX + " " + event.clientY;
}

// 将事件响应函数赋值给对应的事件属性
// onmousemove表示在鼠标移动的时候
divEle.onmousemove = whenMouseMove;
</script>
</html>

image.png

这里实现了在eventArea区域内监控鼠标坐标输出到showdate p标签
对于鼠标的移动用了event这个常见的事件驱动对象的clientX clientY函数
会无限循环监控鼠标坐标并输出

键盘贪吃蛇

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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<!DOCTYPE html>  
<html>
<head>
<meta charset="utf-8">
<title>贪吃蛇游戏</title>
<style> canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
// 获取canvas元素用于绘制区域
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

// 定义蛇的初始位置和长度
var snake = [{x: 200, y: 200}, {x: 190, y: 200}, {x: 180, y: 200}, {x: 170, y: 200}, {x: 160, y: 200}];

// 定义蛇头的初始位置和方向
var head = {x: 200, y: 200, direction: "right"};

// 定义食物的初始位置
var food = {x: 100, y: 100};

// 定义游戏速度和计时器
var speed = 100;
var timer;

// 监听键盘事件
document.addEventListener("keydown", function(event) {
// 判断按键并改变蛇头的方向
if (event.keyCode === 37 && head.direction !== "right") {
head.direction = "left";
} else if (event.keyCode === 38 && head.direction !== "down") {
head.direction = "up";
} else if (event.keyCode === 39 && head.direction !== "left") {
head.direction = "right";
} else if (event.keyCode === 40 && head.direction !== "up") {
head.direction = "down";
} else if (event.keyCode === 13) { // 按下回车键
resetGame();
}
});

// 绘制蛇和食物
function draw() {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);

// 绘制蛇
for (var i = 0; i < snake.length; i++) {
ctx.fillStyle = "#000";
ctx.fillRect(snake[i].x, snake[i].y, 10, 10);
}

// 绘制食物
ctx.fillStyle = "#f00";
ctx.fillRect(food.x, food.y, 10, 10);
}

// 移动蛇
function move() {
// 计算蛇头的新位置
if (head.direction === "right") {
head.x += 10;
} else if (head.direction === "left") {
head.x -= 10;
} else if (head.direction === "down") {
head.y += 10;
} else if (head.direction === "up") {
head.y -= 10;
}

// 判断是否吃到食物
if (head.x === food.x && head.y === food.y) {
// 生成新的食物
food.x = Math.floor(Math.random() * (canvas.width / 10)) * 10;
food.y = Math.floor(Math.random() * (canvas.height / 10)) * 10;

// 增加蛇的长度
snake.push({});
}

// 将蛇的身体向前移动一格
for (var i = snake.length - 1; i > 0; i--) {
snake[i].x = snake[i - 1].x;
snake[i].y = snake[i - 1].y;
}

// 更新蛇头的位置
snake[0].x = head.x;
snake[0].y = head.y;

// 判断是否撞墙或自撞
if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) {
clearInterval(timer);
alert("游戏结束!");
resetGame();
} else {
for (var i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
clearInterval(timer);
alert("游戏结束!");
resetGame();
}
}
}
}

// 开始游戏
function start() {
timer = setInterval(function() {
move();
draw();
}, speed);
}

// 重置游戏
function resetGame() {
clearInterval(timer);
snake = [{x: 200, y: 200}, {x: 190, y: 200}, {x: 180, y: 200}, {x: 170, y: 200}, {x: 160, y: 200}];
head = {x: 200, y: 200, direction: "right"};
food = {x: Math.floor(Math.random() * (canvas.width / 10)) * 10, y: Math.floor(Math.random() * (canvas.height / 10)) * 10};
draw();
start();
}

// 初始化游戏
function init() {
draw();
start();
}

// 调用初始化函数
init();
</script>
</body>
</html>

这里使用了event.keyCode来获取键盘按下的按键编号

[[Vue3.js]]