✏️作者:银河罐头
📋系列专栏:JavaEE
🌲“种一棵树最好的时间是十年前,其次是现在”
目录
- DOM 基本概念
- 选中页面元素
- 事件初识
- 事件三要素
 
- 操作元素
- 获取/修改元素内容
- 获取/修改元素属性
- 获取/修改表单元素属性
- value
- type
 
- 获取/修改样式属性
 
- 操作节点
- 新增元素
- 删除元素
 
- 代码案例:猜数字
- 代码案例:表白墙
WebAPI 是浏览器给 JS 代码提供的功能。浏览器不同,API 的行为也可能会存在差异。
DOM 基本概念
DOM 全称为 Document Object Model.
文档对象模型
把 html 中的每一个 标签都可以映射到 JS 中的一个对象
标签上显示啥,都可以通过 JS 对象感知到。
JS 对象修改对应属性,能够影响到标签的展示
通过 DOM 就可以让 JS 代码来操作页面元素。
- DOM 树结构形如:

选中页面元素
querySelector(CSS 选择器)
<body>
    <div class="box">abc</div>
    <div id="id">def</div>
    <h3>
        <span>
            <input type="text">
        </span>
    </h3>
    <script>
        let elem1 = document.querySelector('.box');//类选择器
        //如果有 2 个.box,默认选中第一个
        //如果想选中所有的 .box,可以使用querySelectorAll(返回数组)
        console.log(elem1);
    </script>
</body>
//打印结果
<div class="box">abc</div>
console.dir(elem1);
//打印结果
div.box
let elem2 = document.querySelector('#id');//id 选择器
console.log(elem2);
let elem3 = document.querySelector('h3>span>input');//后代选择器
console.log(elem3);
事件初识
事件就是针对用户的操作进行的一些响应。
要能够和用户交互,就需要知道用户干了啥。用户做的一些动作,就会浏览器中产生了一些事件。代码就需要对事件做出反应。
这里的"事件",比如:鼠标点击,鼠标双击,鼠标移动,键盘按下,调整浏览器窗口…
事件三要素
1.事件源:哪个元素产生的事件。
2.事件类型:点击,双击,移动,键盘按下…
3.事件处理程序:事件发生之后,要执行哪个代码。(要执行的代码都是提前设定好的)(这个设定的过程称之为"时间绑定")
<div class="box" onclick="alert('hello')">abc</div>
最简单的方式,就是在元素中使用 "onXXX"这样的方法,来绑定一个事件处理程序。

操作元素
获取/修改元素内容
先获取到该元素,使用 innerHTML 属性,就能拿到元素里的内容,修改该属性,就能影响到界面的显示。
div.onclick = function(){
    console.log(div.innerHTML);
    div.innerHTML += 'a';
}

chrome 控制台默认会把相邻的相同的日志合并。

如果不想合并就把这个选项去掉。
获取/修改元素属性
html 标签的属性会映射到 JS 对象中。
let img = document.querySelector('img');
console.dir(img);
img.onclick = function(){
    console.log(img.src);
    console.log(img.alt);
    console.log(img.title);
    console.log(img.width);
    console.log(img.height);
    img.src = '美女小姐姐.jpg';
}
获取/修改表单元素属性
表单元素(input, textarea, select…)有一些特别的属性,普通标签没有的。
表单(主要是指 input 标签)的以下属性都可以通过 DOM 来修改:
value: input 的值.
disabled: 禁用
checked: 复选框会使用
selected: 下拉框会使用
type: input 的类型(文本, 密码, 按钮, 文件等)
value
	<input type="text">
    <button>点我一下</button>
    <script>
        let input = document.querySelector('input');
        let button = document.querySelector('button');
        button.onclick = function(){
            console.log(input.value);
            console.log(input.innerHTML);
        }
    <script>
innerHTML 得到的是标签的内容(是开始标签和结束标签中间夹着的内容)
而 input 是个单标签,没有内容。
- 下面来实现一个功能。
给 input 里面放 1 个数字,每次点击按钮,数字 + 1 并显示出来。
let input = document.querySelector('input');
let button = document.querySelector('button');
button.onclick = function(){
    let value = input.value;
    value += 1;
    input.value = value;
}

因为 input.value 是 String 类型,所以呈现出来的是字符串拼接的效果,和预期不符。
所以就需要把字符串转成整数。
let value = parseInt(input.value);
type
切换按钮的文本。
button.onclick = function(){
    if(input.type == 'text'){
        input.type = 'password';
        button.innerHTML = '显示密码';
    }else{
        input.type = 'text';
        button.innerHTML = '隐藏密码';
    }
}
获取/修改样式属性
1.修改内联样式(修改 style 属性的值)
<div style="font-size: 20px;">这是一个 div, 点击之后字体放大</div>
    <script>
        let div = document.querySelector('div');
        div.onclick = function() {
            //先获取到字体大小
            let fontSize = parseInt(div.style.fontSize);
            fontSize += 10;
            div.style.fontSize = fontSize + 'px';
        }
	</script>

style 里面的属性名字都是和 css 的一样,只不过是脊柱命名改驼峰。
2.修改元素应用的 CSS 类名
- 切换夜间模式
<div id= "one" class="light" style="font-size: 20px; height: 500px;">这是一个 div, 点击之后字体放大</div>
    <style>
        .light {
            /* 日间模式 */
            color: black;
            background-color: white;
        }
        .dark {
            /* 夜间模式 */
            color: white;
            background-color: black;
        }
    </style>
    <script>
        let div = document.querySelector('#one');
        div.onclick = function() {
            //点击 div 切换到日间模式和夜间模式
            if(div.className == 'dark'){
                div.className = 'light';
            }else{
                div.className = 'dark';
            }
        }
	</script>
上述这些操作都是针对当前页面已有的元素展开的。
操作节点
新增元素
1.创建一个元素
在 JS 里提供了 createElement 来创建元素。
2.把这个元素加到 DOM 树里
<div class="one">
        这是一个 div
</div>
<script>
    let input = document.createElement('input');
    //让输入框里默认显示'hello'
    input.value = 'hello';
    let div = document.querySelector('.one');
    div.appendChild(input);
</script>
//新增一个输入框
<ul>
        <li>11</li>
        <li>22</li>
</ul>
<script>
    let ul = document.querySelector('ul');
    for (let n = 3; n < 10; n++){
        let li = document.createElement('li');
        li.innerHTML = n + '' + n;
        ul.appendChild(li);//
    }
</script>
//往无序列表尾增元素
appendChild//加到子元素末尾
insertBefore//把元素加到指定子元素前面
删除元素
parentElem.removeChild(childElem);
//删除 33 这个元素
let toDelete = document.querySelectorAll('li')[2];
console.log(toDelete);
ul.removeChild(toDelete);
代码案例:猜数字
网页版本猜数字
1.生成一个 1-100 之间的随机整数
2.让用户来输入一个数字
3.根据输入数字的大小关系,给出提示:高了/低了/猜对了
<!DOCTYPE html>
<html lang="en">
<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>
    <div>请输入要猜的数字</div>
    <input type="text">
    <button>提交</button>
    <!-- 使用这个 div 来显示结果 -->
    <div class="result">
    </div>
    <script>
        //1.先生成一个随机1-100的整数
        let toGuess = parseInt(100 * Math.random()) + 1;
        console.log(toGuess);
        //2.进行猜数字操作
        let button = document.querySelector('button');
        let resultDiv = document.querySelector('.result');
        let input = document.querySelector('input');
        button.onclick = function() {
            //3.取出输入框的内容
            if(input.value == ''){
                // 用户啥都没输入
                return;
            }
            let inputNum = parseInt(input.value);
            //4.比较大小关系
            if(inputNum < toGuess){
                // 低了
                resultDiv.innerHTML = '低了';
            }else if(inputNum > toGuess){
                // 高了
                resultDiv.innerHTML = '高了';
            }else{
                // 猜对了
                resultDiv.innerHTML = '猜对了';
            }
        }
    </script>
</body>
</html>

代码案例:表白墙


<!DOCTYPE html>
<html lang="en">
<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>
    <style>
        /*  * 是通配符选择器,选中页面所有元素 */
        * {
            /* 消除浏览器的默认样式 */
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        .container {
            width: 600px;
            margin: 20px auto;
            /* 水平方向左右外边距是 auto, 垂直方向上是 0 */
        }
        h1 {
            text-align: center;
        }
        p {
            text-align: center;
            color: #666;
            margin: 20px 0;
        }
        .row {
            /* 开启弹性布局 */
            display: flex;
            height: 40px;
            /* 水平居中 */
            justify-content: center;
            /* 垂直居中 */
            align-items: center;
        }
        .row span {
            width: 80px;
        }
        .row input {
            width: 200px;
            height: 30px;
        }
        .row button {
            width: 280px;
            height: 30px;
            color: white;
            background-color: orange;
            /* 去掉边框 */
            border: none;
            border-radius: 5px;
        }
        .row button:active {
            background-color: grey;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>表白墙</h1>
        <p>输入内容后点击提交, 信息会显示到下方表格中</p>
        <div class="row">
            <span>谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>对谁: </span>
            <input type="text">
        </div>
        <div class="row">
            <span>说: </span>
            <input type="text">
        </div>
        <div class="row">
            <button id="submit">提交</button>
        </div>
        <div class="row">
            <button id="revert">撤销</button>
        </div>
        <!-- <div class="row">
            xx 对 xx 说 xxxxx
        </div> -->
    </div>
    <script>
        // 实现提交操作, 点击提交按钮, 把用户输入的内容提交到页面显示
        // 点击的时候获取到 3 个输入框的内容
        // 创建一个新的 div.row, 把内容构造到这个 div 即可
        let containerDiv = document.querySelector('.container');
        let inputs = document.querySelectorAll('input');
        let button = document.querySelector('#submit');
        button.onclick = function() {
            //1.获取到 3 个输入框的内容
            let from = inputs[0].value;
            let to = inputs[1].value;
            let msg = inputs[2].value;
            if(from == '' || to == '' || msg == '') {
                return;
            }
            //2.构造一个新的 div
            let rowDiv = document.createElement('div');
            rowDiv.className = 'row message';
            rowDiv.innerHTML = from + ' 对 ' + to + ' 说: ' + msg;
            containerDiv.appendChild(rowDiv);
            for(let input of inputs){
                input.value = '';
            }
        }
        let revertButton = document.querySelector("#revert");
        revertButton.onclick = function() {
            //删除最后 1 条消息
            //选中所有的 row, 找出最后一条 row 然后删掉
            let rows = document.querySelectorAll('.message');
            if(rows == null || rows.length == 0){
                return;
            }
            containerDiv.removeChild(rows[rows.length - 1]);
        }
    </script>
</body>
</html>
实现功能 :
提交一次后清空三个输入框。
三个输入框其中有一个为空就无法提交。
撤回一条消息。
(此处有 bug,多按几次撤销,撤销按钮也会被删除)



















