??前面的话??
前面我们学习了JavaScript基本的语法知识,但是只会这个语法我们好像也做不了什么,本篇文章将介绍DOM API,由于DOM体系非常大,本文只介绍一些比较基础常用的DOM知识,做一个DOM的引路人,目的是为了支撑完成猜数字和表白墙案例,其余的知识需要自己去知识海洋去探索了。
📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏??留言📝 📌本文由未见花闻原创,CSDN首发! 📆首发时间:🌴2022年5月29日🌴 ??坚持和努力一定能换来诗与远方! 💭推荐书籍:📚《JavaScript高级程序设计》 💬参考在线编程网站:🌐牛客网🌐力扣 博主的码云gitee,平常博主写的程序代码都在里面。 博主的github,平常博主写的程序代码都在里面。 🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
1.DOM API知识串讲
1.1选中页面标签
在DOM中,document页面全局对象,里面的函数querySelector和querySelectorAll 用于选择元素,通过传入CSS选择器来达到目的,选择的范围是位于该函数之前所存在的选择器,没找到返回值为null 。
let obj = document.querySelector("选择器");
如果选择的标签在页面有多个,只会选择第一次出现在页面的标签。
如果想要把这些元素都选中,就需要使用querySelectorAll函数。
用法和querySelector 是一样的。
let var_name = document.querySelectorAll("选择器");
该函数会返回一个类似与数组的对象,用法和数组一模一样,但是除此之外,还能添加键值对。 对该数组里面的元素进行展开,会发现很多属性,这些属性都是DOM原生的一些属性。
1.2操作页面标签的属性
1.2.1事件
JS很多代码都是通过“事件”来触发的,比如鼠标移动,鼠标滚动,键盘输入,修改浏览器大小等等都会产生事件。
事件的三要素:
- 事件源,哪个HTML元素产生的事件。
- 事件类型,如鼠标移动,鼠标点击,窗口大小改变等。
- 事件处理方式,当事件产生后,要执行什么js代码。
例如,点击事件操作代码:
let button = document.querySelector("button");
button.onclick = function (){
alert("嘻嘻嘻!");
}
栗子与运行效果:
图中给出了一种等价的写法,但是等价的写法会使HTML代码的结构更加复杂,所以更建议图中的第一种写法。
1.2.2获取元素
操作元素的分类:
首先,操作元素的内容可以使用innerHTML属性来获取一个标签里面的内容。
let var_name = document.querySelector();
let content = var_name.innnerHTML;
var_name.innerHTML = 修改内容;
栗子:
效果: 我们发现相同的元素都被折叠输出了,我们可以点击开发者工具的设置栏,来设置展开输出。
上面我们在所选中的标签里面放置的是文本,如果不是文本呢?其实也是一样的,假设里面放了一个列表标签,那么拿到的结果就是里面标签的HTML代码。
1.2.3修改元素
我们也可以来修改HTML的内容,比如将列表改为一个标题。
效果:
1.2.4计数器
根据获取与修改元素的知识,我们可以来实现一个简单的计数器,基本思路就是:
- 获取元素内容
- 修改元素内容(加一操作)
- 写回到元素里面
效果: 欸,好像与我们的预期有点不一致,原因就是修改元素内容时,拿到的内容是字符串类型的,发生的是拼接效果,而不是算术效果,所以我们需要进行转换,那如何转换?我们可以使用与java非常类似且同名的一个方法,它就是parseInt,同理如果需要小数那就有parseFloat,注意这里没有parseDouble方法哦!
效果: 我们来丰富一下,加一个按钮,可以完成减的功能。
页面代码:
<style>
#screen{
width: 88px;
height: 20px;
text-align: center;
line-height: 20px;
border-radius: 4px;
background-color: rgb(100, 200, 100);
}
#plus, #sub{
width: 42px;
height: 20px;
border-radius: 10px;
margin-top: 4px;
border: 0px;
background-color: rgb(180, 200, 255);
}
</style>
<div id="screen">
0
</div>
<button id="plus">计数+1</button>
<button id="sub">计数-1</button>
<script src="./document.js">
</script>
JavaScript代码:
let plus = document.querySelector("#plus");
let sub = document.querySelector("#sub");
let plus_func = function() {
let add_btn = document.querySelector("#screen");
let val = add_btn.innerHTML;
val = parseInt(val);
val = val + 1;
add_btn.innerHTML = val;
}
let sub_func = function() {
let sub_btn = document.querySelector("#screen");
let val =sub_btn.innerHTML;
val = parseInt(val);
val = val - 1;
sub_btn.innerHTML = val;
}
plus.onclick = plus_func;
sub.onclick = sub_func;
效果:
但是对于但标签是没有innerHTML属性的,比如input 标签,虽然不能通过innerHTML获取属性,但是可以通过value 属性获取内容。
页面代码:
<input type="text" id="in" value="0">
<button id="add">+1</button>
<script src="./document.js">
</script>
JavaScript代码:
let add = document.querySelector("#add");
add.onclick = function() {
let add_btn = document.querySelector("#in");
let val = add_btn.value;
val = parseInt(val);
val = val + 1;
add_btn.value = val;
}
效果:
1.2.5点击图片切换
我们想实现一个小案例,就是点击一个图片就能切换图片,再点击一次又能够切换回来,我们可以利用DOM来修改元素的属性来实现,在这个案例中,我们只需设置点击事件为修改图片的路径,也就是src 属性,就可以实现图片的切换。
假设第一张图片的路径是./jee.png ,第二张图片的路径是./樱花.png ,实现图片切换的基本思路为:
- 获取
img 元素。 - 设置onclick。
- 点击事件的细节就是判断路径是否包含
ee ,包含就将src 属性换成./樱花.png ,反过来,判断路径是否包含樱花 ,包含就将src 属性换成./jee.png - 可以使用
indexOf 方法判断是否包含某个字符串。
JavaScript代码:
let img = document.querySelector("img");
img.onclick = function() {
console.log(img.src);
if (img.src.indexOf("ee") >= 0) {
img.src = './樱花.png';
} else if (img.src.indexOf("樱花")) {
img.src = './jee.png'
}
}
页面代码:
<style>
img {
height: 450px;
}
</style>
<img src="./jee.png" alt="">
<script src="./document.js">
</script>
效果: 具体哪些属性可以修改,我们可以使用console.dir 函数来获取某个元素DOM API能够操作的全部属性。
1.2.6暂停/播放切换
实现一个按钮,点击之后按钮文字从"播放"变为"暂停",再点击一次,按钮文字从"暂停"变为"播放"。
实现逻辑和切换逻辑是差不多的,具体看代码吧:
JavaScript代码:
let play = document.querySelector("#play");
play.onclick = function(){
if (play.value == "播放") {
play.value = "暂停";
} else if (play.value = "暂停") {
play.value = "播放";
}
}
页面代码:
<input id="play" type="button" value="播放">
实现效果:
1.2.7全选/取消全选
首先我们需要创建若干个复选框,只有一个全选框,我们选中全选框,其他元素需要被全部选中,一旦其他元素有未选中的,全选也必须是未选中的。
实现的基本思路:
- 获取全选框元素,获取其他元素。
- 注册全选框的点击事件,检查其他框是否都被选中,如果选中,则全选框也选中,否则全选框不选中。
- 对每一个其他复选框设置点击事件,并将状态与全选复选框关联。
- 每次点击其他框都要检测其他框是否都选中,以确定全选框的状态。
JavaScript代码:
let all = document.querySelector("#all");
let gameroles = document.querySelectorAll(".gamerole");
all.onclick = function() {
for (let i = 0; i < gameroles.length; i++) {
gameroles[i].checked = all.checked;
}
}
for (let i = 0; i < gameroles.length; i++) {
gameroles[i].onclick = function() {
all.checked = checkRole();
}
}
function checkRole() {
for (let i = 0; i < gameroles.length; i++) {
if (gameroles[i].checked == '') {
return '';
}
}
return "checked";
}
页面代码:
<input id="all" type="checkbox">全选 <br>
<input class="gamerole" type="checkbox">胡桃 <br>
<input class="gamerole" type="checkbox">可莉 <br>
<input class="gamerole" type="checkbox">万叶 <br>
<input class="gamerole" type="checkbox">心海 <br>
<input class="gamerole" type="checkbox">锅巴 <br>
实际效果:
1.2.8点击文字放大
DOM还可以修改style 属性,下面来尝试运用选中元素与修改元素的知识,来实现点击文字放大的一个小案例。
因为CSS中不区分大小写,属性与变量的命名采用脊柱式命名,而JS中- 不能用于变量的命名,为了能够将CSS属性与JS变量名匹配,JS使用驼峰的形式表示CSS的属性,例如font-size 属性,对应JS的变量名为fontSize 。
对于文字的放大,我们可以给文本所在的标签注册一个点击事件,每点击一次就将字体大小增大,即修改CSS的font-size 属性。
JavaScript代码:
let div = document.querySelector("div");
div.onclick = function() {
let wordsSize = parseInt(div.style.fontSize);
console.log("修改前" + wordsSize);
wordsSize += 5;
div.style.fontSize = wordsSize + "px";
console.log("修改后" + wordsSize);
}
页面代码:
<div style="font-size: 20px;">
我是一段文本
</div>
实现效果:
1.2.9实现关灯/开灯(夜间/白间模式切换)
很多情况下一个个修改样式属性太麻烦了,我们也可以直接修改类属性来达到效果,可以通过选中元素变量名.className 来获取和修改类属性。
由于JavaScript里面的class 是一个关键字,因此获取元素的class 不能使用class ,而需要使用className ,多个class 属性可以使用classList 。
JavaScript代码:
let div = document.querySelector('div');
let button = document.querySelector('button');
button.onclick = function(){
if (div.className == "light") {
div.className = 'black';
button.innerHTML = '开灯';
} else if (div.className == 'black') {
div.className = 'light';
button.innerHTML = '关灯';
}
}
页面代码:
<style>
div{
width: 500px;
text-align: center;
}
.light, .black{
width: 500px;
height: 500px;
text-align: center;
line-height: 500px;
font-size: 50px;
}
button{
width: 100px;
height: 50px;
font-size: 20px;
background-color: rgb(100,200,100);
border: 0cm;
border-radius: 10px;
}
.light{
background-color: aliceblue;
color: black;
}
.black{
background-color: black;
color: aliceblue;
}
</style>
<div class="light" >我是一段文本</div>
<div>
<button>关灯</button>
</div>
实际效果:
1.3操作页面结点
1.3.1新增结点
除了修改元素的属性和内容,我们还可以在页面上添加元素,要添加元素,那就得先新建一个元素,并且还需要依赖一个父元素(已经创建好的),把这个新建的元素插入到父元素中就能实现元素的添加(依赖与DOM树),这个操作也被称为新增页面结点。 新建元素:
let newDiv = document.createElement("元素标签");
补充元素内容:
newDiv.属性 = 值;
插入到DOM树:
选中的父元素.appendChild(创建的子元素);
实例: JavaScript代码:
let cnt = 1;
let add = document.querySelector("#add");
let parent = document.querySelector("#container");
add.onclick = function() {
let newDiv = document.createElement("div");
newDiv.id = "newDiv" + cnt;
newDiv.className = cnt;
newDiv.innerHTML = "hello";
parent.appendChild(newDiv);
console.log(newDiv);
cnt++;
}
页面代码:
<div id="container"></div>
<button id="add">新增节点</button>
实际效果:
1.3.2删除结点
删除结点就更容易了,在DOM树上删除结点就行。
删除结点:
获取到的父元素.removeChild(需要删除的子元素);
实例: JavaScript代码:
let cnt = 1;
let add = document.querySelector("#add");
let parent = document.querySelector("#container");
let arr = [];
add.onclick = function() {
let newDiv = document.createElement("div");
arr[cnt-1] = newDiv;
newDiv.id = "newDiv" + cnt;
newDiv.className = cnt;
newDiv.innerHTML = "hello";
parent.appendChild(newDiv);
console.log(newDiv);
cnt++;
}
let del = document.querySelector("#del");
del.onclick = function() {
cnt--;
if (cnt > 0) {
console.log( "成功删除一个元素");
parent.removeChild(arr[cnt-1]);
} else {
console.log( "该父元素已经没有元素可以删除了");
cnt++;
}
}
页面代码:
<div id="container"></div>
<button id="add">新增节点</button>
<button id="del">删除节点</button>
实际效果:
2.综合案例
2.1猜数字
目标页面
猜数字的逻辑我就不赘述了,不过里面需要取随机数,我们可以通过js中的Math.random() 函数来获取随机数,该函数生成随机数的范围是[0,1) 区间内的一个小数,我们需要的是[1,100] 之间的整数,我们可以乘上100 后向下取整加一就能得到目标区间的数了,实现向下取整的函数是Math.floor(数字) 。
然后前端页面部分是通过HTML加上CSS弹性布局实现的,交互通过JavaScript DOM实现,下面的表白墙案例也是一样的,就不多说了。
JavaScript代码:
let input = document.querySelector("#guess");
let ret = document.querySelector("#result");
let cnt = document.querySelector("#count");
let guessBtn = document.querySelector("#b1");
let flash = document.querySelector("#b2");
let ansNumber = Math.floor(Math.random() * 100) + 1;
guessBtn.onclick = function(){
if(input.value == '') {
return;
}
let guessNumber = parseInt(input.value);
if (guessNumber > ansNumber) {
ret.innerHTML = "YO!猜大了!";
ret.style.color = "red";
} else if (guessNumber < ansNumber) {
ret.innerHTML = "YO!猜小了!";
ret.style.color = "red";
} else {
ret.innerHTML = "Bingo!猜对了!";
ret.style.color = "green";
}
if (ret.innerHTML != "Bingo!猜对了!") {
let guessCount = parseInt(cnt.innerHTML) + 1;
cnt.innerHTML = guessCount;
}
}
flash.onclick = function() {
location.reload();
}
页面代码:
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>猜数字</title>
</head>
<body>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: aliceblue;
}
h3 {
width: 100%;
height: 30px;
text-align: center;
line-height: 30px;
color: blueviolet;
margin: 10px 0;
}
.guessdiv {
width: 100%;
height: 30px;
text-align: center;
display: flex;
justify-content: center;
}
.guessdiv #b1{
height: 20px;
width: 20%;
background-color: rgb(100,200,255);
color: aliceblue;
border: 0cm;
border-radius: 5px;
}
.guessdiv #b1:active{
background-color: gray;
}
.guessdiv #guess{
width: 50%;
height: 20px;
border: 1px solid rgb(100,200,255);
border-radius: 5px;
text-indent: 0.6em;
outline: none;
}
.guessdiv #number{
width: 30%;
text-align: right;
}
.guessdiv #in {
width: 70%;
margin-left: 2%;
text-align: left;
}
.cnt, .ret{
width: 100%;
height: 30px;
text-align: center;
}
.rev{
width: 100%;
height: 20px;
text-align: center;
}
.rev #b2{
margin: 4px;
height: 20px;
width: 100px;
background-color: rgb(100,200,100);
color: aliceblue;
border: 0cm;
border-radius: 5px;
}
.rev #b2:active{
background-color: gray;
}
.ret, .cnt{
width: 100%;
height: 30px;
display: flex;
justify-content:center;
}
.guessdiv #messr, .guessdiv #messc {
width: 30%;
text-align: right;
}
.guessdiv #result, .guessdiv #count{
width: 70%;
text-align: left;
margin-left: 5%;
}
</style>
<h3>猜数字游戏</h3>
<div class="guessdiv">
<span id="number">要猜的数字:</span>
<span id="in">
<input id="guess" type="text" value placeholder="请猜1-100之间的数字,否则你永远猜不对!">
<button id="b1">我就要猜它</button>
</span>
</div>
<div class="guessdiv">
<span id="messr">结果:</span>
<span id="result">你还没有猜哦!</span>
</div>
<div class="guessdiv">
<span id="messc">次数:</span>
<span id="count">0</span>
</div>
<div class="rev">
<button id="b2">
开始/重新开始猜数字
</button>
</div>
<script src="./猜数字.js">
</script>
</body>
</html>
实际效果:
2.2表白墙
目标页面
JavaScript代码:
let loveBtn = document.querySelector("#submit");
let adv = ["深情地", "温柔地", "随便地", "紧张地", "幽默地", "滑稽地", "开心地", ""];
let record = [];
let i = 0;
loveBtn.onclick = function() {
let inputs = document.querySelectorAll("input");
let from = inputs[0].value;
let to = inputs[1].value;
let message = inputs[2].value;
if (from == '' || to == '' || message == '') {
return;
}
let n = adv.length;
let index = (Math.floor(Math.random() * 1000) + 1) % n;
let romAdv = adv[index];
let loveMess = from + romAdv + "对" + to + "说" + message;
record[i] = "留言" + (i+1) + ":" + loveMess;
let div = document.createElement("div");
div.innerHTML = record[i];
div.className = 'oh';
let container = document.querySelector(".container");
container.appendChild(div);
i++;
for (let i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
}
页面代码:
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表白墙</title>
</head>
<body>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: aliceblue;
}
.container {
width: 100%;
}
h3 {
text-align: center;
padding: 30px 0;
font-size: 24px;
color: rgb(255, 140,160);
}
p {
text-align: center;
color: gray;
padding: 5px 0;
}
.row {
width: 400px;
height: 50px;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
}
.row span{
width: 100px;
height: 40px;
text-align:center;
padding-right: 0px;
font-size: 24px;
color: rgb(255, 140,160);
}
.row input{
width: 300px;
height: 40px;
border: 2px solid rgb(255, 140,160);
border-radius: 5px;
outline: 0;
text-align: left;
padding-left: 0px;
margin-left: 0px;
text-indent: 0.4em;
font-size: 20px;
color: rgb(100,160,255);
}
.row #submit{
width: 200px;
height: 40px;
border-radius: 10px;
font-size: 24px;
border: 0px solid rgb(255, 140, 160);
background-color: rgb(255, 140, 160);
color: aliceblue;
line-height: 40px;
margin-top: 8px;
}
.row #submit:active{
background-color: rgb(140,180,255);
}
.oh {
width: 100%;
height: 30px;
margin-top: 8px;
font-size: 16px;
color: rgb(180,140,220);
text-align: center;
line-height: 30px;
}
</style>
<div class="container">
<h3>"真的是"表白墙</h3>
<p>输入后点击提交, 会将信息显示在表白按钮下方</p>
<p>这是一个正经的表白墙,这真的不是一个表白墙</p>
<p></p>
<div class="row">
<span>是谁:</span>
<input type="text" value placeholder="大白">
</div>
<div class="row">
<span>向谁:</span>
<input type="text" value placeholder="小白">
</div>
<div class="row">
<span>说:</span>
<input type="text" value placeholder="你好">
</div>
<div class="row">
<button id="submit">表白</button>
</div>
</div>
<script src="./表白墙0.0.js"></script>
</body>
</html>
实际效果:
下期预告:博客系统前端交互页面设计
觉得文章写得不错的老铁们,点赞评论关注走一波!谢谢啦!
|