document 对象属性详解:从 DOM 入口到实际开发应用

发布时间:2026/9/15 12:31:45
document 对象属性详解:从 DOM 入口到实际开发应用 1. 先搞懂 document 对象在浏览器里的地位1.1 document 对象到底是什么我相信很多前端初学者第一次看到 document 对象是在 console 里敲了一句 document.title。后来慢慢知道 document 是 window 下的一个属性代表整个 HTML 文档不管是读取页面标题也好、手动调整某个表单值也好最后都绕不开它。按 W3C 和 HTML 标准的说法document 对象是 Document 接口的实例它和我们常说的 DOM 树是绑定关系只要浏览器把 HTML 文本解析完就会生成一棵 DOM 树而 document 就是这棵树的入口。你可以把它理解成整棵树的根节点树的任何一层节点都可以从 document 出发找到。在我带新人的时候经常让新人先跑一遍这行代码console.dir(document);dir 打印出来的是对象结构直接在浏览器的开发者工具里展开能看到一大堆属性从 all、body、head 到 title、URL、readyState 都有。这个动作最大的价值是把“属性列表”变成“可以动手翻的树”看完之后至少不会觉得 document 很神秘。为什么我们特别关注 document 对象的属性因为属性就是它对外暴露的数据和状态。有些属性是只读的比如 document.URL 和 document.readyState你改不动它们它们的值由浏览器内部维护有些属性是可写的比如 document.title你把它改了浏览器标签页的标题立刻会变。搞清楚哪些能写、哪些只能读是使用这些属性的第一步。1.2 属性盘点先搭好知识框架document 对象的属性数量非常多官方英文文档列出来的加上兼容性属性粗算下来有三四十个。一次性全部背下来不现实而且大部分场景你真正用到的就是其中十几个。我把它们分成几类在脑海里先有个抽屉节点与结构属性document.documentElement、body、head、title、activeElement、all、children 等。地址与状态属性URL、domain、referrer、readyState、visibilityState、hidden、lastModified。集合与内容属性forms、images、links、anchors、scripts、styleSheets、embeds、plugins。文本与配置属性characterSet、charset、dir、designMode、compatMode、cookie。历史与兼容性属性doctype、implementation、location、defaultView、documentURI。这套分类不是官方标准是我自己在长期调试里为了方便记忆整理的。核心思路是一类属性解决一类问题比如要判断页面有没有加载完用 readyState要知道当前页面扎根在哪个域用 domain要拿到页面上所有表单做统一校验用 forms。实际项目里很多人习惯了直接写 document.querySelector 和 document.getElementById反而对 document 的对象属性不太敏感。但这些属性有自己的优势性能好比如 document.forms[0] 拿第一个表单不需要走完整选择器匹配语义化强比如 document.activeElement 直接告诉你当前焦点在哪可读性比一堆 getElementById 拼接强得多。这篇博客我就带着大家逐个拆开讲。注意我后面提到的每个属性都会顺带说一下兼容性和实际坑新手直接照着用就行老手也可以帮你们查漏补缺。2. 跟节点和文档结构打交道的属性2.1 三个高频根节点documentElement、body、head先看一组最常见的属性document.documentElement // 整个 html 元素 document.body // body 元素 document.head // head 元素documentElement 返回的是文档的根元素对 HTML 文档来说就是 标签。它有什么用最常见的场景就是读取视口相关的信息比如要拿页面整体高度来做滚动相关逻辑很多人会用 document.body.clientHeight但某些文件类型或某些浏览器里 body 的高度可能是不完整的更稳妥的是 document.documentElement.clientHeight 或 offsetHeight。我写页面滚动监听、懒加载判断时都习惯优先用 documentElement。body 和 head 就更直白了。document.body 常用于往页面尾部插入节点比如动态加载脚本的时候你创建一个 script 元素然后 document.body.appendChild(script)简单粗暴。document.head 适合在头部插入样式、meta 标签比如动态设置视口、插入第三方统计脚本。这里有一个坑想提醒大家document.body 在文档解析完成之前可能是 null。比如你在 里直接放一段内联脚本脚本执行到这个位置时 还没开始解析这时候访问 document.body 得到的是 null。要安全使用要么把脚本放到 前面要么等 DOMContentLoaded 事件触发后再操作。我就因为在 head 里的一段代码中直接用了 document.body结果线上环境偶发报错排查了半天才发现是加载时机的锅。2.2 顺着文档树继续title、activeElement、alldocument.title 是可写属性改它可以直接改变浏览器标签页上显示的标题。这个属性在单页面应用里特别常用比如路由切换后要把标题改成对应页面名称。一个常见的操作模式是document.title 首页 - 我的网站;SPA 里的标题显示底层的实现基本都是改 document.title。需要注意搜索引擎对 document.title 抓取也有依赖你在 SPA 里如果只靠它改标题对 SEO 帮助有限但这是另外的工程问题。document.activeElement 返回当前获得焦点的元素没有焦点的时候返回 body。在 PC 端可以用它判断用户当前正在哪个输入框里输入在移动端可以监听键盘弹起相关时机。const el document.activeElement; if (el el.tagName INPUT) { // 当前焦点在输入框 }使用 activeElement 有一点要留神有些浏览器在失焦后返回 body有些返回 null判断时最好兼容一下。而且它对 shadow DOM 里的焦点元素返回的是宿主元素不是真正的内部元素做复杂组件时要注意。document.all 是历史遗留属性早年 IE 用它返回页面所有元素集合现在它其实是个伪数组具有 HTMLAllCollection 接口。在标准浏览器里typeof document.all 是 undefined 这个特例非常出名曾经被很多库用来做 IE 检测。日常开发中不建议再依赖它用 querySelectorAll 代替更靠谱。这个细节我放在后面兼容性章节再说。3. 跟 URL、标题、加载状态有关的属性3.1 URL、domain、referrer 到底存了什么东西接下来这三个属性极容易混URL、domain、referrer。document.URL 返回当前文档的完整 URL 字符串是只读的。注意document.URL 是经过浏览器处理后的地址和 location.href 基本一致但 document.URL 不能用来做跳转。有人会问什么时候用 document.URL比如要在页面里记录来源地址用于统计读取它就行。document.referrer 返回来源页面的 URL也就是用户是从哪个页面跳过来的。如果直接输入网址或新开标签页进来referrer 通常是空字符串。它常用于站内引导来源统计或者判断是否从外部广告落地。这个属性是只读的不过受浏览器安全策略影响如果你的页面设置了 referrer policy 为 no-referrer那么什么都拿不到。document.domain 返回当前文档所属域名。它曾经被用来解决同源跨域通信比如主域相同但子域不同的两个页面把 domain 都设为同一个主域就可以互相访问。现在主流浏览器已经收紧了这个能力很多用法失效了跨域的问题建议通过 postMessage 或服务端代理解决而不是继续依赖修改 document.domain。一个容易忽略的细节document.URL 在设置 base 标签或者页面被 iframe 嵌入的时候返回的仍然是当前文档实际的 URL不会因为而改变。而 document.domain 和页面所在的 iframe 有很强的关系不同 iframe 的 document.domain 可能不同。做站点嵌入和跨域调试时这个差异经常会坑人。3.2 readyState、characterSet 与 lastModifieddocument.readyState 用来表示文档加载状态值有三种loading文档还在加载中。interactive文档解析完成但图片等资源可能还没加载完此时 DOM 可访问。complete文档和所有资源都已加载。在实际开发里很多人已经用了 DOMContentLoaded 事件但通过轮询 readyState 来判断文档状态也是一种经典做法在脚本动态注入、插件初始化的场景下很实用。if (document.readyState complete) { init(); } else { document.addEventListener(readystatechange, handleStateChange); }document.characterSet 返回文档使用的字符编码比如 UTF-8。为什么提这个属性因为如果你在做文本抓取、字节长度计算、乱码排查判断页面编码非常关键。早年很多网站是 gb2312/gbk如果不按对应编码解码抓到的文本就是乱码。现在虽然绝大多数是 UTF-8但接手老项目时还是建议先看一眼。document.lastModified 返回文档最后修改时间字符串格式是 MM/DD/YYYY HH:mm:ss。它依赖于服务器返回的 Last-Modified 响应头如果服务器没给那这个值就是当前时间或者不稳定值。它不适用来做精确的版本控制但如果你想在页脚显示一个简单的“最后更新于 xxx”用它是很省事的方案比自己去写时间戳维护逻辑简单。4. 集合属性一张图抓出页面里的所有表单、图片和链接4.1 forms、images、links、anchors 的定位差异document.forms、document.images、document.links、document.anchors 这四个属性是 DOM 的即时集合live collection意思是它们不是静态快照而是像“活引用”一样DOM 变化后集合会跟着变化。document.forms 返回页面上所有元素的集合。如果你需要统一给页面上所有表单做校验、统一收集请求参数可以直接遍历const forms document.forms; for (let i 0; i forms.length; i) { const form forms[i]; const formData new FormData(form); }document.images 返回所有 元素。做图片懒加载、图片统计、图片替换时从 document.images 出发很方便。但要注意CSS 背景图不包含在 document.images 里它只关心 img 标签。document.links 和 document.anchors 非常容易弄混。document.links 返回所有带 href 属性的 和元素document.anchors 返回所有带 name 属性的 元素这是老式锚点语法现在基本很少用了。所以实际工作里links 的价值远大于 anchors。比如我要检查页面所有外链是否带 relnoopener遍历 document.links 就能做到。集合属性虽好用但它们是 live collection这也意味着每次访问都会有浏览器内部查询。如果你在循环里反复读取 document.forms.length性能会比缓存变量差。建议先 const list document.forms再基于 list 操作。另外如果你用 for...in 遍历这些集合可能会遍历到一些自定义属性或方法更推荐用 for...of 或 Array.from 转成数组Array.from(document.images).forEach(img { ... });4.2 scripts、styleSheets、embeds 与 pluginsdocument.scripts 返回所有

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询