JavaScript DOM操作

作者: 练晓习 | 来源:发表于2017-02-12 09:58 被阅读86次

DOM (文档对象模型) 是针对 HTML 和 XML 文档的一个API (应用程序接口)。
DOM 描绘了一个层次化的节点树,HTML 文档中的所有内容都是节点。

  • 整个文档是一个文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

一. 节点层面

  • 节点类型

    每个节点都有一个 nodeType 属性,用于表示节点类型。nodeType 属性返回节点的类型。nodeType 是只读的。常用的节点类型如下图所示(图片摘自MDN

    nodetype.jpg
  • 节点关系

    1. childNodes 属性

    childNodes 属性以 NodeList 对象返回节点的子节点集合。
    NodeList是一种类数组对象,用于保存一组有序的节点。NodeList 对象是基于 DOM 结构动态执行查询的结果,因此 DOM 结构的变化能够自动反映在 NodeList 对象中。

    var firstChild = someNode.childNodes[0];
    var len = someNode.length;
    
    2. firstChild 属性和 lastChild 属性

    firstChild 属性和 lastChild 属性分别返回指定节点的第一个和最后一个子节点。

    2. parentNode 属性

    parentNode 属性返回指定节点的父节点。

    4. previousSibling 属性和 nextSibling 属性

    previousSibling 属性和 nextSibling 属性分别返回指定节点的上一个和下一个同级节点

    node.png
    • Node.contains(otherNode) 来表示传入的节点是否为该节点的后代节点
    • Node.compareDocumentPosition(otherNode ) 方法用于比较当前节点与文档中的另一个节点的位置关系.
    • Node.hasChildNodes( ) 方法用于判断当前节点是否有子节点,返回一个布尔值
  • 操作节点

1. appendChild( ) 方法

appendChild( ) 方法用于向 childNodes 列表的末尾插入一个节点。添加节点后,相关节点DOM结构得到更新,更新完成后返回新增的节点。

// someNode 有多个子节点
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode = someNode.firstChild); //false
alert(returnedNode = someNode.lastChild); //true
2. insertBefore( ) 方法

insertBefore( ) 方法用于向 childNodes 列表的特定位置插入一个节点,并返回被插入的节点。这个方法接受两个参数:要插入的节点和作为参照的节点。被插入的节点将变成参照节点的前一个同胞节点(previousSibling)。 若参照节点是null,则 insertBefore( ) 与 appendChild( ) 执行相同的操作。

// 插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //ture
3. replaceChild( ) 方法

replaceChild( ) 方法用新节点替换某个子节点,并返回要替换的节点。这个方法接受两个参数:插入的新节点和要替换的节点。

// 替换第一个子节点  
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);

注意:任何 DOM 节点都不能同时出现在文档的多个位置。所以,如果以上的三个方法中要新插入的节点已经是文档的一部分了,那么这个新插入的节点将从原来的位置转移到新位置。

4. removeChild( ) 方法

removeChild( ) 方法用于移除节点。这个方法接受一个参数:要移除的节点。

// 移除第一个子节点  
var formerFirstChild = someNode.removeChild(someNode.firstChild);
4. remove( ) 方法

ChildNode.remove() 方法把调用节点元素ChildNode从它所属的DOM树中删除。

// id 为 'div-01' 的 div 被删掉了
document.getElementById('div-01').remove();
5. cloneNode( ) 方法

cloneNode( ) 方法用于创建调用这个方法的节点的副本。此方法接受一个布尔值参数,表示是否进行深复制。深复制就是复制节点及其子节点树;浅复制是只复制节点本身。
复制后返回的节点副本没有父节点,属于文档中的一个“孤儿”,所以通常还会通过appendChild( )、insertBefore( )或 replaceChild( ) 将它添加到文档中。

6. normalize( ) 方法

规划化元素内的文本节点。如果在包含一个或多个文本节点的父元素上调用这个方法,则会将所有文本节点合并为一个节点,合并之后的新的文本节点的 nodeValue 等于合并前的每个文本节点的 nodeValue 值拼接起来的值。(浏览器自身永远不会创建相邻的文本节点,这种一个元素包含多个文本节点的情况一般是在操作 DOM 时产生的)

二. 文档层面

var htmlEle = document.documentElemnet; // 取得对<html>元素的引用
var bodyEle = document.body; // 取得对<body>元素的引用
var headEle = document.head || document.getElementsByTagName("head")[0]; //取得对<head>的引用;
var title = document.title; //取得文档标题
document.title = "new title"; //修改当前页面的标题
var charset = document.charset; // 取得文档中实际使用的字符集
document.charset = "UTF-8"; // 修改文档字符集
var url = document.URL; //取得完整的URL(即地址栏中显示的URL)*只读*
var domain = document.domain; //取得页面的域名
var referrer = document.referrer; //取得链接到当前页面的那个页面的URL *只读*
var doc_state = document.readyState;  // 取得文档的当前状态(有两个可能的值:loading 和 complete)*只读*
var focus_ele = document.activeElement; //取得文档中当前获得焦点的元素 *只读*
var if_focus = document.hasFocus( ); //取得用于检测文档是否获取焦点的布尔值。

三 . 针对元素

  • 通过 nodeName 或 tagName 属性访问元素的标签名。
  alert (document.body.tagName); // "BODY"
  • 每个HTML 元素都有下列属性: id, title, dir, dir(语言的方向), className
  • 插入标记

1. innerHTML 属性

读模式下,此属性返回与调用元素的所有子节点(包括元素、注释、文本节点)对应的 HTML 标记。 写模式下,innerHTML 会根据指定的值创建新的 DOM 树,然后用这个DOM 树完全替换调用元素原先的所有子节点。(通过innerHTML 属性插入的 <script> 元素不会执行其中的脚本)

2. insertAdjacentHTML( position,text) 方法

这个方法接受两个参数:插入位置和要插入的 HTML 文本。第一个参数的可能值为:"beforebegin"," afterbegin","beforeend","afterend"
注意: beforebegin和afterend位置,仅在节点在树中且节点具有一个parent元素时工作.

// 作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "<p>hello world !</p>");
// 插入元素内部的第一个子节点之前。
element.insertAdjacentHTML("afterbegin", "<p>hello world !</p>");
// 插入元素内部的最后一个子节点之后。
element.insertAdjacentHTML("beforeend", "<p>hello world !</p>");
// 作为后一个同辈元素插入
element.insertAdjacentHTML("afterend", "<p>hello world !</p>");
3. insertAdjacentElement(position, element)

这个方法接受两个参数:插入位置和要插入的元素节点,此方法将一个给定的元素节点插入到相对于被调用的元素的给定的一个位置,返回插入的元素,插入失败则返回null.
注意: 当节点处于DOM树中而且有一个父元素的时候 beforebegin 和 afterend操作才能起作用。

  • 插入文本

1. textContent 属性

Node.textContent 属性可以表示一个节点及其内部节点的文本内容。
读模式下,textContent 会由浅入深将子文档树中的所有文本拼接起来。写模式下,会删除元素的所有子节点,插入包含相应文本值得文本节点。

2. insertAdjacentText ( position,text) 方法

此方法和insertAdjacentHTML( ) 方法用法相同,不过是第二个参数只能是纯文本。

  • 元素属性

<!-- 以下面这个元素为例 -->
 <div id="my_div" class="bd" title="body_text" my_attr="hello" data-appId="123" ></div>
 var div = document.getElementById("my_div"); // 取得对上面元素的引用
1.获取元素属性的数量

通过元素的 attributes.length属性 获取属性数量

  var len = div.attributes.lenght;
2. 删除元素属性

removeAttribute( ) 方法 用于彻底删除元素属性;

div.removeAttribute("title"); //删除 title 属性
3. 获取并操作属性
  • 方法1. 通过元素自身直接获取、修改和添加属性
// 获取元素属性
var class = div.className;
var id = div.id;
// 修改元素属性
div.title = "some other text";
// 添加元素属性
div.lang= "en";
  • 方法2(推荐). 通过 getAttribute( ) 方法 获取属性, setAttribute( ) 方法 修改和添加属性
//获取元素属性
var title = div.getAttribute("title");
var my_attr = div.getAttribute("my_attr");
// 修改元素属性
div.setAttribute("class", "ft");
div.setAttribute("my_attr", "hi");
// 给添加属性
div.setAttribute("lang", "en");
div.setAttribute("my_name", "Tom");

上述两种方法的区别:方法2既可以获取标准的属性还可以获取自定义属性,而方法1只能访问标准的属性无法访问自定义属性。

4. 自定义数据属性

还可以通过元素的 dataset 属性 来获取和修改自定义属性的值

var appId = div.dataset.appId; // 取得自定义属性的值
div.dataset.appId = "234"; // 修改自定义属性的值
  • 创建元素

    var div = document.createElement("div"); // 创建一个<div>元素
    

由于新创建的元素属于文档中的一个“孤儿”,所以通常还会通过 appendChild( )、insertBefore( )或 replaceChild( ) 将它添加到文档中。

  • 获取对元素的引用

1. 取得对文档的子元素节点的引用
var head = document.head || document.getElementsByTagName("head")[0]; //取得对<head>的引用
var html = document.documentElement; //取得对<html>的引用
var body = document.body; //取得对<body>的引用
2. 取得对特定的某个或某组元素的引用
  • getElementById( ) 方法
    无法通过 HTML 元素调用该方法
  • getElementsByClassName( ) 方法
    接收一个包含一或多个类名的字符串作为参数,返回带有指定类名的所有元素的 Nodelist 集合。
    var eles = document.getElementByClassName("btn banner"); // 取得所有类中包含“btn”和“banner”的元素
    
  • getElementsByTagName( ) 方法
    返回带有指定标签名的对象的集合。
var all_ele = document.getElementsByTagName("*"); //取得文档中的所有元素
var images = document.getElementsByTagName("img"); //取得页面中所有的<img>元素
alert(images.length); //输出<img>元素的数量
alert(images[0].src); //输出第一个图片元素的src属性
  • getElementsByName( ) 方法;
    返回带有指定名称的对象的集合,该方法常用于取得单选按钮。
    无法通过 HTML 元素调用该方法。

  • querySelector( ) 方法
    querySelector( ) 方法接收一个 CSS 选择符作为参数,返回与该模式匹配的第一个元素。如果没有找到匹配的元素,则返回 null

var p_first = document.querySelector("p"); //获取文档中第一个<p>  元素
var example = document.querySelector(".example"); // 获取文档中 class="example" 的第一个元素
var p_example = document.querySelector("p.example"); //获取文档中 class="example" 的第一个<p>元素
var a_target = document.querySelector("a[target]"); // 获取文档中有"target"属性的第一个<a>元素
var p_em = document.querySelector("p em"); // 获取文档中第一个<p>元素内的第一个<em>元素
  • querySelectorAll( ) 方法
    querySelectorAll( ) 方法接收一个 CSS 选择符作为参数,返回与该模式匹配的所有元素的集合。

  • 元素关系

    • children 属性 元素的children 属性中只包含元素中同样还是元素的子节点;childNodes 的元素版。
    • childElementCount 属性 返回子元素(不包括注释和文本节点)的个数
    • firstElementChild 属性 指向第一个子元素;firstChild 的元素版
    • lastElementChild 属性指向最后一个子元素;lastChild 的元素版
    • previousElementSibling 属性指向前一个同级元素;previousSibling 的元素版
    • nextElementSibling 属性指向后一个同级元素;nextSibling 的元素版
    • parentElement 属性 返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个元素节点.则 返回null
  • 操作元素

    • hasFocus( ) 方法返回布尔值,用于检测文档(或文档内的任一元素)是否获得焦点。
    • matchesSelector( ) 方法接收一个 CSS 选择符作为参数,如果调用函数与该选择符匹配,返回true;否则,返回false。
  • 元素样式

    1. classList 属性

classList 属性返回元素的class类名列表集合,返回的列表集合也有一个 length 属性来表示类的个数,该属性用于在元素中添加,移除及切换 CSS 类。classList 属性是只读的,但可以使用下面的方法修改它。

  • add(value): 将给定的字符串值添加到列表中。如果值已经存在,则不添加。
  • contains(value): 表示列表中是否存在给定的值,如果存在则返回true,否则返回false。
  • remove(value): 从列表中删除给定的字符串。
  • toggle(value): 如果列表中已经存在给定的值则删除它;如果列表中没有给定的值则添加它。

四 . 针对文本

  • 通过 nodeValue 或 data 属性 获取文本节点的内容。
  • 通过 length 属性 获取文本节点中字符的数目。
  • 使用 document.createTextNode( ) 创建新文本节点
  // 创建一个<div>元素并向其中添加一个文本节点

  var ele = document.createElement("div");
  ele.className = "message";
  var text = document.createTextNode("hello world");
  ele.appendChild(text);
  document.body.appendChild(ele);
  • 操作文本

    • appendData(text): 将text添加到节点的末尾。

    • deleteDate(offset, count): 从 offset 指定的位置开始删除 count 个字符。

    • insertData(offset, text): 在 offset 指定的位置插入 text。

    • replaceData(offset, count, text): 用 text 替换从 offset 指定的位置开始到 offset+count 为止处的文本。

    • substringData(offset, count): 提取从 offset 指定的位置开始到 offset+count 为止处的字符串。

    • splitText(offset): 从 offset 指定的位置将当前文本节点分成两个文本节点。

      分割文本节点是从文本节点中提取数据的一种常用的 DOM 技术。
    // 以上面创建的<div>元素为例
    // 分割文本节点
    var newNode = ele.firstChild.splitText(5);
    alert(ele.firstChild.nodeValue); // "hello"
    alert(newNode.nodeValue); //" world"
    alert(ele.childNodes.length); // 2

五. 样式

1. 通过 style 对象获取并操作元素的内联样式

这个 style 对象包含着通过元素 style属性设置的内联样式信息,不包含外部样式表或嵌入样式表继承层叠而来的样式。

style 对象的一些属性和方法 :

  • cssText: 读模式下返回style 属性中CSS 代码的内部表示;写模式下,赋给 cssText 的值会重写 元素 style 属性的值。
  • length: 元素 style 属性中的css 属性数量
  • parentRule: 表示css信息的CSSRule 对象
  • getPropertyValue(propertyName): 返回给定属性的字符串值
  • item(index): 返回给定位置的css属性的名称
  • removePropertyValue(propertyName): 从元素 style 属性中删除给定属性
  • setProperty(propertyName,value,priority): 将给定属性设置为相应的值,并加上优先权标志(“important” 或者一个空字符串)

2. 通过document.defaultView.getComputedStyle( )获取元素的计算样式

此方法接受两个参数:目标元素和一个伪元素字符串(例如":after"),如果不需要伪元素信息第二个参数可以为 null。

注意: 计算的样式是只读的;计算的样式包含浏览器的默认样式。

相关文章

网友评论

    本文标题:JavaScript DOM操作

    本文链接:https://www.haomeiwen.com/subject/dhypsttx.html