javascript如何操作DOM_有哪些常用方法呢

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

获取元素用 document.querySelector 而不是 document.getElementById 更通用

多数场景下,document.querySelectordocument.getElementById 更实用——它支持 CSS 选择器语法,能一次性覆盖 ID、class、属性、伪类等多种定位方式。而 getElementById 只能按 ID 查,且返回值不是 NodeList(无法直接 forEach),容易在后续操作中出错。

  • querySelector 返回第一个匹配元素(没找到返回 null),适合单个目标操作
  • querySelectorAll 返回 NodeList(类数组,可直接用 forEach),适合批量处理
  • 避免用 getElementsByClassNamegetElementsByTagName,它们返回的是动态 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 的内容不计入),行为不一致,浏览器兼容性差,不推荐

添加/删除元素用 appendChildremove,少用 innerHTML +=

innerHTML += 看似简单,实则每次执行都会销毁旧节点、重新解析整段 HTML 字符串,造成事件监听器丢失、表单输入清空、性能浪费。现代 DOM 操作应基于节点对象进行。

  • 新增元素:先 document.createElement('div'),再设 textContentsetAttribute,最后 parent.appendChild(newEl)
  • 插入到指定位置:用 parent.insertBefore(newEl, referenceEl)
  • 删除元素:直接调用 element.remove()(IE 不支持,需 fallback 到 parentNode.removeChild(element)
  • 批量添加多个节点:用 DocumentFragment 缓存,一次性 append,减少重排重绘

事件绑定别漏掉事件委托和 once 选项

动态生成的元素(如列表项、模态框按钮)不能靠遍历绑定事件,得用事件委托;同时,很多只需触发一次的操作(如初始化、加载完成回调),应利用 { once: true } 避免重复注册。

  • 委托写法: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),尤其在异步或第三方脚本加载后执行时——这是最常被跳过的一步。