蓝旭前端05:JavaScript进阶
基础简单复习
数据类型
基本数据类型:Number、String、Boolean、Null、Undefined等。引用数据类型:Object、Array、Function等。typeof操作符:返回数据类型的字符串形式。变量
变量声明:var、let、const。区别:var没有块级作用域,let和const有块级作用域,const声明的变量不能修改。什么是块级作用域:{}。举例:
{    var a = 1    let b = 2    const c = 3}console.log(a) // 1console.log(b) // 报错console.log(c) // 报错  变量赋值:赋值操作符=。
变量命名:字母、数字、下划线、$,不能以数字开头。
变量作用域:全局作用域、局部作用域。
变量提升:变量声明会提升到作用域的最前面。
变量作用域链:内部作用域可以访问外部作用域的变量,反之不行。
运算符
算术运算符:+、-、*、/、%。赋值运算符:=、+=、-=、*=、/=、%=。比较运算符:==、!=、===、!==、>、<、>=、<=。逻辑运算符:&&、||、!。三元运算符:condition ? expr1 : expr2。 控制语句
if语句:if、else if、else。switch语句:switch、case、break、default。for循环:for、break、continue。while循环:while、do while。break语句:跳出循环。continue语句:跳过本次循环。return语句:返回值。JavaScript引入
<!DOCTYPE html><html><head>    <-- 为什么不推荐在head引入script:阻塞页面渲染 -->    <script src="script.js"></script>    <title>JavaScript引入</title></head><body>    <script>        // JavaScript代码    </script></body></html> JavaScript输出
console.log('Hello, World!') JavaScript注释
// 单行注释/* 多行注释 */ JavaScript弹窗
alert('Hello, World!') Overview
获取元素事件监听事件对象事件委托事件绑定事件解绑事件触发事件处理程序异步编程(回调函数、Promise、async/await)获取元素
通过ID获取元素
ID: 元素的id属性,是唯一的。
document.getElementById('id') 通过类名获取元素
class: 元素的class属性,可以有多个相同的类名。
document.getElementsByClassName('class') 多个类名之间用空格隔开,返回的是一个数组。
通过标签名获取元素
tag: 元素的标签名,如div、p、a等。
document.getElementsByTagName('tag') 通过选择器获取元素
selector: CSS选择器,如#id、.class、tag等。
document.querySelector('selector')document.querySelectorAll('selector')// 举例document.querySelector('#id')document.querySelectorAll('.class')document.querySelectorAll('tag') 区别:querySelector只返回第一个匹配的元素,querySelectorAll返回所有匹配的元素。
事件监听
事件监听
element.addEventListener(event, function, useCapture) 解释:event是事件的类型,function是事件触发时执行的函数,useCapture是一个布尔值,表示事件是否在捕获阶段执行。
事件类型:click、mouseover、mouseout、keydown、keyup等。事件处理函数:事件触发时执行的函数。捕获阶段:事件从最外层元素向内层元素传播的阶段。例如:点击一个按钮,事件会从document传播到按钮。事件监听的例子
举例:
document.getElementById('id').addEventListener('click', function() {    console.log('click')}, false) 解释:点击id为id的元素时,控制台输出click。这里false表示事件在冒泡阶段执行,若为true则表示事件在捕获阶段执行,默认是false(可不写)。
冒泡阶段和捕获阶段的执行顺序:先捕获再冒泡。
冒泡和捕获的例子:
<!DOCTYPE html><html><head>    <title>事件监听</title></head><body>    <div id="div">        <button id="btn">按钮</button>    </div>    <script>        document.getElementById('div').addEventListener('click', function() {            console.log('div')        }, false)        document.getElementById('btn').addEventListener('click', function() {            console.log('btn')        }, false)    </script></body></html> 点击按钮,控制台输出:
btndiv 解释:点击按钮,事件先在按钮上触发,再在div上触发。
 怎么阻止冒泡:使用event.stopPropagation()方法。
 例如:
document.getElementById('btn').addEventListener('click', function(event) {    console.log('btn')    event.stopPropagation()}, false) 这样点击按钮时,只会输出btn。
事件对象
事件对象
事件对象是事件触发时传递给事件处理函数的一个对象,包含了事件的相关信息。
element.addEventListener('event', function(event) {    // 事件对象}) 事件对象的属性:type、target、currentTarget、clientX、clientY等。事件对象的方法:preventDefault()、stopPropagation()等。事件对象的类型:click、mouseover、mouseout、keydown、keyup等。事件对象的坐标:事件触发时的坐标。 事件对象的例子
举例:
document.getElementById('id').addEventListener('click', function(event) {    console.log(event.type) // click    console.log(event.target) // 点击的元素    console.log(event.currentTarget) // 绑定事件的元素    console.log(event.clientX) // 鼠标点击的x坐标    console.log(event.clientY) // 鼠标点击的y坐标}, false) 事件委托
事件委托
事件委托是指将事件绑定到父元素上,通过事件对象的target属性判断事件源,从而执行对应的事件处理函数。
element.addEventListener('event', function(event) {    if (event.target.tagName === 'tag') {        // 事件处理函数    }}) 事件委托的优点:减少事件绑定,提高性能。事件委托的原理:事件冒泡。事件委托的应用:动态添加元素。 事件委托的例子
举例:
<!DOCTYPE html><html><head>    <title>事件委托</title></head><body>    <ul id="ul">        <li>1</li>        <li>2</li>        <li>3</li>    </ul>    <script>        document.getElementById('ul').addEventListener('click', function(event) {            // 为什么要判断tagName:防止事件源不是li,注意tagName是大写,这是一个坑,这个属于DOM的知识            // console.log(event.target.tagName)            if (event.target.tagName === 'LI') {                console.log(event.target.innerHTML)            }        }, false)    </script></body></html> 事件绑定
事件绑定
事件绑定是指将事件处理函数绑定到元素上,当事件触发时执行对应的事件处理函数。
element.addEventListener('event', function, useCapture) 事件绑定的优点:解耦,提高代码的可维护性。事件绑定的原理:事件监听。 事件绑定的例子
举例:
<!DOCTYPE html><html><head>    <title>事件绑定</title></head><body>    <button id="btn">按钮</button>    <script>        document.getElementById('btn').addEventListener('click', function() {            console.log('click')        }, false)    </script></body></html> 事件解绑
事件解绑
事件解绑是指将事件处理函数从元素上解绑,当事件不再触发时不执行对应的事件处理函数。
element.removeEventListener('event', function, useCapture) 事件解绑的优点:减少内存占用,提高性能。事件解绑的原理:事件监听。 事件解绑的例子
举例:
<!DOCTYPE html><html><head>    <title>事件解绑</title></head><body>    <button id="btn">按钮</button>    <script>        // 点击按钮一次后,再点击按钮,按钮的点击事件就会被解绑        var btn = document.getElementById('btn');        function clickHandler() {            console.log('click');            btn.removeEventListener('click', clickHandler);        }        btn.addEventListener('click', clickHandler);    </script></body></html> 事件触发
事件触发
事件触发是指手动触发元素上的事件,执行对应的事件处理函数。
element.dispatchEvent(event) 事件触发的应用:模拟用户操作。事件触发的原理:事件监听。 触发的类型:click、mouseover、mouseout、keydown、keyup等。
事件触发的例子
举例:
<!DOCTYPE html><html><head>    <title>事件触发</title></head><body>    <button id="btn">按钮</button>    <div id="clr">变化颜色</div>    <div id="keyon">现在没有按下</div>    <script>        var btn = document.getElementById('btn');        btn.addEventListener('click', function() {            console.log('click');        }, false);        // 手动触发按钮的点击事件        btn.dispatchEvent(new Event('click'));        var clr = document.getElementById('clr');        clr.addEventListener('mouseover', function() {            this.style.backgroundColor = 'red';        }, false);        // 手动触发div的mouseover事件        // clr.dispatchEvent(new Event('mouseover'));        var keyon = document.getElementById('keyon');        document.addEventListener('keydown', function() {            keyon.innerHTML = '按下了键盘';        }, false);        document.addEventListener('keyup', function() {            keyon.innerHTML = '现在没有按下';        }, false);        // 手动触发键盘事件        document.dispatchEvent(new KeyboardEvent('keydown', {            key: 'a'        }));    </script></body></html> 事件处理程序
事件处理程序
事件处理程序是指事件触发时执行的函数,用于处理事件。
事件处理程序的类型:内联事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序。事件处理程序的优点:解耦,提高代码的可维护性。内联事件处理程序
内联事件处理程序是指将事件处理函数直接写在元素的事件属性中。
<!DOCTYPE html><html><head>    <title>内联事件处理程序</title></head><body>    <button onclick="console.log('click')">按钮</button></body></html> 优点:简单、直观。缺点:不推荐使用,不利于代码的维护。 DOM0级事件处理程序
DOM0级事件处理程序是指将事件处理函数赋值给元素的事件属性。
<!DOCTYPE html><html><head>    <title>DOM0级事件处理程序</title></head><body>    <button id="btn">按钮</button>    <script>        document.getElementById('btn').onclick = function() {            console.log('click');        }    </script></body></html> 优点:简单、直观。缺点:同一事件只能绑定一个处理函数。注意:DOM0级事件处理程序会覆盖元素原有的事件处理函数。注意:DOM0级事件处理程序不支持事件委托、不支持事件解绑、不支持事件触发、不支持事件对象。注意:DOM0级事件处理程序不推荐使用,不利于代码的维护。 DOM2级事件处理程序
DOM2级事件处理程序是指使用addEventListener方法绑定事件处理函数。
<!DOCTYPE html><html><head>    <title>DOM2级事件处理程序</title></head><body>    <button id="btn">按钮</button>    <script>        document.getElementById('btn').addEventListener('click', function() {            console.log('click');        }, false)    </script></body></html> 优点:支持事件委托、支持事件解绑、支持事件触发、支持事件对象。注意:DOM2级事件处理程序不会覆盖元素原有的事件处理函数。注意:DOM2级事件处理程序推荐使用,提高代码的可维护性。注意:DOM2级事件处理程序的第三个参数useCapture是一个布尔值,表示事件是否在捕获阶段执行,默认是false(可不写)。 异步编程
异步编程
异步编程是指在程序执行过程中,不按照顺序执行,而是通过回调函数、Promise、async/await等方式实现异步执行。
异步编程的优点:提高程序的性能、提高用户体验。异步编程的原理:事件循环。异步编程的应用:Ajax、定时器、事件监听等。回调函数
回调函数是指将一个函数作为参数传递给另一个函数,当满足条件时执行回调函数。
function callback() {    console.log('callback')}function fn(callback) {    callback()}fn(callback) 回调函数的优点:解耦、提高代码的可维护性。回调函数的缺点:回调地狱、代码难以维护。回调函数的应用:Ajax、事件监听、定时器等。 举例
console.log('start')setTimeout(() => {    console.log('setTimeout')}, 0)console.log('end') 输出:
startendsetTimeout 解释:setTimeout是异步执行的,会等到同步执行完毕后再执行。
回调地狱:
setTimeout(() => {    console.log('1')    setTimeout(() => {        console.log('2')        setTimeout(() => {            console.log('3')        }, 1000)    }, 1000)}, 1000) 解决回调地狱的方法:Promise、async/await。
Promise
Promise是ES6新增的一种异步编程解决方案,用于处理异步操作。
new Promise((resolve, reject) => {    if (true) {        resolve('成功')    } else {        reject('失败')    }}).then((value) => {    console.log(value)}).catch((reason) => {    console.log(reason)}) Promise的状态:pending、fulfilled、rejected。Promise的方法:then、catch、finally。Promise的优点:解决回调地狱、提高代码的可维护性。Promise的缺点:无法取消、无法中途改变、无法多个一起执行。Promise的应用:Ajax、事件监听、定时器等。 async/await
async/await是ES8新增的一种异步编程解决方案,用于处理异步操作。
async function fn() {    try {        let value = await new Promise((resolve, reject) => {            if (true) {                resolve('成功')            } else {                reject('失败')            }        })        console.log(value)    } catch (reason) {        console.log(reason)    }}fn() async/await的优点:解决回调地狱、提高代码的可维护性。async/await的缺点:无法取消、无法中途改变、无法多个一起执行。async/await的应用:Ajax、事件监听、定时器等。 实践:猜数游戏
代码演示