modified | Thursday 1 May 2025 |
---|
Monday, August 9, 2021 at 13:05
你 不 需 要 $6(document).ready 和
DOMContentLoaded 了
Paul
保 罗 的 小 宇 宙
你 曾 在 编 写 原 生 JS 或 JQuery 代 码 的 时 候 , 是 不 是 会
素 获 取 不 到 的 问 题 ?
/ your-script . js
document .getElLementById(“app“) . innerHTML =
经 常 遇 到 DOM 元
“I am RaulL “ ;
Uncaught TYpeError: Cannot set property “innerHTML“「 of nul1
at Your-script.js : 1
为 什 么
这 是 因 为 你 的 代 码 在 页 面 加 载 完 成 之 前 就 已 经 被 执 行 了 , 默 认 只 能 获 取
到 script 标 签 声 明 之 前 的 内 容 。 所 以 可 以 将 script 标 签 放 在 最 后
面 , 是 平 常 最 简 单 直 接 的 办 法 , 防 止 拿 不 到 对 应 的 DOM 元 素 。
这 是 因 为 你 的 代 码 在 页 面 加 载 完 成 之 前 就 已 经 被 执 行 了 , 默 认 只 能 获 取
到 script 标 签 声 明 之 前 的 内 容 。 所 以 可 以 将 script 标 签 放 在 最 后
面 , 是 平 常 最 简 单 直 接 的 办 法 , 防 止 拿 不 到 对 应 的 DOM 元 素 。
但 在 某 些 情 况 下 ,script 标 签 不 一 定 能 被 放 在 最 后 面 , 于 是 需 要 考 虑
到 如 何 在 页 面 内 容 加 载 完 成 后 再 执 行 代 码 。 写 过 JQuery 的 同 学 , 一 定
都 知 道 $(document) .ready( ) 这 个 API。
// _ Juery
$(document) .ready(function() 《
( “app“) .html (“I am Paul“) .
])
或 者 是 原 生 版 本 :
// Vanilla
document.addEventListener (“DOMContentLoaded“ , () => t
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
])
/ ! 不 推 荐 , 因 为 会 因 阻 塞 资 源 ( 图 片 等 ) 导 致 长 时 间 不 会 执 行 , 就 是 页 面 所 有 资
源 加 载 完 成 之 后 才 会 执 行
window.onload = function () 《
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
这 是 因 为 你 的 代 码 在 页 面 加 载 完 成 之 前 就 已 经 被 执 行 了 , 默 认 只 能 获 取
到 script 标 签 声 明 之 前 的 内 容 。 所 以 可 以 将 script 标 签 放 在 最 后
面 , 是 平 常 最 简 单 直 接 的 办 法 , 防 止 拿 不 到 对 应 的 DOM 元 素 。
但 在 某 些 情 况 下 ,script 标 签 不 一 定 能 被 放 在 最 后 面 , 于 是 需 要 考 虑
到 如 何 在 页 面 内 容 加 载 完 成 后 再 执 行 代 码 。 写 过 JQuery 的 同 学 , 一 定
都 知 道 $(document) .ready( ) 这 个 API。
// _ Juery
$(document) .ready(function() 《
( “app“) .html (“I am Paul“) .
])
或 者 是 原 生 版 本 :
// Vanilla
document.addEventListener (“DOMContentLoaded“ , () => t
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
])
/ ! 不 推 荐 , 因 为 会 因 阻 塞 资 源 ( 图 片 等 ) 导 致 长 时 间 不 会 执 行 , 就 是 页 面 所 有 资
源 加 载 完 成 之 后 才 会 执 行
window.onload = function () 《
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
e
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
这 里 面 基 本 上 都 是 一 个 「 匿 名 函 数 」 封 装 了 一 波 , 以 此 实 现 让 浏 览 器 加
载 完 页 面 内 容 之 后 才 执 行 script 的 内 容 。
defer, 新 的 帮 手
然 而 , 有 一 个 你 也 许 并 不 知 道 的 属 性 , 非 常 完 美 的 解 决 这 个 问 题 。
没 错 , 只 需 要 在 script 标 签 上 加 一 个 aefer 属 性 , 就 可 以 让 浏 览 器 知
道 这 个 能 本 需 要 在 页 面 内 容 加 载 完 成 ( 不 包 括 onload 提 到 的 资 源 际
塞 ) 之 后 才 执 行 了 。 完 全 不 再 需 要 把 脚 本 放 在 最 底 部 , 或 者 是 设 置 以 上
两 个 事 件 , 就 可 以 使 用 。
your-script .js 现 在 只 需 要 一 行 代 码 直 接 执 行 , 就 可 以 拿 到 DOM 上
的 内 容 了 。
document.getElLlementById(“app“) .innerHTML =“I am PaulL .“;
当 然 , 相 信 大 家 并 不 会 这 样 做 , 毕 竟 这 样 写 会 把 变 量 完 全 公 开 出 来 , 很
容 易 被 控 制 台 获 取 , 编 写 一 个 脚 本 重 写 代 码 更 是 「 轻 而 易 举 」 。 实 际 情
况 去 编 写 一 段 简 单 的 代 码 , 依 然 需 要 匿 名 函 数 的 封 装 。
(function () 《
document.getElLlementById(“app“) .innerHTML =“I am PauL .“;
) () 7
再 举 个 例 子 ,Svelte 框 架 生 成 的 原 生 代 码 是 这 样 的 :
var app = function () 《
1
var app = function () 《
107
菊 宝 性
个 你 就 不 用 担 心 了 , 连 IE10 都 能 用 , 其 他 浏 览 器 基 本 上 都 是 OK
o
caniuse.bitsofco.de/embedyindex.html?feat=script-defer&iper..。 》
CanlUse
执 行 顺 序
全 部 带 上 aefer 的 script 标 签 , 将 和 一 般 引 入 的 情 〉
如 果 一 个 带 上 , 页 序 就 是 先 执 行 不 带 aefer 的 , 再
执 行 帝 2 的 。
/ 一
CanlUse
执 行 顺 序
全 部 带 上 aqefer 的 script 标 签 , 将 和 一 般 引 入 的 情 况 执 行 |
页 序 相 同 。
如 果 一 个 带 上 , 一 个 不 带 上 , 执 行 顺 序 就 是 先 执 行 不 带 defer 的 , 再
执 行 带 qdefer 的 。