DOM 修改、DOM 添加、DOM 删除、DOM 常用对象

2,046 阅读5分钟

1. DOM 修改

1.1. 内容修改
  • innerHTML: 获取或设置元素开始标签到结束标签之间的 HTML 代码片段
  • textContent: 获取或设置元素开始标签到结束标签之间的纯文本内容
    • 2 件事: 1. 去掉文本中嵌套的标签 2. 将所有转义字符翻译为正文
  • IE8: innerText
  • .value: 获取或设置表单元素的内容
1.2. 属性修改: 3 类
1.2.1. 标准属性: 2 种
  • 标准属性: 在 HTML 基础知识里有写到
  1. 核心 DOM: 4 个 API -> 繁琐

    • 所有属性节点都保存在元素的 attribute 集合中
    • 获取属性值: elem.getAttribute('属性名')
    • 设置 / 修改属性值: elem.setAttribute('属性名', '属性值)
    • 是否包含: elem.hasAttribute('属性名')
    • 移出属性: elem.removeAttribute('属性名')
  2. HTML DOM -> 简洁

    • HTML DOMHTML 标准属性都封装成了元素对象的属性, 可以直接通过 元素. 访问

    • 获取属性值: elem.属性名

    • 设置 / 修改属性值: elem.属性名 = 属性值

    • 是否包含: elem.属性名 === ''

    • 移出属性: elem.属性名 = ''

    • 特殊: class 属性

      • class 属性是 JS 语言的保留字, 所以 DOM 中的 class 属性需要改名为 className
1.2.2. 状态属性
  • 包括: selected / checked / disabled
  • 不能通过核心 DOM 访问, 只能通过 HTM DOM 访问
1.2.3. 自定义扩展属性
  • Ex: data-toggle = "dropdown"
  1. 核心 DOM -> 繁琐
    • 不能使用 HTML DOM 访问
  2. HTML 5 语法 -> 简洁
    • 设置 / 修改自定义属性值: data-dataset.属性名 = 值
    • 获取自定义属性: elem.dattset.属性名
  3. 何时:
    1. 在客户端页面中临时缓存部分业务数据
    2. 代替 id / class 作为查找元素的条件
1.3. 样式修改: 2 种
  • 单独修改一个 css 属性
1.3.1. 内联:
  • 内联样式: 写在元素的 style 属性种的样式

  • 获取内联样式: elem.style.css属性名

  • 设置 / 修改内联样式: elem.style.css属性名 = css属性值

  • 强调:

    1. css 属性名都要去横线变驼峰
      • Ex: background-color -> backgroundColor
    2. 所有的 css 属性值都是字符串( 可能带单位 )
      • 计算前都要先去掉单位, 转数字再计算
  • 设置内联: 优先级高, 当前元素独有, 不影响其他元素

  • 获取内联:

    • 问题: 实际开发中可能几乎不包括内联样式 -> 用 elem.style 可能无法获得任何样式

    • 解决: 用 getComputedStyle(elem) 代替 elem.style

      • getComputedStyle(): 计算后的样式, 最终作用到元素上的所用样式的综合

      • 如何: var style = getComputedStyle(elem) -> style.css属性名

      • 强调: 计算后的 css 属性都是只读

        • 因为计算后的 css 属性可能原来是共用的, 一旦修改, 牵一发而动全身
1.3.2. 内部 / 外部样式表 -> 危险
  1. 找到对应的样式表对象: var sheet = document.stylesheets[i]
  2. 找到 cssRule 对象: var cssRule = sheet.cssRules[i]
    • 如果是 keyframes, 就需要继续找下级的 cssRule
  3. 修改 cssRulestyle 下的 css 属性: cssRule.style.css属性名 = css属性值
  • 问题: 每次只能修改一个 css 属性
    • 解决: 通过修改元素的 class 属性, 来批量应用多个 css 属性

2. DOM 添加、DOM 删除

2.1. DOM 添加: 3 步
  1. 创建空元素: var elem = document.createElement('元素名')
    • Ex: var createA = document.createElement('a') => <a></a>
  2. 设置关键属性: elem.属性名 = 属性值
    • Ex: createA.href = 'http://www.baidu.com' -> createA.innerHTML = '百度' => <a href="http://www.baidu.com">百度</a>
  3. 将创建的元素添加到 DOM 树指定父元素下
    • 新建的元素, 只有添加到 DOM 树上才能显示出来
    • 添加元素: 3 种
      1. 末尾追加: parent.appendChild(elem)
      2. 中间插入: parent.insertBefore(elem, child)
      3. 替换: parent.replaceChild(elem, child)
  • 优化: 尽量减少操作 DOM

    • 原理: 页面加载过程 html -> DOM TreeRender Tree -> ** layout( 计算每个元素的精确布局耗时 ) ** -> paintcss -> CSSRules

      • 频繁修改 DOM 树, 会导致频繁 layout, 降低页面响应速度
    • 解决: 2 种

      1. 如果需要同时添加父元素和子元素时, 就要在内存中先将子元素添加到父元素, 再将父元素整体一次性添加到 DOM

      2. 如果父元素已经在页面上, 要添加多个平级子元素, 就要借助文档片段

        • 文档片段: 内存中临时保存多个子元素的虚拟父元素

          • 何时: 要添加多个平级子元素

          • 如何: 3步

            1. 创建文档片段: var frag = document.createDocumentFragment()
            2. 将平级子元素添加到 frag 中: frag.appendChild(elem)
            3. frag 整体添加到页面父元素下: parent.appendChild(frag)
          • 说明: 将子元素添加到 DOM 树后, frag自动释放, 不占用页面空间

2.2. DOM 删除
  • 删除: parent.removeChild(child)

3. DOM 常用对象

3.1. Image

指代页面中一个 img 元素

  • 创建: var img = new Image()
3.2. Select

指代页面中一个 <select> 元素

  1. 属性

    • sel.selectedIndex: 获得当前选中项的下标位置
    • sel.value: 获取当前选中项的值( value )
      • 如果当前 option 没有 value, 则用 innerHTML 代替\
    • sel.options: 获取当前 sel 下的所有 option 元素的集合
      • sel.options.length: 选项的个数
      • sel.options.length = 0: 清除所有选项
    • sel.length: 选项的个数, 相当于 sel.options.length
      • sel.length = 0: 清除所有选项
  2. 方法

    • sel.add(option): 向 sel 末尾追加一个 option

      • 强调: 不支持文档片段

    • sel.remove(i): 移出 i 位置的选项

  3. 事件

    • sel.onchange: 当选中项发生改变时触发
3.3. Option

指代页面中一个 option 元素

  • 创建: var opt = new Option(text, value)
  • 属性: opt.text 代替 opt.innerHTML
3.4. Table

指代页面中一个 table 元素

3.4.1. 管着行分组: 创建, 删除, 获得
  1. 创建:
    • var tHead = table.createTHead()
    • var tBody = table.createTBody()
    • var tFoot = table.createTFoot()
  2. 删除:
    • table.deleteTHead()
    • table.deleteTFoot()
  3. 获取:
    • table.tHead
    • table.tBodies[i]
    • table.tFoot
3.4.2. 行分组
  • 包括: tHead / tBody / tFoot -> 管着 tr

  • 创建: var tr = tXXXX.insertRow(i)

    • 说明: 如果 i 位置有行, 则原位置的行向后顺移

    • 常用操作: 1. 末尾追加一行: tXXXX.insertRow()

      1. 开头插入一行: tXXXX.insetRow(0)
  • 删除: tXXXX.deleteRow(): 删除当前行分组中下标为 i 的行

  • 获取: tXXXX.rows

3.4.3. 行 tr
  • 管着格

  • 创建: tr.insertCell(i)

    • 强调: insetCell 只能创建 td

  • 删除: tr.deleteCell(i)

  • 获取: tr.cells

3.4.4. 删除行: 2种
  1. 行分组.deleteRow(i)
    • i 是行分组内的相对位置, 无法直接获得
  2. table.deleteRow(i)
    • i 是行在整个表格中的位置, 可以直接获得
      • tr.rowIndex: 表示 tr 在整个表格中的位置
  • 总结: 今后凡是删除行: table.deleteRow(tr.rowIndex)

3.5. Form

指代页面中一个 form 元素

  • 获取: var formEl = document.forms[i / id]
  • 属性: formEl.elements: 获得包含所有表单元素的集合 -> 包含: input / select / button / textarea
    • form.elements.length: 获取表单中表单元素的个数
    • form.length: 获取表单中表单元素的个数, 相当于 form.elements.length
  • 方法: form.submit(): 手动提交表单
    • 只有验证通过才能提交: 2 种
      1. <input type='button' /> 代替 <input type='submit' />
        • <input type='button' /> 的单击事件中自己调用 form.submit()
      2. <input type='submit' /> 配合 onsubmit 事件
  • 表单元素
    • 获取: form.elements[i / id / name]
      • 更简写: 如果表单元素有 name 属性, 可直接: form.name
    • 方法:
      • elem.focus(): 让 elem 获取焦点
      • elem.blur(): 让 elem 失去焦点