JavaScript进阶

简介: 在上一篇文章【JavaScript简识】中介绍了关于JavaScript的基础语法知识,但只有基础语法知识是不够的,还需要操作页面,让页面动起来,更加丰富,本文就主要介绍能够操作页面元素的DOM API。

1.DOM树


一个页面的结构是一个树形结构,称为DOM树。


DOM树的树形结构形如:


微信图片_20230111153918.png

文档:一个页面就是一个文档,使用document表示

元素:页面中所有的标签都称为元素,使用element表示

节点:网页中所有的内容都可以称为节点,使用node表示。

这些概念在JS代码中就对应一个一个的对象。


2.常用DOM API


2.1 获取元素


要想操作页面上的元素,就需要先拿到对应的JS对象,DOM中提供了一组API能够获取到网页的元素,最常用的就是以下两个API。

querySelector

querySelectorAll

两者都是document的属性,通过页面document的属性和方法,来操作页面的内容。


用法:


let obj=document.querySelector("CSS选择器");

代码示例:


微信图片_20230111153914.png

当querySelector的参数匹配器,匹配到了多个元素的时候,此时返回的对象,就是匹配结果中的第一个元素。

像上图的情况,如果想要把所有的li都选中,就需要使用querySelectorAll,其返回的是一个数组,包含了所有被选中的元素。


微信图片_20230111153911.png

2.2 事件


事件就是浏览器对于用户的操作行为进行的一个统称,例如鼠标在页面上某个位置点击,就会产生一个鼠标点击事件;再例如鼠标滚轮来滚动页面,就会产生一组滚动事件…


JS的主要工作就是在不同的事件中,进行不同的处理。


事件的三个要素:


事件源:哪个HTML元素产生的事件

事件类型:鼠标移动,鼠标点击,键盘事件,窗口大小改变事件等

事件的处理程序:当事件产生之后,执行怎样的代码

下边我们就用代码来展示最为常见的点击事件:


微信图片_20230111153907.png

2.3 操作元素内容


操作元素需要先获取到元素,然后再进行修改,对元素进行修改,无非涉及到内容、属性、样式三个方面。


我们首先来看如何操作元素内容;


对元素内容的操作,我们主要通过Element.innerHTML属性设置或获取HTML语法表示的元素的后代。


语法规则:


//读操作
var content=element.innerHTML;
//写操作
element.innerHTML=htmlString;


代码练习:实现计数器


<div id="screen">0</div>
    <button id="plus">+</button>
    <script>
        let plusBtn=document.querySelector("#plus");
        plusBtn.onclick=function() {
            // 1.获取到screen里的值
            let screen=document.querySelector("#screen");
            let val=screen.innerHTML;
            // 获取到的值默认为string类型,需要转换成number类型
            val=parseInt(val);
            // 2.val++;
            val+=1;
            // 3.把新值写回去
            screen.innerHTML=val;
        }
    </script>


预览效果:


微信图片_20230111153902.gif

实现以上代码效果还可以利用input标签来完成,input作为一个单标签,并没有innerHTML属性,但是可以通过的value属性来获取到内部的内容,代码如下:


<input type="text" id="screen" value="0">
    <button id="plus">+</button>
    <script>
        let plusBtn=document.querySelector("#plus");
        plusBtn.onclick=function() {
            // 1.获取到screen里的值
            let screen=document.querySelector("#screen");
            let val=screen.value;
            // 获取到的值默认为string类型,需要转换成number类型
            val=parseInt(val);
            // 2.val++;
            val+=1;
            // 3.把新值写回去
            screen.value=val;
        }
    </script>


2.4 操作元素属性


可以通过Element对象的属性来直接进行修改,就能影响到页面显示效果。


代码示例:


<img src="1.jpg" alt="头像1" title="帅哥">
    <script>
        let img=document.querySelector('img');
        console.dir(img);
        // console.log(img.src);
        // console.log(img.title);
        // console.log(img.alt);
    </script>


通过console.dir这个方法,可以打印出一个dom对象的全部属性和值。

预览结果:


微信图片_20230111153857.png

代码练习:点击切换图片


<img src="1.jpg" alt="头像1" title="帅哥">
    <script>
        let img=document.querySelector('img');
        img.onclick=function() {
            console.dir(img);
            if(img.src.indexOf('1.jpg')>=0) {
                img.src='2.jpg';
            }else if(img.src.indexOf('2.jpg')>=0) {
                img.src='1.jpg';
            }
        }
    </script>


预览效果:


微信图片_20230111153849.gif

我们还可以操作表单元素属性:


表单(主要是指input标签)有以下属性:


value:input值

disabled:禁用

checked:复选框会使用

selected:下拉框会使用

type:input的类型(文本、密码、按钮、文件等)

代码练习:全选/取消全选按钮


微信图片_20230111153844.png

1.点击全选按钮,则选中所有选项

2.只要某个选项取消,则自动取消全选按钮的勾选状态。


<input type="checkbox" id="all">我全都要 <br>
    <input type="checkbox" class="girl">美杜莎 <br>
    <input type="checkbox" class="girl">云韵 <br>
    <input type="checkbox" class="girl">萧薰儿 <br>
    <input type="checkbox" class="girl">雅菲 <br>
    <script>
        // 1.获取到元素
        let all=document.querySelector('#all');
        let girls=document.querySelectorAll('.girl');
        // 2.给all注册点击事件,选中/取消所有选项
        all.onclick=function() {
            for(let i=0;i<girls.length;i++) {
                girls[i].checked=all.checked;
            }
        }
        // 3.给girl注册点击事件
        for(let i=0;i<girls.length;i++) {
            girls[i].onclick=function() {
                // 检测当前是不是所有的girl都被选中了
                all.checked=checkGirls(girls);
            }
        }
        // 4.实现checkGirls
        function checkGirls(girls) {
            for(let i=0;i<girls.length;i++) {
                if(!girls[i].checked) {
                    //只要有一个girl没被选中,就认为结果是false
                    return false;
                }
            }
            // 所有girl都被选中,就是全选中
            return true;
        }
    </script>


效果预览:


微信图片_20230111153839.gif

2.5 操作元素样式


操作元素样式本质上也是操作元素属性。

可以通过行内样式或者类名样式来完成操作。


行内样式示例:点击放大字体


element.style.[属性名] = [属性值];


<div style="font-size:20px">这是一个文本</div>
    <script>
        let div=document.querySelector('div');
        div.onclick=function() {
            // 1.先获取到当前字体大小
            console.log(parseInt(div.style.fontSize));
            let fontSize=parseInt(div.style.fontSize);
            fontSize+=5;
            div.style.fontSize=fontSize+'px';
        }
    </script>


效果预览:


微信图片_20230111153834.gif

类名样式示例:开启夜间模式


element.className = [CSS 类名];


class是JS的关键字,所以名字叫做className


点击关灯切换到夜间模式(背景变成黑色)

点击开灯恢复至日间模式(背景变成白色)


<style>
        .light {
            background-color: #fff;
            color: black;
        }
        .dark {
            background-color: #000;
            color: #fff;
        }
    </style>
    <div class="light" style="height:500px">这是一段话</div>
    <button>关灯</button>
    <script>
        let div=document.querySelector('div');
        let button=document.querySelector('button');
        button.onclick=function() {
            if(div.className=='light') {
                div.className='dark';
                button.innerHTML='关灯';
            }else if(div.className=='dark') {
                div.className='light';
                button.innerHTML='开灯';
            }
        }
    </script>


效果预览:


微信图片_20230111153829.gif

2.6 操作节点


2.6.1 新增节点


1.创建新元素节点


微信图片_20230111153826.png

此时该新节点并不能在页面中显示出来,需要在页面的父节点上插入该子结点才能将该新节点显示出来。


2.把元素节点插入到dom树中


微信图片_20230111153822.png

2.6.2 删除节点


利用页面父节点的removeChild方法删除节点


微信图片_20230111153817.png

3.综合案例


3.1 代码案例:猜数字


期待效果:


微信图片_20230111153814.png

<!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>Document</title>
</head>
<body>
    <button id="resetBtn">重新开始一局游戏</button><br>
    <span>要猜的数字:</span>
    <input type="text">
    <button id="guessBtn">猜</button><br>
    <span>结果:</span><span id="result"></span><br>
    <span>已经猜的次数:</span><span id="guessCount">0</span>
    <script>
        // 1.先把上面需要用到的元素拿到
        let resetBtn=document.querySelector('#resetBtn');
        let input=document.querySelector('input');
        let guessBtn=document.querySelector('#guessBtn');
        let resultSpan=document.querySelector('#result');
        let guessCountSpan=document.querySelector('#guessCount');
        // 2.生成一个1-100的随机整数
        let toGuess=Math.floor(Math.random()*100)+1;
        // Math.random()生成[0,1)的数字,乘以一百通过floor向下取整,加一得到[1,100]的随机数
        console.log(toGuess);
        // 3.点击实现猜的逻辑
        guessBtn.onclick=function() {
            // 1.读取到input中输入的内容,并转成整数
            if(input.value=='') {
                return;
            }
            let curNum=parseInt(input.value);
            // 2.判定大小关系,并给出提示
            if(curNum<toGuess) {
                resultSpan.innerHTML='低了';
                resultSpan.style.color='red';
            }else if(curNum>toGuess) {
                resultSpan.innerHTML='高了';
                resultSpan.style.color='red';
            }else {
                resultSpan.innerHTML='猜对了!';
                resultSpan.style.color='green';
            }
            // 3.更新猜的次数
            let guessCount=parseInt(guessCountSpan.innerHTML);
            guessCountSpan.innerHTML=guessCount+1;
        }
        // 4.实现reset操作的逻辑(开始新游戏)
        resetBtn.onclick=function() {
            // 让页面刷新即可
            location.reload();
        }
    </script>
</body>
</html>


效果预览:


微信图片_20230111153808.gif

3.2 代码案例:表白墙


期待效果:


微信图片_20230111153804.png

代码示例:


<!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>Document</title>
</head>
<body>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            background-color: rgb(30,100,200);
        }
        .container {
            width: 100%;
        }
        h3 {
            text-align: center;
            padding: 30px 0;
            font-size: 24px;
            color: rgb(255,140,10);
        }
        p {
            text-align: center;
            color: rgba(66, 37, 3, 0.637);
            font-size: 18px;
            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,10);
        }
        .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,240);
        }
    </style>
    <div class="container">
        <h3>表白墙</h3>
        <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>
    <script>
        // 当用户点击submit,就会获取到input中的内容,从而把内容构造成一个div,插入到页面末尾
        let submitBtn=document.querySelector('#submit');
        submitBtn.onclick=function() {
            // 1.获取到3个input中的内容
            let inputs=document.querySelectorAll('input');
            let from=inputs[0].value;
            let to=inputs[1].value;
            let msg=inputs[2].value;
            if(from==''||to==''||msg=='') {
                // 用户还没有提交完,暂时先不提交数据
                return;
            }
            // 2.生成一个新的div,内容是input里面的内容,把这个新的div加到页面中
            let div=document.createElement('div');
            div.innerHTML=from+'对'+to+'说:'+msg;
            div.className='row';
            let container=document.querySelector('.container');
            container.appendChild(div);
            //3.清空之前输入框内的内容
            for(let i=0;i<inputs.length;i++) {
                inputs[i].value='';
            }
        }
    </script>
</body>
</html>


效果预览:


微信图片_20230111153755.gif


相关文章
|
5月前
|
前端开发 JavaScript 开发者
JavaScript进阶-Promise与异步编程
【6月更文挑战第20天】JavaScript的Promise简化了异步操作,从ES6开始成为标准。Promise有三种状态:pending、fulfilled和rejected。基本用法涉及构造函数和`.then`处理结果,如: ```javascript new Promise((resolve, reject) =&gt; { setTimeout(resolve, 2000, &#39;成功&#39;); }).then(console.log); // 输出: 成功
86 4
|
5月前
|
存储 JavaScript 前端开发
JavaScript进阶-Map与Set集合
【6月更文挑战第20天】JavaScript的ES6引入了`Map`和`Set`,它们是高效处理集合数据的工具。`Map`允许任何类型的键,提供唯一键值对;`Set`存储唯一值。使用`Map`时,注意键可以非字符串,用`has`检查键存在。`Set`常用于数组去重,如`[...new Set(array)]`。了解它们的高级应用,如结构转换和高效查询,能提升代码质量。别忘了`WeakMap`用于弱引用键,防止内存泄漏。实践使用以加深理解。
74 3
|
4月前
|
XML 前端开发 JavaScript
JavaScript进阶 - AJAX请求与Fetch API
【7月更文挑战第3天】前端开发中的异步基石:AJAX与Fetch。AJAX,使用XMLHttpRequest,处理跨域、回调地狱和错误处理。Fetch,基于Promise,简化请求,但需注意默认无跨域头和HTTP错误处理。两者各有优劣,理解其问题与解决策略,能提升前端应用的性能和用户体验。
134 24
|
4月前
|
前端开发 JavaScript 安全
JavaScript进阶-JavaScript库与框架简介
【7月更文挑战第11天】JavaScript库和框架加速Web开发,但也带来挑战。选择适合项目、团队技能的库或框架,如React、Angular、Vue,是关键。保持依赖更新,注意性能优化,避免过度依赖。遵循最佳实践,确保安全性,如防XSS和CSRF。学习基础,结合代码示例(如React计数器组件),提升开发效率和应用质量。
56 1
|
4月前
|
缓存 JavaScript 前端开发
JavaScript进阶 - Web Workers与Service Worker
【7月更文挑战第4天】JavaScript的Web Workers和Service Worker增强了Web性能。Web Workers处理后台多线程,减轻主线程负担,但通信有开销,受同源策略限制。Service Worker则用于离线缓存和推送通知,需管理其生命周期、更新策略,并确保安全。两者都带来了挑战,但也极大提升了用户体验。通过理解和优化,开发者能构建更高效、安全的Web应用。
121 2
|
4月前
|
资源调度 JavaScript 前端开发
JavaScript进阶 - JavaScript库与框架简介
【7月更文挑战第5天】JavaScript库和框架构成了前端开发的核心,如jQuery简化DOM操作,Angular、React和Vue提供全面解决方案。选择时要明确需求,避免过度工程化和陡峭学习曲线。使用版本管理工具确保兼容性,持续学习以适应技术变化。示例展示了jQuery和React的简单应用。正确选择和使用这些工具,能提升开发效率并创造优秀Web应用。
47 2
|
4月前
|
设计模式 前端开发 JavaScript
JavaScript进阶 - JavaScript设计模式
【7月更文挑战第1天】JavaScript设计模式增进代码复用和维护性。单例模式确保唯一实例,用闭包防止命名冲突和控制状态访问。观察者模式实现一对多依赖,通过解绑避免内存泄漏。工厂模式封装对象创建,适度使用避免复杂度。装饰者模式动态添加行为,保持简洁以保可读性。理解模式的优缺点,灵活应用,提升代码质量。
128 3
|
4月前
|
存储 前端开发 安全
JavaScript进阶 - 浏览器存储:localStorage, sessionStorage, cookies
【7月更文挑战第2天】探索Web存储:localStorage持久化,sessionStorage会话限定,cookies则伴随HTTP请求。了解它们的特性和限制,如localStorage的5MB容量限制、跨域问题,sessionStorage的生命周期,及cookies的安全与带宽消耗。使用时需权衡安全、效率与应用场景。示例代码展示存储与检索方法。
254 2
|
5月前
|
JavaScript 前端开发
JavaScript进阶-Class与模块化编程
【6月更文挑战第21天】**ES6引入Class和模块化,提升JavaScript的代码组织和复用。Class是原型机制的语法糖,简化面向对象编程。模块化通过`import/export`管理代码,支持默认和命名导出。常见问题包括`this`指向和循环依赖。理解这些问题及避免策略,能助你写出更高效、可维护的代码。**
62 5
|
5月前
|
JavaScript 前端开发 开发者
JavaScript进阶-解构赋值与展开运算符
【6月更文挑战第19天】ES6的解构赋值与展开运算符增强了JS开发效率。解构允许直接从数组或对象提取值,简化数据提取,而展开运算符则用于合并数组和对象或作为函数参数。解构时注意设置默认值以处理不存在的属性,避免过度嵌套。展开运算符需区分数组与对象使用,勿混淆于剩余参数。通过示例展示了这两种操作在数组和对象中的应用,提升代码可读性与简洁度。
144 5