应用编程接口 (API) 是编程语言中提供的结构,允许开发者更轻松地创建复杂的功能。、
webapi 是一套 操作网页内容(DOM) 与 浏览器窗口(BOM) 的对象
Js由ECMAScript、DOM、BOM三个部分组成。
零、前言
0.1 变量声明
-
排除
var
:var
是早期的 JavaScript 变量声明方式,但由于其作用域问题(如函数作用域、变量提升)以及在大规模应用中容易导致意外行为,现代开发中通常不再使用。
-
优先使用
const
:建议数组和对象使用 const 来声明
-
const
声明的变量必需初始化赋值且不能再重新赋值,因此在语义上更清晰,表示这个变量的值不会改变。 -
尽管
const
声明的值不能更改,但对于引用数据类型(如对象、数组等),const
声明的变量存储的是引用的地址,而不是具体的值。这意味着你可以修改引用数据类型的内容,但不能重新赋值为其他引用。 -
在现代开发中,尤其是在使用如 React 这样的框架时,
const
是最常用的声明方式,因为很多状态和常量一经初始化就不会改变。
-
// 代码01:尝试重新定义const声明的对象,这会导致错误
const obj = { name: "张三" };
obj = { name: "李四" }; // 错误:TypeError: Assignment to constant variable.
// 代码02:在const声明的对象上添加新属性,这是允许的
const obj2 = { name: "张三" };
obj2.uname = "李四"; // 正确:在obj2对象上添加了一个新属性uname
在JavaScript中,对象的属性可以在对象创建后任何时间被添加或修改。这是因为JavaScript的对象是动态的,可以随时扩展或更改其结构。
*
代码01尝试重新定义一个已经声明为const
的对象obj
。这是不允许的,因为const
声明的变量不能被重新赋值。这里的错误是尝试将obj
重新赋值为一个新的对象字面量,这违反了const
的规则。
*
代码示例则是在已经存在的对象obj
上添加一个新的属性uname
。这是允许的,因为虽然obj
是用const
声明的,但我们只是在修改对象的内容,而不是尝试改变obj
变量的引用地址。const
只保证变量的引用不变,不保证其内容不变。
*
因此,右边的代码是有效的,而左边的代码会导致一个错误。
-
在必要时使用
let
:如果基本数据类型的值或者引用类型的地址发生变化的时候,需要用let
- 如果你需要声明一个会被重新赋值的变量,应该使用
let
。let
有块级作用域,这样可以避免一些var
可能带来的问题。 - 开发时可以先尝试使用
const
,如果后续发现变量需要改变,再将其改为let
。
- 如果你需要声明一个会被重新赋值的变量,应该使用
总结建议:
- 优先使用
const
:在确定变量不会被重新赋值的情况下,直接使用const
。 - 如果需要重新赋值:在发现需要改变变量的值时,将其改为
let
。
壹、WebAPI的认识
1.1 作用
操作html和浏览器
DOM(文档对象模型): 表示 HTML 文档的结构。
BOM(浏览器对象模型): 处理浏览器相关的对象,使得与浏览器进行交互成为可能。
1.2 什么是DOM
DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API,是一种与浏览器、平台、语言无关的接口,是用户可以访问页面其他的组件。
使得Web开发人员,方便的访问站中的数据,脚本,表现层的对象的内容。
我们可以拥有下面这样的节点图
文档树直观的体现了标签与标签之间的关系
1.3 什么是DOM对象
浏览器根据html标签生成的 JS对象(DOM对象),把内容当作对象处理
document是 DOM 里提供的一个对象,网页所有内容都在document里面
DOM(Document Object Model,文档对象模型)对象是一个用于表示和操作HTML或XML文档的编程接口。它将文档表示为一个由节点组成的树形结构,每个节点代表文档中的一个部分,例如元素、属性、文本等。通过DOM,程序可以动态地访问和修改页面内容、结构和样式。
主要概念:
-
节点:DOM树的基本组成单位,分为不同类型的节点,如元素节点、文本节点和属性节点。
- 元素节点:代表HTML或XML文档中的标签(如
<div>
、<p>
)。 - 文本节点:代表元素或属性中的文本内容。
- 属性节点:代表元素的属性(如
class
、id
)。
- 元素节点:代表HTML或XML文档中的标签(如
-
DOM树:文档的结构化表示,根节点通常是文档本身,下面是其子节点,形成一个树状结构。
-
节点操作:
- 创建:使用
document.createElement()
、document.createTextNode()
等方法创建新节点。 - 插入:使用
appendChild()
、insertBefore()
等方法将新节点插入到DOM树中。 - 删除:使用
removeChild()
删除节点。 - 修改:通过修改节点的属性、文本内容或样式来更新页面内容。
- 创建:使用
-
访问和操作:
- 选择节点:通过
document.getElementById()
、document.querySelector()
等方法选择节点。 - 修改内容:使用
.innerHTML
、.textContent
等属性修改节点内容。 - 修改样式:通过
element.style
修改节点的样式。
- 选择节点:通过
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM 操作示例</title>
<style>
#myElement {
color: blue;
font-size: 20px;
}
#newElement {
color: green;
font-size: 16px;
}
</style>
</head>
<body>
<div id="myElement">这是一个示例元素。</div>
</body>
</html>
<script>
// 获取ID为'myElement'的元素
let element = document.getElementById('myElement');
// 修改文本内容
element.textContent = '新内容: 这个元素的内容已经被修改了!';
// 修改元素样式
element.style.color = 'red'; // 更改字体颜色为红色
element.style.fontSize = '24px'; // 更改字体大小为24px
// 创建新的段落元素
let newElement = document.createElement('p');
newElement.id = 'newElement'; // 给新元素指定ID
newElement.textContent = '这是新创建的段落。';
// 修改新元素的样式
newElement.style.color = 'green'; // 设置字体颜色为绿色
newElement.style.fontSize = '16px'; // 设置字体大小为16px
// 将新元素插入到页面中
document.body.appendChild(newElement);
</script>
DOM是与JavaScript交互的桥梁,允许开发者动态更新页面内容,使得Web应用程序可以更具互动性和响应能力。
二、获取DOM对象
2.1 根据CSS选择器获取DOM元素
querySelector
和 querySelectorAll
是两种非常强大的JavaScript方法,用于选择DOM中的元素。它们使用CSS选择器语法,允许你通过复杂的选择器模式找到页面上的元素。
2.1.1 querySelector
-
功能:
querySelector
返回文档中与指定CSS选择器匹配的第一个元素。如果找到了符合条件的元素,它将返回该元素;如果没有找到,则返回null
。 -
使用场景: 当你只需要找到第一个匹配的元素时,使用
querySelector
。 -
语法:
var element = document.querySelector("cssSelector");
-
返回值:
querySelector
返回与指定CSS选择器匹配的第一个元素。- 如果找到了匹配的元素,返回该 单个元素的引用(
Element
对象)。 - 如果没有找到匹配的元素,返回
null
。
-
示例:
var element = document.querySelector(".example"); console.log(element); // 如果存在匹配元素,输出该元素;如果没有匹配,输出 null。
-
示例:
// 获取页面中第一个类名为 'header' 的元素 var header = document.querySelector(".header"); // 获取页面中第一个 id 为 'main' 的元素 var main = document.querySelector("#main"); // 获取页面中第一个 <p> 元素 var paragraph = document.querySelector("p"); // 获取页面中第一个属性为 'data-role="admin"' 的元素 var adminElement = document.querySelector('[data-role="admin"]');
2.1.2 querySelectorAll
-
功能:
querySelectorAll
返回文档中与指定CSS选择器匹配的所有元素的一个静态NodeList
(类数组对象)。如果找到了符合条件的元素,它将返回一个包含所有匹配元素的NodeList
;如果没有找到,则返回一个空的NodeList
。 -
使用场景: 当你需要找到所有匹配的元素时,使用
querySelectorAll
。 -
语法:
var elements = document.querySelectorAll("cssSelector");
-
返回值:
querySelectorAll
返回与指定CSS选择器匹配的所有元素的一个静态NodeList
(类似数组的对象)。- 如果找到了匹配的元素,返回一个
NodeList
,其中包含了所有匹配的元素。 - 如果没有找到匹配的元素,返回一个空的
NodeList
,即长度为0。
-
示例:
var elements = document.querySelectorAll(".example"); console.log(elements); // 输出一个 NodeList 对象,如果没有匹配元素,则输出一个空的 NodeList。
-
示例:
// 获取页面中所有类名为 'header' 的元素 var headers = document.querySelectorAll(".header"); // 获取页面中所有 <p> 元素 var paragraphs = document.querySelectorAll("p"); // 获取页面中所有属性为 'data-role="admin"' 的元素 var adminElements = document.querySelectorAll('[data-role="admin"]'); // 遍历所有匹配的元素 headers.forEach(function(header) { console.log(header.textContent); });
2.1.3 区别与相似点
- 返回值:
querySelector
返回第一个匹配的单个元素。querySelectorAll
返回所有匹配元素的NodeList
,即使只有一个元素匹配,也会返回一个长度为1的NodeList
。
Element
对象(querySelector
返回的):这是一个代表HTML元素的对象,它允许你访问和操作该元素的属性和方法。
NodeList
对象(querySelectorAll
返回的):这是一个类数组对象,包含了文档中所有与选择器匹配的元素。它可以通过索引访问元素,类似数组,可以使用forEach
或
for...of
进行遍历,但它不是一个真正的数组(尽管可以通过Array.from()
方法将其转换为数组)。
-
选择器:
- 二者都使用相同的CSS选择器语法,如类选择器(
.class
)、ID选择器(#id
)、属性选择器([attribute="value"]
)等。
- 二者都使用相同的CSS选择器语法,如类选择器(
-
遍历:
querySelectorAll
返回的NodeList
是静态的,可以使用forEach
、for...of
循环或标准的索引来遍历。
示例对比
// querySelector 示例
var firstDiv = document.querySelector("div");
console.log(firstDiv); // 返回文档中第一个 <div> 元素,或 null(如果不存在)
// querySelectorAll 示例
var allDivs = document.querySelectorAll("div");
console.log(allDivs); // 返回包含所有 <div> 元素的 NodeList,或空的 NodeList(如果没有匹配元素)
// 访问 NodeList 中的元素
if (allDivs.length > 0) {
console.log(allDivs[0]); // 访问第一个 <div> 元素
}
2.1.4 实际应用
querySelector
非常适合用于快速获取页面中的单个元素,例如获取页面中的第一个表单、按钮或图片。querySelectorAll
更适合用于处理多个元素的集合,例如对页面中的所有列表项进行操作,或获取所有符合特定条件的元素。
2.2 其他获取DOM元素方法、要获取DOM对象,可以使用以下几种常见的JavaScript方法:
1. 使用 getElementById
通过元素的 id
属性来获取DOM对象。这是最常用的方法之一,因为 id
是唯一的。
var element = document.getElementById("elementId");
2. 使用 getElementsByClassName
通过元素的 class
属性获取DOM对象。这个方法返回的是一个类数组对象(HTMLCollection),即使只有一个元素符合条件。
var elements = document.getElementsByClassName("className");
3. 使用 getElementsByTagName
通过元素的标签名获取DOM对象。这个方法也返回一个类数组对象(HTMLCollection)。
var elements = document.getElementsByTagName("tagName");
4. 直接从 document
或 window
对象
一些全局的DOM对象可以直接从 document
或 window
对象中获取,例如 document.body
或 window.document
。
var body = document.body;
var head = document.head;
选择的方法取决于你需要获取的元素的特性(如 id
、class
、tag
)以及是否需要获取单个元素或多个元素。
三、操作元素
在JavaScript中,你可以通过多种方式操作DOM元素的内容。这些操作主要包括修改元素的文本内容、HTML内容、属性和样式等。以下是常见的方法:
3.1 操作内容
1. 修改元素的文本内容
-
textContent
:- 该属性用于获取或设置元素的纯文本内容。它会将元素中的所有文本(包括子元素中的文本)作为一个字符串返回或设置。
- 示例:
var element = document.querySelector("#myElement"); // 获取文本内容 var text = element.textContent; console.log(text); // 设置文本内容 element.textContent = "This is the new text content.";
-
innerText
:- 与
textContent
类似,但innerText
会考虑CSS样式,显示的内容与页面呈现的文本一致,并且会触发重绘(reflow)。 - 示例:
var element = document.querySelector("#myElement"); element.innerText = "This is the new innerText content.";
- 与
2. 修改元素的HTML内容
innerHTML
:- 该属性用于获取或设置元素的HTML内容。它不仅可以包含文本,还可以包含HTML标签和嵌套元素。
- 示例:
var element = document.querySelector("#myElement"); // 获取HTML内容 var htmlContent = element.innerHTML; console.log(htmlContent); // 设置HTML内容 element.innerHTML = "<strong>This is bold text</strong> and <em>this is italic text</em>.";
3. 区别
直接选择使用innerHTML
Ø 元素.innerText 属性 只识别文本,不能解析标签
Ø 元素.innerHTML 属性 能识别文本,能够解析标签
innerHTML
和 innerText
是两个常见的 DOM 属性,用于获取或设置 HTML 元素的内容,它们之间有一些关键区别:
-
内容类型:
innerHTML
: 包含 HTML 标签在内的整个元素内容。当你使用innerHTML
读取或设置内容时,HTML 标签也会被包含在内。例如,<div>
元素中的<span>
、<a>
等标签都将被解析和呈现。innerText
: 仅包含元素的纯文本内容,忽略所有 HTML 标签。当你使用innerText
读取或设置内容时,所有 HTML 标签都会被忽略或被视为文本的一部分。
-
性能:
innerHTML
: 由于需要解析和构建 HTML 内容,因此在处理复杂或大量内容时可能较慢。使用innerHTML
修改内容会导致页面的重新渲染,特别是当包含大量或复杂的 HTML 结构时。innerText
: 只处理文本,因此相对来说速度更快。innerText
在修改文本内容时不会重新解析 HTML 标签,适合处理简单的文本操作。
-
安全性:
innerHTML
: 因为它允许插入 HTML 内容,因此有可能导致 XSS(跨站脚本攻击)。需要特别小心,尤其是在插入用户输入的内容时,必须进行转义或消毒处理。innerText
: 不会解析或执行任何 HTML 或脚本,因此较为安全。如果你只需要处理文本内容而不涉及 HTML 结构,使用innerText
更为安全。
-
浏览器行为:
innerHTML
: 在不同浏览器中表现一致,用于获取和设置元素的 HTML 结构和内容。innerText
: 在早期浏览器中(特别是 Internet Explorer),可能表现不一致,但现代浏览器已经解决了大多数兼容性问题。
示例:
<div id="example"><span>Hello</span> World!</div>
-
使用
innerHTML
:document.getElementById("example").innerHTML; // 返回 "<span>Hello</span> World!"
-
使用
innerText
:document.getElementById("example").innerText; // 返回 "Hello World!"
综上所述,innerHTML
更适合用于处理包含 HTML 结构的内容,而 innerText
更适合用于处理纯文本内容。
3.2 操作元素的属性
3.2.1 操作元素的属性
-
getAttribute
和setAttribute
:-
使用
getAttribute
获取元素的特定属性值。getAttribute(attributeName): 返回元素中指定属性的值。如果属性不存在,则返回 null。
-
使用
setAttribute
设置元素的特定属性值。
setAttribute(attributeName, value): 将指定属性设置为新的值。如果属性不存在,则会创建它。 -
示例:
var element = document.querySelector("#myElement"); // 获取属性值 var srcValue = element.getAttribute("src"); console.log(srcValue); // 设置属性值 element.setAttribute("src", "newImage.png");
-
-
removeAttribute
:- 该方法用于移除元素的某个属性。
- 示例:
var element = document.querySelector("#myElement"); element.removeAttribute("title");
3.2.2 操作元素的样式
-
直接操作
style
属性:- 你可以直接通过
style
属性设置元素的内联样式。 - 示例:
var element = document.querySelector("#myElement"); element.style.color = "red"; // 改变文本颜色 element.style.fontSize = "20px"; // 改变字体大小
- 你可以直接通过
-
添加或移除
class
:- 通过
classList
属性,可以添加、移除、切换CSS类,或检查元素是否包含某个CSS类。 - 示例:
var element = document.querySelector("#myElement"); // 添加一个类 element.classList.add("newClass"); // 移除一个类 element.classList.remove("oldClass"); // 切换一个类(如果存在则移除,如果不存在则添加) element.classList.toggle("toggleClass"); // 检查是否包含某个类 if (element.classList.contains("specificClass")) { console.log("Element contains 'specificClass'"); }
- 通过
3.2.3 自定义属性
自定义属性(Custom Attributes)是指在 HTML 元素上定义的用户自定义属性,通常以 data-
前缀开始。使用自定义属性可以方便地在 HTML 元素上存储与页面或应用程序相关的数据。
1.自定义属性的用法
-
定义自定义属性:
自定义属性通常以data-
开头,后跟自定义的属性名称。例如,data-user-id
、data-role
等。 -
获取自定义属性的值:
可以使用 JavaScript 的getAttribute
方法来获取自定义属性的值,或者使用dataset
属性。 -
设置自定义属性的值:
可以使用setAttribute
方法来设置自定义属性的值,或者通过dataset
属性直接操作。
2.示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Attribute Example</title>
</head>
<body>
<button id="userButton" data-user-id="12345" data-role="admin">User Button</button>
<script>
// 获取按钮元素
var button = document.getElementById("userButton");
// 使用 getAttribute 获取自定义属性
var userId = button.getAttribute("data-user-id");
console.log("User ID:", userId); // 输出: User ID: 12345
// 使用 dataset 获取自定义属性
var role = button.dataset.role;
console.log("User Role:", role); // 输出: User Role: admin
// 设置自定义属性
button.setAttribute("data-user-id", "67890");
console.log("New User ID:", button.getAttribute("data-user-id")); // 输出: New User ID: 67890
// 通过 dataset 设置自定义属性
button.dataset.role = "editor";
console.log("New User Role:", button.dataset.role); // 输出: New User Role: editor
</script>
</body>
</html>
3.说明
-
data-
前缀:- 所有自定义属性都应以
data-
开头,这是 HTML5 规范中的要求。这样可以确保自定义属性与标准的 HTML 属性(如id
、class
等)不冲突。
- 所有自定义属性都应以
-
dataset
对象:dataset
是一个特殊的 DOM 属性,它允许你直接访问元素的所有data-
属性。属性名会自动转换为驼峰命名法,例如data-user-id
可以通过element.dataset.userId
访问。
-
灵活性:
- 自定义属性非常适合在 HTML 元素中嵌入与 JavaScript 交互的相关数据,例如用户 ID、状态标识符等。
通过自定义属性,你可以在不影响元素本身行为的情况下,存储和传递额外的数据。这在构建复杂的前端应用时非常有用。
3.3 操作子元素
-
appendChild
:- 用于在元素的末尾添加一个子元素。
- 示例:
var parentElement = document.querySelector("#parent"); var newElement = document.createElement("div"); newElement.textContent = "I am a new child!"; parentElement.appendChild(newElement);
-
removeChild
:- 用于移除元素中的某个子元素。
- 示例:
var parentElement = document.querySelector("#parent"); var childElement = document.querySelector("#child"); parentElement.removeChild(childElement);
-
replaceChild
:- 用于替换一个子元素。
- 示例:
var parentElement = document.querySelector("#parent"); var newElement = document.createElement("div"); newElement.textContent = "I am the replacement!"; var oldElement = document.querySelector("#oldChild"); parentElement.replaceChild(newElement, oldElement);
通过这些方法,你可以灵活地操作DOM中的任何元素,修改其内容、样式和结构。
四、定时器-间歇函数
在 JavaScript 中,间歇函数(Interval Function)是通过 setInterval()
方法实现的。setInterval()
方法会在指定的时间间隔(以毫秒为单位)内反复执行指定的代码或函数,直到使用 clearInterval()
方法手动停止它。
setInterval()
的用法
语法:
setInterval(function, delay, arg1, arg2, ...)
function
: 要重复执行的函数。delay
: 每次执行之间的时间间隔,以毫秒为单位。arg1, arg2, ...
: 传递给函数的参数(可选)。
示例代码
以下是一个简单的示例,在控制台中每隔 1 秒(1000 毫秒)打印一次当前时间:
// 定义一个函数,用于显示当前时间
function showTime() {
let date = new Date();
let time = date.toLocaleTimeString();
console.log(time);
}
// 每隔 1 秒执行一次 showTime 函数
let timerId = setInterval(showTime, 1000);
停止间歇函数
要停止 setInterval()
设置的间歇执行,可以使用 clearInterval()
方法。你需要传递 setInterval()
返回的定时器 ID 给 clearInterval()
,以终止间歇函数的执行。
// 停止间歇函数
clearInterval(timerId);
完整示例
下面的代码示例展示了如何使用 setInterval()
和 clearInterval()
。每隔 1 秒打印一次时间,并在 5 秒后停止打印。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>setInterval Example</title>
</head>
<body>
<script>
// 定义一个函数,用于显示当前时间
function showTime() {
let date = new Date();
let time = date.toLocaleTimeString();
console.log(time);
}
// 每隔 1 秒执行一次 showTime 函数
let timerId = setInterval(showTime, 1000);
// 5 秒后停止间歇函数
setTimeout(function() {
clearInterval(timerId);
console.log("Timer stopped.");
}, 5000);
</script>
</body>
</html>
说明
setInterval()
会在页面的整个生命周期中持续运行,直到手动停止或页面被关闭。- 使用
clearInterval()
可以避免不必要的资源消耗和潜在的内存泄漏。 - 可以根据需要调整时间间隔(
delay
参数)来控制函数执行的频率。
通过间歇函数,可以实现如轮询、定时更新 UI 等功能。在使用时,注意合理管理定时器,避免造成性能问题。