js基础篇(三)——DOM的各种操作

1. 什么是DOM

文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述,并定义了一种方式可以使从程序中对该结构进行访问,从而改变文档的结构,样式和内容。DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。简言之,它会将web页面和脚本或程序语言连接起来。

HTML DOM树

2.DOM节点

在 HTML DOM (Document Object Model) 中 , 每一个元素都是** 节点**:

  • 整个html文档就是是一个Document
  • 所有的HTML元素都是元素节点。
  • 所有 HTML 属性都是属性节点。
  • 文本插入到 HTML 元素是文本节点。
  • 注释是注释节点。

3. Document 对象

  • 当浏览器载入 HTML 文档, 它就会成为 document对象。
  • document 对象是HTML文档的根节点与所有其他节点(元素节点,文本节点,属性节点, 注释节点)。
  • Document对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
    ** 提示:**Document 对象是 Window对象的一部分,可通过 window.document属性对其进行访问。

4. Document 对象属性和方法

下表是DOM对象的全部属性和方法列表,在列表下面,详细地介绍了常见的原生javascript DOM操作。

属性 / 方法 描述
document.activeElement 返回当前获取焦点元素
document.addEventListener() 向文档添加句柄
document.adoptNode(node) 从另外一个文档返回 adapded节点到当前文档。
document.anchors 返回对文档中所有 Anchor 对象的引用。
document.applets 返回对文档中所有 Applet对象的引用。
document.baseURI 返回文档的绝对基础 URI
document.body 返回文档的body元素
document.close() 关闭用 document.open()方法打开的输出流,并显示选定的数据。
document.cookie 设置或返回与当前文档有关的所有 cookie
document.createAttribute() 创建一个属性节点
document.createComment() createComment()方法可创建注释节点。
document.createDocumentFragment() 创建空的 DocumentFragment 对象,并返回此对象。
document.createElement() 创建元素节点。
document.createTextNode() 创建文本节点。
document.doctype 返回与文档相关的文档类型声明 (DTD)。
document.documentElement 返回文档的根节点
document.documentMode 返回用于通过浏览器渲染文档的模式
document.documentURI 设置或返回文档的位置
document.domain 返回当前文档的域名。
document.domConfig 返回normalizeDocument()被调用时所使用的配置
document.embeds 返回文档中所有嵌入的内容(embed)集合
document.forms 返回对文档中所有 Form对象引用。
document. getElementsByClassName() 返回文档中所有指定类名的元素集合。
document.getElementById() 返回对拥有指定 id 的第一个对象的引用。
document.getElementsByName() 返回带有指定名称的对象集合。
document.getElementsByTagName() 返回带有指定标签名的对象集合。
document.images 返回对文档中所有Image对象引用。
document.implementation 返回处理该文档的 DOMImplementation 对象。
document.importNode() 把一个节点从另一个文档复制到该文档以便应用。
document.inputEncoding 返回用于文档的编码方式(在解析时)。
document.lastModified 返回文档被最后修改的日期和时间。
document.links 返回对文档中所有 AreaLink对象引用。
document.normalize() 删除空文本节点,并连接相邻节点
document.normalizeDocument() 删除空文本节点,并连接相邻节点的
document.open() 打开一个流,以收集来自任何 document.write()document.writeln() 方法的输出。
document.querySelector() 返回文档中匹配指定的CSS选择器的第一元素
document.querySelectorAll() document.querySelectorAll()是 HTML5中引入的新方法,返回文档中匹配的CSS选择器的所有元素节点列表
document.readyState 返回文档状态 (载入中……)
document.referrer 返回载入当前文档的文档的 URL
document.removeEventListener() 移除文档中的事件句柄(由 addEventListener()方法添加)
document.renameNode() 重命名元素或者属性节点。
document.scripts 返回页面中所有脚本的集合。
document.strictErrorChecking 设置或返回是否强制进行错误检查。
document.title 返回当前文档的标题。
document.URL 返回文档完整的URL
document.write() 向文档写 HTML 表达式 或 JavaScript 代码。
document.writeln() 等同于write()方法,不同的是在每个表达式之后写一个换行符。

5. 常见的原生javascript DOM操作

5.1 创建元素

  1. 创建元素节点:document.createElement()
    使用document.createElement()可以创建新元素。这个方法只接受一个参数,即要创建元素的标签名。这个标签名在HTML文档中不区分大小写,在XHTML中区分大小写。
var div = document.createElement("div");

此时,新元素尚未被添加到文档树中,因此设置各种特性均不会影响浏览器的显示。要添加到文档树,可用appendChild()insertBefore()replaceChild()。(稍后讲到)

document.body.appendChild(div);

当把元素添加到文档树中后,这个元素做的任何修改都会实时地反应到浏览器中。

  1. 创建文本节点 :document.createTextNode()
    使用document.createTextNode()来创建文本节点,这个方法接受一个参数:要插入节点的文本。与设置已有文本节点的值一样,作为参数的文本将按照HTMLXML的格式进行编码。
document.createTextNode("121212");

可以添加多个文本节点。假如两个文本节点是相邻的同胞节点,那么两个文本节点会连起来,中间不会有空格。

5.2 节点关系

IE9以前不将换行和空格看做文本节点,其他浏览器会)

文本关系如下:

<div id="div1">
    <div id="div2">2</div>
    <div id="div3">3</div>
    <div id="div4">4</div>
</div>
  1. 父节点:parentNode
    parentNode是指定节点的父节点。一个元素节点的父节点可能是一个元素(Element )节点,也可能是一个文档(Document)节点,或者是个文档碎片(DocumentFragment)节点。
    每一个节点都有一个parentNode属性。
    对于下面的节点类型: Attr, DocumentDocumentFragment,Entity, Notation,其parentNode属性返回null。如果当前节点刚刚被建立,还没有被插入到DOM树中,则该节点的parentNode属性也返回null
    var child2 = document.getElementById("div2");
    var parent = child2.parentNode;
  1. 子节点:childNodes
    childNodes 返回包含指定节点的子节点的** 集合**,该集合为即时更新的集合(live collection)。
    即时更新就是对节点元素的任意修改都会立即反映到结果里。
    var child2 = document.getElementById("div2");
    var parent = child2.parentNode;
    var allChilds = parent.childNodes;
    console.log(allChilds.length) // IE下是3,其他浏览器是7
    var nodeAdd = document.createElement("div");
    var textAdd = document.createTextNode("这是添加的文本节点");
    nodeAdd.appendChild(textAdd);
    parent.appendChild(nodeAdd);
    console.log(allChilds.length);// IE下是4,其他浏览器是8
  1. 兄弟节点:nextSiblingpreviousSibling
    nextSibling返回某节点的下一个兄弟节点,previousSibling返回某节点的上一个兄弟节点,没有的话返回null
    注意:可能因为元素换行的原因返回的是text节点。
    var child3 = document.getElementById("div3");
    var next = child3.nextSibling;
    var previous = child3.previousSibling;
    console.log(next); // IE下返回div4,其他返回text
    console.log(previous)  // IE下返回div2,其他返回text

第一个或最后一个子节点:firstChildlastChild
firstChild返回node的子节点中的第一个节点的引用,没有返回null
lastChild返回node的子节点中的最后一个节点的引用,没有返回null

    var child3 = document.getElementById("div3");
    var parent = child3.parentNode;
    var first = parent.firstChild; // IE是div2,其他是text
    var last = parent.lastChild; // IE是div4,其他是text

5.3 节点元素关系

只算元素,不算文本节点。

以下三个方法用法和节点关系完全一样,只是这三个方法只看元素节点,不管因为空格、换行造成的文本节点或者手动加上去的文本节点。
children: 返回所有** 元素子节点**(IE5+、ff3.5、opera3、chrome,但在IE8及以下会将注释节点看成一个元素节点)

以下两个IE9+才支持
nextElementSibling:返回元素的下一个兄弟元素节点
previousElementSibling: 返回元素的上一个兄弟元素节点

5.4 节点操作

  1. appendChild()
    appendChild()用于向childNodes列表的末尾添加一个节点,并且返回这个新增的节点。
    如果传入到appendChild()里的节点已经是文档的一部分了,那结果就是将节点从原来的位置转移到新位置,任何一个节点不能同时出现在文档中的多个位置。
    var returnNode = someNode.appendChild(someNode.firstChild);
    // 返回第一个节点
    console.log(returnNode === someNode.firstChild); // false
    console.log(returnNode === someNode.lastChild); // true
  1. insetBefore()
    insetBefore()可以将节点插入到某个特定的位置。这个方法接受两个参数:要插入的节点和作为参照的节点。
    插入节点后,被插入的节点变成参照节点的前一个同胞节点,同时被方法返回。 如果参照节点是null,则与appendChild()执行相同的操作。
    // 插入后成为最后一个子节点
    var returnNode = someNode.insetBefore(newNode, null);
    console.log(returnNode === someNode.lastChild); // true

    // 插入后成为第一个子节点
    var returnNode = someNode.insetBefore(newNode, someNode.firstChild);
    console.log(returnNode === newNode); // true
    console.log(returnNode === someNode.firstChild); // true

    // 插入到最后一个子节点的前面
    var returnNode = someNode.insetBefore(newNode, someNode.lastChild);
    console.log(returnNode === someNode.childNodes[someNode.childnodes.length - 2]) // true
  1. 替换节点:replaceChild()
    replaceChild()接受两个参数:要插入的节点和要被替换的节点。被替换的节点将由这个方法返回并从文档中被移除,同时由要插入的节点占据其位置。
    // 替换第一个子节点
    var returnNode = someNode.replaceChild(newNode, someNode.firstChild);

使用replaceChild()后,被替换的节点的所有关系指针都会被复制到插入的节点上面。

  1. 删除节点:removeChild()
    该方法移除节点,接受一个参数,即要移除的节点,同时该方法返回被移除的节点。只能是一个节点,不能是一组节点。
    // 移除第一个子节点
    var returnNode = someNode.removeChild(newNode, someNode.firstChild);
  1. 克隆节点:cloneNode(true/false)
    返回调用该方法的节点的一个副本。参数表示是否采用深度克隆,如果为true,则该节点的所有后代节点也都会被克隆,如果为false,则只克隆该节点本身,文本或者换行、空格这些不会复制,因为他们都是一个textNode
    克隆一个元素节点会拷贝它所有的属性以及属性值,当然也就包括了属性上绑定的事件(比如onclick="alert(1)"),但不会拷贝那些使用addEventListener()方法或者node.onclick = fn这种用JavaScript动态绑定的事件。
    注意:为了防止一个文档中出现两个ID重复的元素,使用cloneNode()方法克隆的节点在需要时应该指定另外一个与原ID值不同的ID
    var div1 = document.getElementById("div1");
    var cloneHtml = div1.cloneNode(true);
    document.body.appendChild(cloneHtml);

5.5 元素选择

HTML代码示例:

<div id="div1">
    <p id="div2" class="one" name="nameone">2</p>
    <div id="div3">3</div>
    <div id="div4" name="div2">4</div>
</div>
  • querySelector
    返回节点子树内与之相匹配的第一个Element节点。如果没有匹配的节点,则返回null
  • querySelectorAll
    返回一个包含节点子树内所有与之相匹配的Element节点列表,如果没有相匹配的,则返回一个空节点列表。
    注意:querySelector()querySelectorAll()返回的节点列表不是动态实时的(非live Collection)。这和其他DOM查询方法返回动态实时节点列表不一样。
    选择器方法接受一个或多个用逗号分隔的选择器来确定需要被返回的元素。例如,要选择文档中所有CSS的类(class)是warning或者note的段落(p)元素,可以这样写:
var special = document.querySelectorAll( "p.warning, p.note" );

也可以通过ID来查询,例如:

var el = document.querySelector( "#main, #basic, #exclamation" );

执行上面的代码后,el就包含了文档中元素的ID是mainbasicexclamation的所有元素中的第一个元素。querySelector() and querySelectorAll()里可以使用任何CSS选择器,他们都不是live Collection

var notLive = document.querySelectorAll("p");
console.log(notLive);
document.getElementById("div1").removeChild(document.getElementById("div2"));
console.log(notLive);
// 上面两个输出都是输出 `p#div2.one`的引用,没有因为删除了`p`标签而使`notLive`的结果发生变化。
  • document.getElementById()方法
返回指定 ID 的元素:
document.getElementById("demo");
  • document.getElementsByTagName()方法
返回带有指定标签名的对象的集合:
document.getElementsByTagName("P");
  • document.getElementsByName()方法,常用于表单(数组)
var x=document.getElementsByName("x");//x为元素name属性值
alert(x.length);
  • getElementsByClassName()方法
    当在 document对象上调用此方法时,会检索整个文档,包括根元素。(IE9以下不支持)要匹配多个class,则className用空格分开。
getElementsByClassName("class1 class2");

5.6 属性操作

  • setAttribute()
    添加一个新属性(attribute)到元素上,或改变元素上已经存在的属性的值。
    如果指定的属性已经存在,则其值变为传递的值。如果不存在,则创建指定的属性。也可指定为null。如果设置为null,最好使用removeAttribute()
var div2 = document.getElementById("div2"); 
div2.setAttribute("class", "new_class"); 
div2.setAttribute("id", "new_id");
  • removeAttribute()
    该方法用于移除元素的属性。
    var div2 = document.getElementById("div2");
    div2.removeAttribute("class");
  • getAttribute()
    该方法返回元素上指定属性(attribute)的值。如果指定的属性不存在,则返回null""(空字符串)。
    var div2 = document.getElementById("div2");
    var attr = div2.getAttribute("class");
    console.log(attr);
  • hasAttribute()
    hasAttribute()返回一个布尔值,指示该元素是否包含有指定的属性(attribute)。

参考资料:
常见的原生javascript DOM操作
廖雪峰的官方网站

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 本篇是基于《JavaScript高级程序设计(第3版)》DOM相关章节做的整理与归纳,概述了DOM的常见节点类型及...
    查查查查查查克阅读 2,406评论 2 7
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,621评论 2 17
  • 转载请声明出处 博客原文 随手翻阅以前的学习笔记,顺便整理一下放在这里,方便自己复习,也希望你有也有帮助吧 第一课...
    程序员poetry阅读 12,576评论 13 94
  • 话说,说起闺蜜,你们第一个想到谁,经常会有一种误区就是说:闺蜜嘛不就是整天腻歪在一起,一起洗洗澡、按按摩、烫烫头发...
    A大棋小姐阅读 794评论 0 2
  • 当黎明的第一缕阳光 悠然撒进窗棂 像羽毛一样 那般无声,轻柔的 抚摸着 干涸的大地 在睡梦中呢喃 呢喃着 故国的青...
    姀萧阅读 200评论 1 10