JavaScript-DOM
JavaScript DOM 学习笔记
Page Visibility API 页面可见性API
JavaScript 中可通过 Page Visibility API 精确检测页面是否处于前台(用户可见)
visibilityState 页面可见状态
document.visibilityState
返回当前页面的可见状态
visible
页面内容至少部分可见(例如标签页在前台、窗口未被最小化)。hidden
页面内容对用户完全不可见(如标签页切换到后台、窗口最小化、屏幕锁定等)。
visibilitychange 页面可见状态变化事件
visibilitychange
事件:当页面可见状态变化时触发,例如用户切换标签页、最小化窗口等
js 代码示例:
// 监听可见性变化
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
console.log('页面处于前台'); // 用户正在查看当前页面
} else {
console.log('页面处于后台'); // 用户离开页面
}
});
// 直接获取当前状态
const isForeground = document.visibilityState === 'visible';
console.log(`当前是否前台: ${isForeground}`);
页面可见状态 visibilityState 与 窗口焦点状态 onfocus/onblur
假如有2块屏幕,网站页面在第二块屏幕的前台页面可看到,但鼠标在第一个屏幕上,那么 visibilityState 可见状态是什么?
答:visible
多显示器场景,如果页面所在的浏览器标签页处于激活状态(即该标签页是当前浏览器的前台标签),即使系统焦点在另一个显示器上,该页面仍然被认为是可见的,即 visibilityState === 'visible'
即使页面被其他窗口部分覆盖,只要浏览器窗口未被最小化且标签页在前台,visibilityState
状态仍为 visible
可见性状态 visibilityState
与 窗口焦点状态 window.onfocus/onblur
无关,只要页面是浏览器的激活页面 visibilityState
就是 visible
,无论窗口是否在焦点上。
window.onfocus = () => console.log("窗口聚焦(前台)");
window.onblur = () => console.log("窗口失焦(后台)");
实例:页面切换时暂停视频
const video = document.getElementById('myVideo');
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
video.pause(); // 离开页面时暂停
} else {
video.play(); // 返回页面时继续
}
});
requestIdleCallback 闲时回调 API
requestIdleCallback 是浏览器 JavaScript 的一个 API,允许开发者在浏览器空闲时期调度低优先级的任务,避免阻塞关键操作(如用户交互、动画渲染),从而提升页面性能与用户体验。
用途:执行非紧急的后台任务(如日志上报、数据分析、预加载资源),不影响用户感知的延迟(如点击响应、动画流畅度)。
实现原理:
- 浏览器在每一帧(通常 16ms/帧)中处理完高优先级任务后,若仍有空闲时间,则执行注册的 requestIdleCallback 回调。
- 若无空闲时间,回调会延迟到下一次空闲时段执行。
用法:
const requestId = requestIdleCallback(callback[, options]);
参数:
- callback:空闲时执行的函数,接收一个 IdleDeadline 对象作为参数。
- options(可选):
- timeout:指定回调超时时间(毫秒)。若超时后仍未空闲,浏览器会强制执行回调。
返回值:唯一 ID(用于 cancelIdleCallback 取消回调)。
- timeout:指定回调超时时间(毫秒)。若超时后仍未空闲,浏览器会强制执行回调。
Web Worker 工作者线程
Web Worker API
https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API
JavaScript 在浏览器中运行是单线程的
Worker 是浏览器提供的、在后台独立运行的 JavaScript 线程。由主页面(主脚本)创建和管理,但运行在完全隔离的环境中。
数据隔离:
- Worker 线程无法直接访问DOM,不能操作 document, window 等 DOM 元素
- Worker 线程有自己的独立内存空间(堆栈、全局作用域)
- Worker 线程不能访问主线程的全局变量或函数
- 在 Worker 内部,全局对象是 self 或 this,不再是 window
Worker 线程与主线程通信:
- 通过
postMessage(data)
方法发送数据 - 通过
onmessage
事件处理接收到的数据 - 传递的数据是副本(通常是深拷贝),但也支持可转移对象(性能更好)
通过 new Worker('script.js')
将单独的 .js
文件定义为 Worker
主线程 index.html 中创建 worker:
- 通过
worker.postMessage
给 Worker 发消息 - 通过
worker.onmessage
接收来自 Worker 的消息
Worker 线程 worker.js 中:
- 通过
self.onmessage
接收来自主线程的消息 - 通过
self.postMessage
给主线程发送消息
index.html 实现:
<!-- index.html -->
<button id="calculate">计算</button>
<script>
const worker = new Worker('worker.js'); // 创建Worker,加载worker.js
document.getElementById('calculate').addEventListener('click', () => {
worker.postMessage({ number: 1000000 }); // 发送消息给Worker
});
worker.onmessage = (e) => { // 监听Worker发回的消息
console.log('计算结果:', e.data.result);
};
// 监听错误
worker.onerror = (e) => console.error('Worker错误:', e);
</script>
worker.js 实现:
// worker.js
self.onmessage = (e) => { // 监听主线程发来的消息
const input = e.data.number;
let sum = 0;
// 模拟一个耗时的计算 (比如计算一个大数以内的所有质数)
for (let i = 0; i < input; i++) {
// ... 复杂计算 ...
sum += i; // 简化示例
}
// 计算完成,发送结果回主线程
self.postMessage({ result: sum });
};
MDN 的 Web Worker 示例
https://github.com/mdn/dom-examples/blob/main/web-workers/simple-web-worker/README.md
SharedWorker 多页面共享线程
SharedWorker 是 JavaScript 中 Web Workers 的一种特殊类型,允许多个浏览器上下文(如不同标签页、窗口 或 iframe)共享同一个后台线程。它解决了传统 Web Worker 无法跨页面共享的问题。
1、多页面共享
同一域名下的不同页面访问相同脚本路径时,共享同一个 Worker 实例。
2、基于端口的通信
通过 MessagePort 对象建立连接(每个连接对应一个独立的 port)。
3、独立生命周期
Worker 在所有连接关闭后自动终止,不受单个页面关闭影响。
4、线程安全通信
使用结构化克隆算法传输数据,确保线程安全。
Chrome 查看 SharedWorker 控制台
Chrome 地址栏输入 chrome://inspect 回车,进入开发者工具调试页面
找到 Shared Workers 点击 inspect 即可打开 SharedWorker 控制台
SharedWorker 中的网络请求自动携带同源 Cookie
从 SharedWorker 发起的 HTTP/WebSocket 网络请求,会自动携带同源主线程的 Cookie,包括 token 等 HttpOnly Cookie
但是 SharedWorker 线程里是不能直接 读/写 document.cookie 的
而且,在浏览器的 SharedWorker 控制台是看不到 Cookie 的
因为 SharedWorker 里没有 document,也没有可用的 document.cookie,控制台切到 SharedWorker 上下文也读不到任何 Cookie
创建 SharedWorker 实例
https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker
var myWorker = new SharedWorker(scriptURL);
var myWorker = new SharedWorker(scriptURL, name);
var myWorker = new SharedWorker(scriptURL, options);
参数:scriptURL
字符串,表示 worker js 脚本的URL,必须同源name
可选,SharedWorker 名称,可方便调试options
可选,额外属性
- type: 字符串,classic 或 module,默认是 classic
- name: 字符串,用于命名worker,可用于解决同一脚本不同worker实例的区分
- credentials: 字符串,凭据选项,可取值 ‘omit’, ‘same-origin’, ‘include’,默认值
omit
返回值:返回一个 SharedWorker
对象,包含以下重要属性:
port
一个MessagePort
对象,用于和 worker 进行通信。onerror
错误事件处理器。
不同页面如果使用相同的 scriptURL 和相同的 name(如果提供了),则会共享同一个 worker 实例。如果 name 不同,即使同一个脚本URL也会创建不同的 worker 实例
self.onconnect
在 Worker 线程内部,即 shared.js 脚本内,通过 self.onconnect
处理 主页面/主线程 的连接事件
事件对象为 MessageEvent
,其 ports 属性是一个数组,但通常只有一个端口,即事件对象的第一个端口 e.ports[0]
在 worker 线程内部,我们可以通过获取到的端口(port)来设置 onmessage 事件处理函数,进行双向通信。
MessagePort
https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
port.start()
开始接收消息。如果使用 addEventListener
来监听消息,则必须调用 start()
方法。如果使用 onmessage
则不需要。port.close()
关闭端口,断开与 worker 的连接。port.onmessage
设置消息事件处理函数(当 worker 通过该端口发送消息时触发)。port.onmessageerror
处理消息解析错误事件。
port.postMessage(message, transferList)
向 worker 发送消息。
message
要传递的数据,可以是任意结构化克隆算法支持的类型。transferList
可选,一个可转移对象的数组,如 ArrayBuffer 等。
通过 SharedWorker 在多页面间通信示例
SharedWorker 线程脚本 shared.js
// 保存所有页面的通信端口
const connectedPorts = [];
// 处理来自页面的连接请求
self.onconnect = (e) => {
// 从事件对象获取通信端口
const port = e.ports[0];
// 添加到连接列表
connectedPorts.push(port);
// 处理来自页面的消息
port.onmessage = (e) => {
const message = e.data;
// 广播消息给所有连接页面
broadcast({
type: message.type,
username: message.username,
text: message.text,
timestamp: new Date().toISOString()
});
};
// 发送欢迎消息
port.postMessage({
type: 'system',
text: '连接已建立!当前用户数: ' + connectedPorts.length
});
// 监听端口关闭
port.addEventListener('close', () => {
removePort(port);
});
};
// 广播消息给所有连接的页面
function broadcast(message) {
connectedPorts.forEach(port => {
port.postMessage(message);
});
}
// 移除断开连接的端口
function removePort(port) {
const index = connectedPorts.indexOf(port);
if (index !== -1) {
connectedPorts.splice(index, 1);
// 通知所有用户更新在线人数
broadcast({
type: 'system',
text: `用户已断开。当前用户数: ${connectedPorts.length}`
});
}
}
主页面/主线程 中的脚本:
<script>
// 1. 创建 SharedWorker
const worker = new SharedWorker('shared.js');
const port = worker.port;
// 2. 启动通信端口
port.start();
// 3. 接收来自 Worker 的消息
port.onmessage = (e) => {
const message = e.data;
displayMessage(message);
};
// 4. 发送消息
document.getElementById('sendBtn').addEventListener('click', () => {
const username = document.getElementById('username').value;
const text = document.getElementById('messageInput').value;
if (text.trim()) {
port.postMessage({
type: 'message',
username: username,
text: text
});
document.getElementById('messageInput').value = '';
}
});
// 5. 显示消息
function displayMessage(message) {
const messagesEl = document.getElementById('messages');
const messageEl = document.createElement('div');
messageEl.className = message.type === 'system' ?
'message system-message' : 'message';
messageEl.innerHTML = message.type === 'system' ?
`<em>${message.text}</em>` :
`<strong>${message.username}:</strong> ${message.text}`;
messagesEl.appendChild(messageEl);
messagesEl.scrollTop = messagesEl.scrollHeight;
}
// 6. 页面关闭时通知 Worker
window.addEventListener('beforeunload', () => {
port.postMessage({ type: 'close' });
});
</script>
window 对象(浏览器窗口)
Window
https://developer.mozilla.org/zh-CN/docs/Web/API/Window
所有浏览器对象的最顶层是 window
对象。它代表当前打开的浏览器窗口或标签页。window
对象表示一个包含 DOM 文档的窗口,其 document 属性指向窗口中载入的 DOM文档 。window
作为全局变量,代表了脚本正在运行的窗口,暴露给 Javascript 代码。
window
对象常用操作方法:window.innerWidth
浏览器窗口的宽度(不包含工具栏) console.log(window.innerWidth)window.innerHeight
浏览器窗口的高度(不包含工具栏) console.log(window.innerHeight)window.open()
打开新浏览器窗口 window.open(“https://example.com")window.close()
关闭当前窗口 window.close()window.scrollTo()
滚动到指定位置 window.scrollTo(0, 500)window.alert()
显示警告弹窗 window.alert(“警告信息”)window.setTimeout()
设置延迟执行的定时器 setTimeout(() => {}, 1000)window.setInterval()
设置周期性执行的定时器 setInterval(() => {}, 1000)
pageYOffset
= scrollY
文档在垂直方向已滚动的像素值,文档从顶部开始滚动过的像素值
pageYOffset 属性是 scrollY 属性的别名
为了跨浏览器兼容,请使用 window.pageYOffset 代替 window.scrollY
window.
可省略
在浏览器环境中,全局变量和函数实际上是被添加到 window
对象上的。window
对象是浏览器中的全局对象,代表了当前浏览器窗口。window
对象可以省略,如: alert()
等价于 window.alert()
document 对象
document 对象是 window 对象中最重要的二级对象,代表当前窗口加载的 HTML 文档
由于 window
对象可以省略,可以直接使用 document
对象,所以 window.document === document
// document 是 window 的属性
console.log(window.document === document); // true
// 实际用例
const title = document.title; // 获取页面标题
const bodyContent = document.body.innerHTML; // 获取 body 内容
const element = document.getElementById("myElement"); // 获取 DOM 元素
referrer 上一个页面url
document.referrer
返回 跳转或打开到当前页面 的页面的 URI
如果用户直接打开了这个页面(不是通过页面跳转,而是通过地址栏或者书签等打开的),则该属性为空字符串。
location 对象
Location 对象存储在 Window 对象的 Location 属性中,表示当前窗口中显示的文档的 Web 地址。
location 对象包含当前 URL 的信息并提供导航方法。
它的 href 属性存放的是文档的完整 URL,其他属性则分别描述了 URL 的各个部分。
当一个 Location 对象被转换成字符串,href 属性的值被返回。这意味着你可以使用表达式 location 来替代 location.href
Location
https://developer.mozilla.org/zh-CN/docs/Web/API/Location
主要属性 及 操作
console.log(window.location === location); // true
// location 的关键属性和方法
location.href; // 完整 URL
location.protocol; // http: 或 https:
location.host; // 主机名和端口
location.hostname; // 域名
location.pathname; // 路径部分
location.search; // 查询字符串 (?后部分)
location.hash; // 哈希部分 (#后部分)
location.reload(); // 重新加载当前页面
location.assign("https://new-url.com"); // 导航到新页面
location.replace("https://new-url.com"); // 替换当前页面
href 页面完整url
protocol 协议
包含URL对应协议的一个DOMString,最后有一个”:”。
host 域名:端口号
对于没有端口的页面, host 等于 hostname
对于带端口的页面, host 包括整个 域名:端口, hostname只包含域名
hostname 不带端口号的域名
port 端口号
pathname url的path
包含URL中路径部分的一个DOMString,开头有一个“/“
search url的查询串
包含URL参数的一个DOMString,开头有一个“?”
hash 页内锚点
包含块标识符的DOMString,开头有一个“#”
origin 源信息(只读)
包含页面来源的域名的标准形式
通过location获取当前页面的url等信息
window.location.protocol: http:
window.location.host: localhost:4000
window.location.hostname: localhost
window.location.origin: http://localhost:4000
window.location.pathname: /article/JavaScript/
window.location.href: http://localhost:4000/article/JavaScript/
window.location与document.location
window 对象的 location 属性 等于 document 对象的 location 属性, 都是引用了 location 对象
window.location === document.location //true
document.location===location // true
window.location===location // true
navigator 浏览器及操作系统
navigator 提供浏览器和操作系统的信息
console.log(navigator.userAgent);
// 示例输出: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
navigator.platform; // 操作系统平台
navigator.language; // 浏览器主语言
navigator.onLine; // 是否联网
navigator.geolocation; // 获取位置信息接口
// 实际应用:检测浏览器功能
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
console.log("地理定位不可用");
}
platform 操作系统
platform 属性是一个只读的字符串,声明了运行浏览器的操作系统和(或)硬件平台。
userAgent 用户代理
userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。
一般来讲,它是在 navigator.appCodeName 的值之后加上斜线和 navigator.appVersion 的值构成的。
例如 “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36”
注 用户代理头中也有个 user-agent header
screen 屏幕信息
screen.width; // 屏幕宽度(以像素为单位)
screen.height; // 屏幕高度
screen.availWidth; // 可用屏幕宽度(减去窗口装饰)
screen.availHeight; // 可用屏幕高度
screen.colorDepth; // 颜色深度(位)
screen.pixelDepth; // 像素深度(位)
// 应用场景:响应式设计
if (screen.width < 768) {
document.body.classList.add("mobile-layout");
}
console 控制台
console 提供浏览器控制台接口
console.log("日志消息");
console.error("错误消息");
console.warn("警告消息");
console.info("信息消息");
console.debug("调试消息");
console.group("分组标题");
console.log("组内消息");
console.groupEnd();
console.table([{name: "John", age: 30}, {name: "Jane", age: 25}]);
// 计时功能
console.time("timer");
// 执行一些操作...
console.timeEnd("timer"); // 显示执行时间
history 历史记录
history.length; // 历史记录中的条目数
history.state; // 当前历史记录的关联状态对象
history.back(); // 返回上一页
history.forward(); // 前进到下一页
history.go(-2); // 后退两页
// 添加历史记录并更改URL(不会实际加载页面)
history.pushState({page: "settings"}, "Settings", "/settings");
sessionStorage 会话存储
会话存储(标签页关闭时清除)
不同 源(Origin) 之间 sessionStorage 是隔离的,不同标签页之间也是隔离的。
sessionStorage.setItem("sessionId", "xyz123");
const id = sessionStorage.getItem("sessionId");
localStorage 持久化存储
持久性存储(关闭浏览器后仍然存在)
不同 源(Origin) 之间 localStorage 是隔离的。
// 保存数据
localStorage.setItem("username", "john_doe");
localStorage.setItem("preferences", JSON.stringify({theme: "dark"}));
// 读取数据
const username = localStorage.getItem("username");
const preferences = JSON.parse(localStorage.getItem("preferences"));
// 移除数据
localStorage.removeItem("username");
localStorage.clear(); // 清除所有
indexedDB 数据库
大型结构化数据存储
不同 源(Origin) 之间 indexedDB 是隔离的。
// 打开数据库
const request = indexedDB.open("myDatabase", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
const store = db.createObjectStore("users", {keyPath: "id"});
store.createIndex("email", "email", {unique: true});
};
request.onsuccess = (event) => {
const db = event.target.result;
// 添加数据
const transaction = db.transaction("users", "readwrite");
const store = transaction.objectStore("users");
store.add({id: 1, name: "John", email: "john@example.com"});
// 获取数据
const getRequest = store.get(1);
getRequest.onsuccess = () => {
console.log(getRequest.result);
};
};
DOM 操作
// 获取<html>元素,即 根元素
const root = document.documentElement;
// 获取<head>和<body>
const head = document.head;
const body = document.body;
// 获取所有<h1>元素
const headings = document.getElementsByTagName("h1");
// 使用CSS选择器查找元素
const element = document.querySelector("#container > .item");
// 遍历元素
const listItems = document.querySelectorAll("ul > li");
listItems.forEach(item => {
console.log(item.textContent);
});
// 动态修改DOM
const newDiv = document.createElement("div");
newDiv.textContent = "新添加的元素";
document.body.appendChild(newDiv);
const toRemove = document.getElementById("oldElement");
toRemove.parentNode.removeChild(toRemove);
scrollTop()
scrollTop() 方法设置或返回被选元素的【垂直滚动条位置】,即元素距离他容器顶部的像素距离
当滚动条位置位于最顶部时,位置是0;即当一个元素的容器没有产生垂直方向的滚动条,那它的 scrollTop 的值默认为0。
当滚动条位置位于最底部时,位置是元素的高度;
1.未设置时默认为0
2.为负值时不做任何响应
3.设置为超出本身最大值时,默认为最大值
scrollTop() 实现聊天窗口自动滚动
<div id="div-received-msg" class="div-received-msg"></div>
// 始终显示滚动条最底部
$("#div-received-msg").scrollTop($("#div-received-msg").prop("scrollHeight"));
其中 scrollHeight 是对象的高度,包含内边距,但不包括水平滚动条、边框和外边距。
scrollTop() 实现瀑布数据流加载
如果元素滚动到底,下面等式返回true,没有则返回false.
element.scrollHeight - element.scrollTop === element.clientHeight
JavaScript 获取 html 元素值
JavaScript 中取得元素的方法有4种:分别是:
- 1、
getElementById()
:通过id取得HTML元素。 - 2、
getElementsByName()
:通过name取得元素,是一个数组。 - 3、
getElementsByTagName()
:通过HTML标签取得元素,是一个数组。 - 4、
getElementsByClassName()
:根据类名获得元素,是一个数组
getElementById()
getElementById()
方法可返回对拥有指定 ID 的第一个对象的引用。
HTML DOM 定义了多种查找元素的方法,除了 getElementById() 之外,还有 getElementsByName() 和 getElementsByTagName()。
不过,如果您需要查找文档中的一个特定的元素,最有效的方法是 getElementById()。
在操作文档的一个特定的元素时,最好给该元素一个 id 属性,为它指定一个(在文档中)唯一的名称,然后就可以用该 ID 查找想要的元素。
例1,获取元素标签内的值
<html>
<head>
<script type="text/javascript">
function getValue()
{
var x=document.getElementById("myHeader")
alert(x.innerHTML)
}
</script>
</head>
<body>
<h1 id="myHeader" onclick="getValue()">This is a header</h1>
<p>Click on the header to alert its value</p>
</body>
</html>
例2,自定义id(x)方法
getElementById() 是一个重要的方法,在 DOM 程序设计中,它的使用非常常见。我们为您定义了一个工具函数,这样您就可以通过一个较短的名字来使用 getElementById() 方法了:
function id(x) {
if (typeof x == "string") return document.getElementById(x);
return x;
}
上面这个函数接受元素 ID 作为它们的参数。对于每个这样的参数,您只要在使用前编写 x = id(x) 就可以了。
getElementsByName()
getElementsByName()
方法可返回带有指定名称的对象的集合。
该方法与 getElementById() 方法相似,但是它查询元素的 name 属性,而不是 id 属性。
另外,因为一个文档中的 name 属性可能不唯一(如 HTML 表单中的单选按钮通常具有相同的 name 属性),所有 getElementsByName() 方法返回的是元素的数组,而不是一个元素。
例,统计文档内name为myInput的标签有多少个
<html>
<head>
<script type="text/javascript">
function getElements()
{
var x=document.getElementsByName("myInput");
alert(x.length);
}
</script>
</head>
<body>
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<br />
<input type="button" onclick="getElements()" value="名为 'myInput' 的元素有多少个?" />
</body>
</html>
getElementsByTagName()
getElementsByTagName()
方法可返回带有指定标签名的对象的集合。
getElementsByTagName() 方法返回元素的顺序是它们在文档中的顺序。
如果把特殊字符串 “*” 传递给 getElementsByTagName() 方法,它将返回文档中所有元素的列表,元素排列的顺序就是它们在文档中的顺序。
注意:传递给 getElementsByTagName() 方法的字符串可以不区分大小写。
例1,统计文档内有多少个input标签
<html>
<head>
<script type="text/javascript">
function getElements()
{
var x=document.getElementsByTagName("input");
alert(x.length);
}
</script>
</head>
<body>
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<input name="myInput" type="text" size="20" /><br />
<br />
<input type="button" onclick="getElements()" value="How many input elements?" />
</body>
</html>
例2,统计文档内有多少表格table
var tables = document.getElementsByTagName("table");
alert ("This document contains " + tables.length + " tables");
例3,获得文档中的第4个段落
如果您非常了解文档的结构,也可以使用 getElementsByTagName() 方法获取文档中的一个特定的元素。例如,下面的代码可以获得文档中的第四个段落:var myParagragh = document.getElementsByTagName("p")[3];
不过,如果您需要操作某个特定的元素,使用 getElementById() 方法将更为有效。
例4,获取id=”main”的元素中的所有p元素
下面的例子返回包含文档中所有p元素的列表,并且这些p元素应该是 id=”main” 的元素的后代(子、孙等等):document.getElementById("main").getElementsByTagName("p");
getElementsByClassName()
getElementsByClassName()
方法返回文档中所有指定类名的元素集合,作为 NodeList 对象,元素在集合中的顺序以其在代码中的出现次序排序。
若获取class为多个类的元素,多个类名使用空格分隔,如 “test demo”。
NodeList 对象代表一个有顺序的节点列表。NodeList 对象 我们可通过节点列表中的节点索引号来访问列表中的节点(索引号由0开始)。
提示: 你可以使用 NodeList 对象的 length 属性来确定指定类名的元素个数,并循环各个元素来获取你需要的那个元素。
注意: Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法。
例1,获取class为”example”和”color”的所有元素var x = document.getElementsByClassName("example color");
例2,统计文档中有多少个class为example的元素
<html>
<body>
<div class="example">样式 class="example" 的 div 元素</div>
<div class="example">另外一个样式 class="example" 的 div 元素</div>
<p class="example">样式 class="example" 的 p 元素</p>
<p>点击按钮查看文档中有多少个类名为 "example" 的元素。</p>
<button onclick="myFunction()">点我</button>
<p><strong>注意:</strong> Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法。</p>
<p id="demo"></p>
<script>
function myFunction() {
var x = document.getElementsByClassName("example");
document.getElementById("demo").innerHTML = x.length;
}
</script>
</body>
</html>
例3,修改所有样式class为”example”的元素的背景颜色
<html>
<head>
<style>
.example {
border: 1px solid black;
margin: 5px;
}
</style>
</head>
<body>
<div class="example">样式 class="example" 的 Div 元素</div>
<div class="example">另外一个样式 class="example" 的 Div 元素</div>
<p class="example">样式为 class="example" 的 p 元素。</p>
<p>这是一个插入在 p 元素中样式 class="example" 的<span class="example">span</span> 元素 。</p>
<p>点击按钮修改所有样式 class="example" 的背景颜色。</p>
<button class="example" onclick="myFunction()">点我</button>
<p><strong>注意:</strong> Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法。</p>
<script>
function myFunction() {
var x = document.getElementsByClassName("example");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.backgroundColor = "red";
}
}
</script>
</body>
</html>
例4,修改第一个类为”example color”的div元素的背景颜色
<html>
<head>
<style>
div {
border: 1px solid black;
margin: 5px;
}
</style>
</head>
<body>
<div class="example">
<p>P 元素在在第一个样式为 class="example" 的 Div 元素中。Div 的索引值为 0。</p>
</div>
<div class="example color">
<p>P 元素在在第一个样式为 class="example color" 的 Div 元素中。Div 的索引值为 0。</p>
</div>
<div class="example color">
<p>P 元素在在第二个样式为 class="example color" 的 Div 元素中。Div 的索引值为 1。</p>
</div>
<p>点击按钮修改第一个类为 "example color" 的 div 元素的背景颜色。</p>
<button onclick="myFunction()">点我</button>
<p><strong>注意:</strong> Internet Explorer 8 及更早 IE 版本不支持 getElementsByClassName() 方法。</p>
<script>
function myFunction() {
var x = document.getElementsByClassName("example color");
x[0].style.backgroundColor = "red";
}
</script>
</body>
</html>
- HTML DOM getElementsByClassName() 方法
http://www.runoob.com/jsref/met-document-getelementsbyclassname.html
innerHTML 与 value 的区别
getElementById().innerHTML 与 getElementById().value 的区别
有value属性的标签才能操作其value值,只有input等表单输入标签才有value值。
例如:<input type="text" id="txt1" value="hello"/>
这样一个元素,当你使用document.getElementById(“txt1”).value时,可以得到其value值,即”hello”这个字符串。
如果一个元素没有value值,那么使用document.getElementById().value时是取不到。这是理所当然的,没有的东西怎么访问?
比如一个div标记,就不一定有value值。
innerHTML是指元素起始标记和结束标记之间的内容。
例如:<label id="lb1">this is a label</label>
当你使用document.getElementById(“lb1”).innerHTML可以取到<label>
与</label>
之间的内容,即“this is a label”。
一个实例如下:
<html>
<head>
<script type="text/javascript">
function getValue()
{
var x=document.getElementById("myHeader")
alert(x.innerHTML)
}
function getValue2()
{
var x=document.getElementById("myInput")
alert(x.value)
}
</script>
</head>
<body>
<h1 id="myHeader" onclick="getValue()">这是标题</h1>
<input id="myInput" type="text" value="value值" onclick="getValue2()" />
<p>点击标题,会提示出它的innerHTML值。</p>
<p>点击input框,会提示出它的value值。</p>
</body>
</html>
cookie 操作
JavaScript 无法读取 HttpOnly 的 Cookie
HttpOnly 的设计目的
安全机制:HttpOnly 是浏览器提供的安全特性
防 XSS:专门防御跨站脚本攻击 (XSS)
敏感数据保护:用于保护包含敏感信息(如会话 ID、身份令牌)的 Cookie
JavaScript 访问限制
document.cookie 属性会完全忽略所有标记为 HttpOnly 的 Cookie
JavaScript 无法通过任何 API 读取 HttpOnly Cookie
即使尝试遍历 Cookie 或使用特殊技巧,仍然无法获取
同源请求会自动携带 Cookie
对于同源请求,浏览器自动且无条件发送所有相关 Cookie,无需任何特殊 JS 设置(如 credentials: ‘include’)
例如
页面访问:http://localhost:8000/user/profile
API访问:http://localhost:8000/api/v1/user/findDetail
是同源的,所以会自动携带 access_token 等 Cookie
但是如果 api 接口是 http://api.localhost:8000/data 就不是同源了,不会自动携带 Cookie
JavaScript 原生 Cookie 操作
document.cookie 返回结果样式 cookie1=value1; cookie2=value2; ...
// 设置cookie
document.cookie = "username=john_doe; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";
// 读取cookie
function getCookie(name) {
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [key, value] = cookie.split('=');
if (key.trim() === name) return decodeURIComponent(value);
}
return null;
}
console.log(getCookie("username"));
js-cookie 操作 cookie
https://github.com/js-cookie/js-cookie
上一篇 Spring-JDBC
下一篇 c3p0
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: