JavaScript基础——节点操作

节点概念

节点类型

节点常见类型有以下几种:

1.元素结点    Node.ELEMENT_NODE(1)
2.属性结点    Node.ATTRIBUTE_NODE(2)
3.文本结点    Node.TEXT_NODE(3)


结点操作

节点层级

  利用DOM树可以将结点划分为不同层级关系,获取与之相关联节点进行操作,常见的是父子级关系

一、父级节点

node.parentNode

例如:实现点击test结点中的close结点让test消失,就可以这么写。

<div id='test'>
    <div id='close'>x</div>
</div>
<script>
    var close = this.document.querySelector('#close');
    close.onclick = function(){
        close.parentNode.remove();
    }
</script>

二、子节点

1.获取所有子节点
node.childNodes // 标准

例如:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
<script>
    var ul = this.document.querySelector('ul');
    console.log(ul.childNodes);
</script>

我们要将ul中的childNodes将所有4个li打印出来,但是将上述代码进行输出时,却发现得到的数组长度为9,如下所示。

image

展开该数组不难发现,除了4个元素结点li外还有5个文本结点,这5个并不是li中的文本,因为li中的文本已经不属于ul的子节点

那么这5个文本类型的结点是ul的?可ul中并没有文本啊?

别忘了,其实换行符也是属于一个字符,这5个文本结点正好对应ul中li与li之间的换行符。

childsNode返回值里面包含的是所有的子节点,如果想要获取里面的元素结点,则需要专门处理。一般不提倡使用。

2.获取所有子元素结点
parentNode.children // 非标准

children是一个只读属性,返回所有子元素的节点。它只返回元素结点,其他结点均不返回。
虽热children是非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。


3.获取第一个和最后一个结点

获取第一个/最后一个节点,包含文本结点、元素结点等。

node.firstChild // 获取第一个子节点
node.lastChild  // 获取最后一个子节点

获取第一个/最后一个节点,只获取子元素结点。

node.firstElementChild // 获取第一个子元素节点
node.lastElementChild  // 获取最后一个子元素节点
这两个方法有兼容性问题,IE9以上才支持

获取第一个/最后一个节点,只获取子元素结点。(实际开发中为了照顾兼容性的写法)

node.children[0] // 获取第一个子元素节点
node.children[node.children.length] // 获取最后一个子元素节点

三、兄弟结点

获取上一个/下一个兄弟节点,包含文本节点、元素节点等。

node.nextSibling      // 下一个兄弟节点
node.previousSibling  // 上一个兄弟节点

获取上一个/下一个兄弟节点,只获取元素节点。

node.nextElementSibling   // 上一个兄弟元素节点
node.previousElementSibling   // 上一个兄弟元素节点
解决办法:自己封装一个兼容性的函数
function getNextElementSibling(element){
    var el = element;
    while(el = el.nextSibling){ // 注意这里是赋值运算符并不是比较,循环条件是el不为null
        if(el.nodeType==1)return el;
    }
    return null;
}

元素创建及添加

一、创建元素

1.document.createElement()创建元素

通过 document.createElement(tagName); 方法创建元素
譬如要创建一个div标签,那么就可以通过这种方式进行创建,如下:

var newElement = document.createElement('div');

特点:创建多个元素效率低一点点,但结构更清晰

2.element.innerHTML()创建元素

通过element.innerHTML属性创建元素
如下所示,在文档中创建一个div元素

document.body.innerHTML+='div';

特点:将内容写入某个DOM节点中,不会导致页面重绘。另外,采用innerHTML创建多个元素效率更高(采用数组,不要采用字符串拼接的方式),结构稍微复杂。
如下所示,使用innerHTML创建一百个div元素

var divs =  [];
for(var i = 0 ; i < 100; i++){
    divs.push('<div id="div'+i+'">这是第'+i"个div</div>);
}
document.body.innerHTML=divs.join('');

3.document.write()创建元素

通过document.write(HTML)方法创建元素
如下所示,在文档中创建一个div元素:

document.write('div')

特点:直接写入页面的内容流,但是文档流执行完毕,则它会导致页面重绘

二、添加元素

创建一个结点之后并不能直接在文档之中显示,需要在文档中的某个节点之下进行添加,才能让新建的结点存在于文档之中
可以通过parentNode.appendChild(nodeObject)方法进行添加
譬如要在一个id为test的div元素中添加新建元素节点a,就可以怎么做:

var test  = document.querySelector('#test');
var newElement = document.createElement('a');
test.appendChild(newElement);

三、删除元素

可以通过 node.removeChild(child) 方法进行删除节点的操作
node.removeChild(child)方法从DOM中删除一个子节点,返回删除的节点
如下所示,删除一个元素下的第一个元素:

element.removeChild(element.children[0]);

四、复制元素

可以通过node.cloneNode()方法来进行复制节点的操作。

括号内的参数若为false或者空,则是浅拷贝,即只是克隆复制节点本身,不克隆其中的子节点。如果括号内为true,则是深拷贝,会连节点中的所有子节点一并拷贝。
如下所示,深拷贝一个结点:
var newNode = node.cloneNode(true);

拓展(常见的节点定性操作)

使用 document.createNode()动态创建元素节点后,无法再使用html定义元素节点的id、类名、内容等。这时就需要通过节点操作,来进行动态添加。

1.添加类名
node.className = 'content' ; // 等价于↓
<div class='content'></div>
2.添加id
node.id = 'content'; // 等价于↓
<div class='content'></div>
3.添加内容
node.innerHtml = '这是一个元素标签'; // 等价于↓
<div>这是一个元素标签</div>
posted @ 2022-05-12 01:04  maplerain  阅读(426)  评论(0编辑  收藏  举报