应优先使用 document.querySelector(支持CSS选择器、返回null)和 querySelectorAll(返回可遍历NodeList),避免 getElementsByClassName 等返回动态 HTMLCollection 的方法;修改文本用 textContent 而非 innerHTML 以保安全;增删元素用 appendChild、remove 和 DocumentFragment;事件绑定善用委托与 { once: true }。

获取元素用 document.querySelector 而不是 document.getElementById 更通用
多数场景下,document.querySelector 比 document.getElementById 更实用——它支持 CSS 选择器语法,能一次性覆盖 ID、class、属性、伪类等多种定位方式。而 getElementById 只能按 ID 查,且返回值不是 NodeList(无法直接 forEach),容易在后续操作中出错。
-
querySelector返回第一个匹配元素(没找到返回null),适合单个目标操作 -
querySelectorAll返回NodeList(类数组,可直接用forEach),适合批量处理 - 避免用
getElementsByClassName或getElementsByTagName,它们返回的是动态HTMLCollection,DOM 变化后会“自动更新”,导致循环中索引错乱或死循环 - 如果只查 ID,
querySelector('#my-id')和getElementById('my-id')性能差异极小,但写法统一更利于维护
修改内容优先用 textContent,不是 innerHTML
除非你明确需要插入 HTML 标签并执行其中的脚本或样式,否则一律用 textContent 设置文本。它更快、更安全,不会触发 HTML 解析,也杜绝 XSS 风险。
-
element.textContent = 'Hello '→ 显示原样字符串,不执行脚本 -
element.innerHTML = 'Hello '→ 实际弹窗,且可能破坏原有结构(比如闭合标签不匹配时) - 若必须插 HTML,先用
DOMPurify.sanitize(htmlStr)过滤(需引入库),别手写正则清洗 -
innerText受 CSS 影响(如display: none的内容不计入),行为不一致,浏览器兼容性差,不推荐
添加/删除元素用 appendChild 和 remove,少用 innerHTML +=
innerHTML += 看似简单,实则每次执行都会销毁旧节点、重新解析整段 HTML 字符串,造成事件监听器丢失、表单输入清空、性能浪费。现代 DOM 操作应基于节点对象进行。
- 新增元素:先
document.createElement('div'),再设textContent或setAttribute,最后parent.appendChild(newEl) - 插入到指定位置:用
parent.insertBefore(newEl, referenceEl) - 删除元素:直接调用
element.remove()(IE 不支持,需 fallback 到parentNode.removeChild(element)) - 批量添加多个节点:用
DocumentFragment缓存,一次性 append,减少重排重绘
事件绑定别漏掉事件委托和 once 选项
动态生成的元素(如列表项、模态框按钮)不能靠遍历绑定事件,得用事件委托;同时,很多只需触发一次的操作(如初始化、加载完成回调),应利用 { once: true } 避免重复注册。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“Java免费学习笔记(深入)”;
- 委托写法:
list.addEventListener('click', e => { if (e.target.matches('.item-delete')) { /* 处理删除 */ } }) -
once: true示例:button.addEventListener('click', handler, { once: true }),执行完自动解绑 - 避免在循环里写
for (let i = 0; i console.log(i) }——闭包问题导致所有回调输出相同i值,改用forEach或箭头函数 +let声明 - 移除委托事件不用手动清理,但自定义事件或定时器仍需在回调内显式清除
const list = document.querySelector('#todo-list');
list.addEventListener('click', function (e) {
if (e.target.matches('button.delete')) {
e.target.closest('li').remove();
}
});
DOM 操作真正难的不是记方法名,而是判断该不该操作、什么时候操作、是否已挂载、有没有被框架接管。原生 JS 操作前,先确认目标元素确实存在(if (!el) return),尤其在异步或第三方脚本加载后执行时——这是最常被跳过的一步。










