24、JavaScript学习笔记——DOM基本操作

DOM基本操作

DOM (Document Object Model) 文档对象模型,是HTML/XML文档的编程接口。DOM表示由多层节点构成的文档,通过DOM,开发者可以添加、删除和修改页面的各个部分

1. 对节点的增删改查

1.1 查

1.1.1 查看元素节点

document代表整个文档。

document上有很多方法:

1.1.1.1 getElementById

document.getElementById('')通过元素id来选择元素;

在IE8以下的浏览器,不区分id大小写,而且也返回匹配name属性的元素。

<div id="only"></div>
<script>
    var div1 = document.getElementById('only');
</script>
1.1.1.2 getElementsByTagName

document.getElementsByTagName(''),通过标签名选择元素,返回一个动态的包含所有指定标签名的元素的HTML集合(类数组);

<div></div>
<script>
    var div1 = document.getElementsByTagName('div')[0];
</script>

兼容性很好,在IE4以及绝大部分浏览器上都可以使用。

getElementsByTagName('')是最主流的用法。

''中的标签名可以写*getElementsByTagName('*')表示选择所有标签名的元素。

1.1.1.3 getElementsByClassName

document.getElementsByClassName(''),通过类名选择元素;

但是IE8以及IE8以下版本的浏览器中没有此方法,正因为此兼容性问题,这种方法才不是最主流的用法。

<div class="selection"></div>
<div class="selection"></div>
<div class="selection"></div>
<script>
    var div1 = document.getElementsByClassName('selection')[0];
</script>
1.1.1.4 getElementsByName

document.getElementsByName(''),选择name属性(数据名)为指定值的所有元素;

需注意,只有部分标签name属性可以生效(例如,表单、表单元素、img、iframe等)。

<input name='fruit'>
<script>
    var div1 = document.getElementsByName('fruit')[0];
</script>
1.1.1.5 querySelector

document.querySelector(''),CSS选择器,可以按照CSS选择器的方式选中元素,这个方式选中的元素默认是单独的一个。

<div>
    <strong></strong>
</div>
<div>
    <span>
        <strong></strong>
    </span>
</div>

<script>
    var div = document.querySelector('div>span strong');
</script>

在IE7和IE7以下版本中没有。

1.1.1.6 querySelectorAll

document.querySelectorAll(''),CSS选择器,可以按照CSS选择器的方式选中元素,这个方式选中的元素是一组。

<div>
    <strong></strong>
</div>
<div>
    <span>
        <strong></strong>
    </span>
</div>

<script>
    var div = document.querySelectorAll('div>span strong')[0];
</script>

在IE7和IE7以下版本中没有。

querySelector和querySelectorAll选择出来的元素不是实时的,是静态的,选中的元素不是HTML中的元素本身,而是元素的副本。

因此,基于两种query方法的两个缺点(1.兼容性;2.实时性),因此也并不常用。

1.1.2 遍历节点树

根据w3c的dom标准,文档中的所有内容都是节点,节点是dom的最小组成单元

浏览器会根据dom模型将文档解析成一系列节点,这些节点组成一个树状结构,称为dom节点树

dom节点树体现了文档的层次结构。dom节点树有两种类型,其一,dom文档节点树,其二,dom元素节点树,dom文档节点树包含文档中所有类型的节点,dom元素节点树只包含元素节点。

1.1.2.1 parentNode

node.parentNode,父节点(最顶端的parentNode为#document)

<div>
    <strong></strong>
    <span></span>
    <em></em>
</div>

<script>
    var strong = document.getElementsByTagName('strong')[0];
    var div = strong.parentNode;
</script>

若接着往上推,div的父节点是body,body的父节点是html,html的父节点是#document。

1.1.2.2 childNodes

node.childNodes,子节点们。

每个节点都有一个childNodes属性,其中包含了NodeList的实例NodeList是一个类数组对象,用于存储可以按位置存取的有序节点。

<div>
    <strong></strong>
    <span></span>
    <em></em>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

上述代码中,div的子节点有7个。

childNodes

7childNodes

除了元素节点以外还有多种节点需要考虑在内,比如上例中存在文本节点。

又例如:

<div>123
    <!-- 注释 -->
    <span></span>
    <em></em>
</div>

上述div有7个子节点,[text, comment, text, span, text, em, text]

NodeList是一个对DOM结构的查询,DOM结构的变化会自动地在NodeList中反映出来。因此NodeList是实时地活动对象,而不是第一次访问时所获得的快照。

可以使用[n].item(n)访问该节点的第n + 1个子节点(NodeList中第n + 1个元素)。

<div>
    <span>123</span>
    <strong>234</strong>
    <i></i>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

访问子节点

1.1.2.3 firstChild

node.firstChild,第一个子节点

1.1.2.4 lastChild

node.lastChild,最后一个子节点

1.1.2.5 nextSibling

node.nextSibling,后面一个兄弟节点

1.1.2.6 previousSibling

node.previousSibling,前面一个兄弟节点

1.1.3 基于元素节点树的遍历
1.1.3.1 parentElement

node.parentElement,返回当前元素的父元素节点(IE不兼容)

由于#document不是元素,所以父元素节点的顶端是html元素。

1.1.3.2 children

node.children,只返回当前元素的元素子节点

<div>123
    <!-- 注释 -->
    <span></span>
    <em></em>
</div>

div的元素子节点只有两个,[span, em]

1.1.3.3 childElementCount

node.childElementCount相当于node.children.length,当前元素节点的子元素节点个数。

1.1.3.4 firstElementChild

node.firstElementChild,返回的是第一个元素节点(IE不兼容)

1.1.3.5 lastElementChild

node.lastElementChild,返回的是最后一个元素节点(IE不兼容)

1.1.3.6 nextElementSibling

node.nextElementSibling,返回后一个兄弟元素节点(IE不兼容)

1.1.3.7 previousElementSibling

node.previousElementSibling,返回前一个兄弟元素节点(IE不兼容)

上述基于元素节点树的遍历,除了children以外,其他在IE9以下不兼容。

1.1.4 节点的类型与属性
1.1.4.1 节点的类型
  • 元素节点
  • 属性节点
  • 文本节点
  • 注释节点
  • document
  • DocumentFragment
1.1.4.2 节点的四个属性
  • nodeName

其中元素的标签名,以大写形式表示,只读

<div>123
    <!-- 注释 -->
    <strong></strong>
    <span></span>
    <em></em>
    <i></i>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

nodeName

只读,不能写入

只读

  • nodeValue

Text(文本)节点或Comment(注释)节点的文本内容,可读写。

nodeValue

元素节点的nodeValue始终为null。

  • nodeType

该节点的类型,只读。

各类型节点对应的nodeType值:

  • 元素节点:1
  • 属性节点:2
  • 文本节点:3
  • 注释节点:8
  • document:9
  • DocumentFragment:11

若使用遍历节点树的方法以及节点的nodeType属性来写一个输出某节点的所有子元素节点的函数(不能使用Children)

<div>123
    <!-- 注释 -->
    <strong></strong>
    <span></span>
    <em></em>
    <i></i>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
    // var div = strong.parentNode;

    function retElementChild (node) {
        var temp = {
            length : 0,
            push : Array.prototype.push,
            splice : Array.prototype.splice
        },
            child = node.childNodes,
            len = child.length;
        for(var i = 0; i < len; i ++){
            if(child[i].nodeType === 1){
                temp.push(child[i]);
            }
        }
        return temp;
    }
</script>

nodeType应用

  • attributes

Element节点的属性集合

<div id="only" class="a"></div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

attributes

attributes有value和name两种方法,可以读取某属性的属性名和属性值,其中value可改写属性值,name只可读。

value&name

1.1.4.3 节点的一个方法

Node.hasChildNodes(),判断该节点是否存在子节点,返回ture/false

<div id="only" class="a"></div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

hasChildNodes_exp1

<div id="only" class="a">
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

hasChildNodes_exp2

1.2 增

1.2.1 createElement

document.createElement(''),创建一个由标签名称 tagName 指定的 HTML 元素。

var div = document.createElement("div");  //创建div元素
1.2.2 createTextNode

document.createTextNode('文本内容'),创建一个新的文本节点。

1.2.3 createComment

document.createComment('注释内容'),创建一个新的注释节点。

1.2.4 createDocumentFragment

创建文档碎片节点

1.3 插

1.3.1 appendChild

某节点.appendChild(子节点)向节点添加最后一个子节点。

<script>
    var div = document.createElement('div');
    div.innerHTML = 123;
    document.body.appendChild(div);

    var text = document.createTextNode('createTextNode');
    div.append(text);  //向div节点添加最后一位子节点text
</script>

appendChild_exp1

appendChild可以向目标节点插入一个新创建的节点,也可以插入某个已有节点。但是若是将已有节点插入,则此节点位置发生移动,即该节点从之前存在的位置移动到目标节点的最后一个子节点的位置。

<div></div>
<span></span>

<script>
    var div = document.getElementsByTagName('div')[0];
    var span = document.getElementsByTagName('span')[0];

    div.appendChild(span);
</script>

原本div标签和span标签应该是兄弟元素,但是经过JS操作后,span标签变成了div标签的子元素。

appendChild_exp2

简而言之,appendChild主要有两个功能:

  • 插入新创建的节点;
  • 移动已有的节点。
1.3.2 insertBefore

node.insertBefore(a, b),在node节点的子节点b前插入节点a。

<div>
    <span></span>
</div>


<script>
    var div = document.getElementsByTagName('div')[0];
    var span = document.getElementsByTagName('span')[0];
    var strong = document.createElement('strong');

    div.insertBefore(strong, span);
</script>

insertBefore_exp1

1.4 删

removeChild

parentNode.removeChild(childNode),在父节点中删除指定子节点。removeChild的方法是将指定子节点剪切出去,可以拿个变量接收剪切出去的节点。

<div>
    <span></span>
    <strong></strong>
    <i></i>
</div>


<script>
    var div = document.getElementsByTagName('div')[0];
    var strong = document.getElementsByTagName('strong')[0];

    div.removeChild(strong);
</script>

removeChild_exp1

remove

node.remove(),销毁自身。remove方法不存在剪切,直接删除。

1.5 替换

1.5.1 replaceChild

parentNode.replaceChild(new, origin),在指定父节点中选定一个子节点origin,将其替换成节点new。

<div>
    <span></span>
    <strong></strong>
    <i></i>
</div>


<script>
    var div = document.getElementsByTagName('div')[0];
    var strong = document.getElementsByTagName('strong')[0];
    var newDiv = document.createElement('div');

    div.replaceChild(newDiv, strong);
</script>

replaceChild_exp1

2. DOM结构树

DOM结构树

注:

  • Document可以视作一个构造函数,从命名上也符合构造函数的命名规则,但是他无法使用new Document()来构造对象。
  • document --> HTMLDocument.prototype --> Document.prototype

document节点表示每个文档的根节点,DOM中称之为文档元素(documentElement)。在HTML中,根节点的唯一子节点是<html>元素,

原型链

这里给构造函数Document的原型对象Document.prototype上添加了属性abc,则构造函数HTMLDocument的原型对象HTMLDocument.prototype上继承了Document.prototype的属性abc,而document是对象,不是构造函数,其会继承HTMLDocument.prototype的属性。
上图的第二行有误,HTMLDocument是构造函数,是没有其原型对象上的属性的。

  • Document下其实有两个分支,HTMLDocument和XMLDocument,因此Document上应该写HTMLDocument和XMLDocument的共有方法,HTMLDocument上应该写适用于HTML文档节点的方法。
  • 注释节点和文本节点的方法在Comment和Text构造函数的原型对象上,这两个原型又继承自CharacterData的原型。
  • 其他依此类推。
  • 向上追溯原型:

elementProto

documentProto

textProto

  • 其他规则:

    1.getElementById方法定义在Document.prototype上,即Element节点不能使用;

    2.getElementByName方法定义在HTMLDocument.prototype上,即非HTML中的document不能使用(XML document, Element);

    3.getElementsByTagName方法定义在Document.prototypeElement.prototype上;

    4.HTMLDocument.prototype定义了一些常用属性,body,head分别指代HTML文档中的<body><head>标签;

    5.Document.prototype上定义了documentElement属性,指代文档的根元素,在HTML文档中,他总指代<html>元素;

    6.getElementsByClassNamequerySelectorAllquerySelectorDocument.prototypeElement.prototype类中均有定义。

例2.1:对于getElementsByTagName方法,可以灵活在Document.prototypeElement.prototype上交替使用。

<div>
   <span>1</span>
</div>
<span></span>
<script>
    var div = document.getElementsByTagName('div')[0];
    var span = div.getElementsByTagName('span')[0];
</script>

例2.2:HTMLDocument.prototype上的body,head属性

body&head

例2.3:Document.prototype上定义了documentElement属性

documentElement

3. Element节点的一些属性和方法

3.1 一些属性

3.1.1 innerHTML

elementNode.innerHTML;,获取此元素节点的html内容;

<div>
    <span></span>
    <strong></strong>
    <i></i>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

innerHTML_exp1

elementNode.innerHTML = "content";,将此节点的html内容替换成新的内容,覆盖之前的内容。

innerHTML_exp21
innerHTML_exp22

若不想覆盖之前的内容,则elementNode.innerHTML += "content";

innerHTML写入的内容不一定只是普通的文本,也可以以字符串的形式写入元素。

innerHTML_exp31
innerHTML_exp32

3.1.2 innerText

读写此元素节点的文本内容。

读的时候会将该节点中包括所有子节点的文本内容读出来。

<div>
    <span>123</span>
    <strong>234</strong>
    <i></i>
</div>

<script>
    var div = document.getElementsByTagName('div')[0];
</script>

innerText_exp1

改写的时候需要注意,其会将节点中的内容全部替换成这个文本,因此在有子节点或其他结构的节点慎用innerText来改写文本。

innerText_exp21
innerText_exp22

注意innerText在火狐浏览器中不兼容,但是火狐浏览器中提供了一个相同用法的属性textContent,但是textContent不适用于低版本的IE浏览器。

3.2 一些方法

3.2.1 setAttribute

elementNode.setAttribute('name', 'value'),给元素节点添加行间属性,name为属性名,value为属性值。

setAttribute_exp

3.2.2 getAttribute

elementNode.getAttribute('name'),获取元素节点的name属性的属性值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值