Libon

HTML Element

#JavaScript#HTML#dom
盘点一下一些常用的获取和操作 DOM 的一些方法和属性。

ToC

查找节点

在JS中有很多查找 HTML 节点的方法,在使用方面也有些许不同,这里做一下统计及它们的区别记录。

getElementById

首当其冲的当然是我们的老大哥 document.getElementById().

语法

var element = document.getElementById(id);

在示例中, element 是一个 Element 对象. 如果在文档中存在 id 属性相同的节点时会被返回, 不存在则返回 null. 其中 id 属性是一个大小写敏感的字符串, 使用相同名称但大小写不一致的id值的话, 这个方法依旧不能正常工作. 这表示了元素的唯一标识.

这里有几个需要注意的点, 如下:

  1. 如果页面中有多个相同 id 的元素节点, 该方法只会返回第一个符合条件的元素. 包括 querySelector() 方法也是一样的规则. 虽然在 CSS 当中, 设置的样式条件都会被应用, 但在 JS 中规则还是不一样的, 不能搞混.
  2. getElementById 方法只有当 document 作为调用方的时候才能正常工作, 在其他节点上访问方法会是 undefined. 这是因为元素的 id 值在整个网页中必须保持唯一, 所以没有必要为这个方法创建局部版本, 所以最终只能通过 document 来访问.
  3. 必须是存在于 document 中的元素才能被获取到. 当使用 document.createElement 创建了一个元素, 并设置了 id 属性, 但是未被添加到文档中的话, 调用方法时, 依旧获取不到元素. 在非 HTML 文档中也同样无法获取到节点, 比如 XHTML/XUL 中 id 通常被定义为 ID 类型的属性. 同样的, 这个方法也无法获取 iframe 中的元素节点, 以下方法若未做其他说明, 则自动套用这条规则.
  4. 由于一部分历史遗留问题, 在创建一个带有 id 属性的节点并添加到文档中以后, 会在 window 上声明挂载一个与 id 同名的属性, 它的键值就是创建的元素节点. 但是这并不是 W3C 规范中明确规定的, 所以不要依赖这个不稳定的特性.

getElementsByClassName

通过元素节点的 class 属性来获取.

语法

var elements = document.getElementsByClassName(className)
var targetNode = elements[0].getElementByClassName(className)
// 同时设置多个 className 以空格隔开
var multiNodes = document.getElementsByClassName(className className)

在示例中, elements 是一个包含所有符合条件的类数组元素节点集合, 它可能是多个的, 所以它是一个集合, 但它并不是一个真正的数组, 所以不能使用数组原型上的方法. 与 getElementByIdquerySelector('#*') 不同, getElementsByClassName 方法是可以在其他元素下调用的, 因为者不存在唯一性的问题.

getElementsByName

通过元素属性上的 name 属性来获取元素节点集合.

语法

<!DOCTYPE html>
<html lang="en">
  <body>
    <form name="up"><input type="text"></form>
    <div name="down"><input type="text"></div>

    <script>
    var up_forms = document.getElementsByName("up");
    console.log(up_forms[0].tagName); // returns "FORM"
    </script>
  </body>
</html>

name (en-US) 属性只有在(X)HTML文档中可用。

该方法返回一个live的 NodeList 集合,这个集合包含 name (en-US) 属性为指定值的所有元素,例如 <meta> 、<object>,甚至那些不支持 name 属性但是添加了 name 自定义属性的元素也包含其中。

getElementsByName 在不同的浏览器其中工作方式不同。在IE和Opera中, getElementsByName() 方法还会返回那些 id 为指定值的元素。所以你要小心使用该方法,最好不要为元素的 name 和 id 赋予相同的值。 IE 和 Edge 都返回一个 HTMLCollection, 而不是NodeList。

getElementsByTagName

通过元素节点名获取节点, 这同样适用于 web components element. 这个方法或搜索整个文档中的节点, 包括根节点.

语法

var elements = document.getElementsByTagName(name);

elementsgetElementsByClassName 方法返回的节点结果一样, 同样是一个节点的集合. name 代表的是一个元素节点的标签名, 同时还可以使用 * 来选择所有的html节点.

这个方法有两个注意事项, 如下:

  1. 当在一个HTML 文件上执行时, getElementsByTagName() 会在执行前把参数转换为小写字母。这是试着在一个HTML文件的子树匹配驼峰命名法的 SVG 元素时不希望的。 document.getElementsByTagNameNS() 在那种情况下会有用.
  2. document.getElementsByTagName() 类似于 element.getElementsByTagName(),除了它会搜索整个文档这点。

getElementsByTagNameNS

返回带有指定名称和命名空间的元素集合。整个文件结构都会被搜索,包括根节点。当调用方是某个节点的时候则只在某个节点的子节点内部搜索。

语法

<!DOCTYPE html>
<html lang="en">
  <body>
    <p>This is p tag</p>

    <script>
    var elements = document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'p')
    console.log(elements);
    </script>
  </body>
</html>

namespace 是所要查询的元素的命名空间URL. 命名空间URL多为 http://www.w3.org/1999/xhtml.

querySelector

通过CSS选择器来获取元素(单个). 可以使用 css 选择器的方式来设定查找条件, 包括属性原则器或者 + > ~ 选择符, 但是不能使用伪类(::before ::after ::mark 等, 详细可参见 Selectors API). 如果在选择符中使用了 :\ 的话, 则需要额外添加 \ 来进行转义. 方法只会返回符合条件的第一个元素, 如果没有符合条件的元素则返回 null.

语法

var element0 = document.querySelector('#id')
var element1 = document.querySelector('.class')
var element2 = document.querySelector('[attr]')
var element3 = document.querySelector('ul > li')

querySelectorAll

返回符合css选择器的节点集合. 使用与 querySelector 一致, 但该方法返回的是一个集合对象.

操作 HTML Text

常见的以 HTML Text 操作节点的方法其实很少, 基本上就是 innerHTML insertAdjacentElement这种. 这里也主要讲解一下这个方法和属性.

innerHTML

这个属性主要用于以节点文本的形式来替换掉某个元素内部的所有子节点内容

语法

document.body.innerHTML = '<div id="app"></div>'

方法会删除 body 元素内部的所有子节点及内容, 包括文本/注释等节点. 以上示例中表示了将 <div id=“app”></div> 元素节点放到 body 元素内部. 当父元素是 document 时, 设置的 innerHTML 将会无效, 因为其上面没有 innerHTML 属性.

insertAdjacentHTML

insertAdjacentHTML() 方法将指定的文本解析为 Element 元素, 并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用innerHTML操作更快。

语法

element.insertAdjacentHTML(position, text);

position 是一个用于表示插入的 DOMString 位置的属性, 必填并且必须是以下值:

text 则是需要被解析成 HTML 或 XML 的文本

位置名称可视化

<!-- beforebegin -->
<p>
  <!-- afterbegin -->
  foo
  <!-- beforeend -->
</p>
<!-- afterend -->

beforebegin和afterend位置,仅在节点在树中且节点具有一个parent元素时工作。

以上.


CD ..
回顾上一篇
NodeJS require 机制
接下来阅读
JS 事件流