当前位置 : 首页 » 文章分类 :  开发  »  JavaScript-DOM

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 取消回调)。

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 发起的 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 提供浏览器和操作系统的信息

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>

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>

HttpOnly 的设计目的
​​安全机制​​:HttpOnly 是浏览器提供的安全特性
​​防 XSS​​:专门防御跨站脚本攻击 (XSS)
​​敏感数据保护​​:用于保护包含敏感信息(如会话 ID、身份令牌)的 Cookie

JavaScript 访问限制
document.cookie 属性会​​完全忽略​​所有标记为 HttpOnly 的 Cookie
JavaScript ​​无法通过任何 API​​ 读取 HttpOnly 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


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"));

https://github.com/js-cookie/js-cookie


上一篇 Spring-JDBC

下一篇 c3p0

阅读
评论
7.5k
阅读预计33分钟
创建日期 2017-05-22
修改日期 2025-08-25
类别
目录

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论