一、节点之间的层级:父子兄

节点主要 有父子兄关系

1.父节点操作

语法:子节点.parentNode,得到的是一个元素不是集合
比如我选了一个类名叫zzy的元素

var zzy = document.querySelector('.zzy');

那么要获取zzy 的父节点,只需要zzy.parentNode

console.log(zzy.parentNode);

注意,得到的时离该元素最近的父节点(亲爹),如果找不到父节点,就返回null

2.子节点操作

(1)父节点.childNodes(目测用的不多)

这个得到的是所有的子节点,除了我们想要的元素节点,还有换行、空格等文本节点,所以要想拿到元素,就要循环遍历,因为元素节点nodeType是1,属性2,文本3。这个真的是麻烦的一塌糊涂

(2)父节点.children(这个才是常用的)

这个只返回子元素节点,其他的都滚蛋,不错

3.获取第一个子元素和最后一个子元素

父节点.firstChild和父节点,lastChild,和父节点.childNodes差不多,返回的是所有类型节点中的第一个和最后一个,所以这两个用的不多,真正带劲的是:
父节点.firstElementChild和父节点.lastElementChild,这俩都是返回的第一个和最后一个元素节点,不错
但是!这个不错的方法,只有IE9以上支持。

这可咋办!

不要怕,在实际开发中,我们都会用父元素.children[i],既没有兼容问题,又能返回首尾元素节点
比如这里有这么几个东西

<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li>
</ul>

那么首尾元素分别是:

var ul = document.querySelector('ul');
console.log(ul.children[0]);
console.log(ul.children[ul.children.length - 1]);

案例:下拉菜单

下拉菜单的常用布局:头部放个ul,ul里有几个li,每个li里面上边a,下边放ul包几个li
先放html和css

* {margin: 0;padding: 0;box-sizing: border-box;
}li {list-style: none;
}a {color: black;text-decoration: none;
}.box {margin: 100px auto;width: 400px;height: 50px;
}.box>li {float: left;/* position: relative; */width: 100px;height: 50px;line-height: 50px;text-align: center;
}.box>li a {display: inline-block;width: 100px;height: 50px;
}.box>li a:hover {background-color: #ccc;
}.box ul {display: none;/* position: absolute; */left: 0;top: 50px;border-left: 1px solid red;border-right: 1px solid red;
}.box ul li {border-bottom: 1px solid red;
}.box li ul li:hover {background-color: rgb(247, 149, 149);
}
   <ul class="box"><li><a href="#">微博</a><ul><li>私信</li><li>评论</li><li>@我</li></ul></li><li><a href="#">微博</a><ul><li>私信</li><li>评论</li><li>@我</li></ul></li><li><a href="#">微博</a><ul><li>私信</li><li>评论</li><li>@我</li></ul></li><li><a href="#">微博</a><ul><li>私信</li><li>评论</li><li>@我</li></ul></li></ul>

然后是JavaScript,其实这部分代码比较好理解,就是我第一步获取元素老写错

   var box = document.querySelector('.box'); //这个地方老写错……var lis = box.children;  //得到4个lifor (var i = 0; i < lis.length; i++) {lis[i].onmouseover = function () {//鼠标放上去,这个li的第二个孩子(ul)显示this.children[1].style.display = 'block';}lis[i].onmouseout = function () {this.children[1].style.display = 'none';}}

4.获取兄弟节点

和父子一样,有个获取下一个(全部中的下一个)节点和上一个节点的方法,没什么p用

真正有用的是下面这个,但是又有兼容性问题

那咋办呢?实际上兄弟节点用的少,了解下就行了

二、节点的增删

1.创建和添加元素节点

先创建,再添加
比如我要创建一个li的元素节点

var myli = document.createElement('li');

(1)父元素.appendChild(要添加的元素)

先获取它的父元素,然后把我创建的li添加进去,默认是添加到父元素的尾部

var ul = document.querySelector('ul');
//把我创建的li放到ul里面去,默认添加到尾部
ul.appendChild(myli);

(2)父元素.insertBefore(要添加的元素节点,添加到谁前面)

下面这个代码就是在ul的第一个孩子前添加我创建的li

ul.insertBefore(myli, ul.children[0]);

(3)简单添加留言案例

<textarea name="" id="content" cols="30" rows="10"></textarea> <button>发布</button>
<ul class="my"><li></li>
</ul>

注意获取textarea和input里面的值是.value

//简单留言案例var content = document.querySelector('textarea');//获取文本域var my = document.querySelector('.my');  //获取ulvar btn = document.querySelector('button');  //获取button//点击按钮就生成一个li,添加到ul里btn.onclick = function () {if (content.value == '') {alert('您没有输入任何内容');} else {var li = document.createElement('li');li.innerHTML = content.value;// my.appendChild(li);my.insertBefore(li, my.children[0]);}}

2.删除元素节点

(1)使用父元素.removeChild(子元素)

<button>删除</button>
<ul><li>zzy</li><li>aoaoao</li><li>3213</li>
</ul>
 var ul = document.querySelector('ul');var btn = document.querySelector('button');btn.onclick = function () {if (ul.children.length != 0) {ul.removeChild(ul.children[0]);} else {//如果删完了就禁用按钮this.disabled = true;}}

(2)添加留言和删除留言(上面案例的升级版)

这里遇到个问题就是删除留言的代码要放到btn.onclick里面,要不然会先执行下面这段(注意代码的执行顺序),等点击btn的时候才添加a标签,那样先获取的as就是空了

//简单添加删除留言案例
var content = document.querySelector('textarea');//获取文本域
var my = document.querySelector('.my');  //获取ul
var btn = document.querySelector('button');  //获取button
//1.添加留言:点击按钮就生成一个li,添加到ul里
btn.onclick = function () {if (content.value == '') {alert('您没有输入任何内容');} else {var li = document.createElement('li');//把textarea里面的内容取过来,然后再添加一个a标签li.innerHTML = content.value + "<a href='javascript:;'>删除</a>";//卧槽,还能这么写// my.appendChild(li);my.insertBefore(li, my.children[0]);}//2.删除留言//先获取a标签//这段代码要放到btn.onclick里面,要不然会先执行下面这段,等点击btn的时候才添加a标签,那样as就是空了var as = document.querySelectorAll('a');for (var i = 0; i < as.length; i++) {as[i].onclick = function () {my.removeChild(this.parentNode);}}
}

3.复制元素节点

(1)语法:node.cloneNode()

<ul><li>1</li><li>2</li><li>3</li>
</ul>

把ul里的第一个孩子复制过来,放到ul的尾部

 var ul = document.querySelector('ul');var li1 = ul.children[0].cloneNode();ul.appendChild(li1);

(2)浅拷贝和深拷贝

node.cloneNode()括号里默认是false,也就是浅拷贝,只copy元素不copy内容
node.cloneNode(true),如果括号里是true就是深拷贝,copy元素和内容

三、动态生成表格

创建html和css

table {width: 400px;margin: 100px auto;text-align: center;border-collapse: collapse;
}th,
td {border: 1px solid #333;
}thead tr {height: 40px;background-color: #ccc;
}tbody tr {height: 30px;
}
<table cellspacing="0"><thead><tr><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></tr></thead><tbody></tbody>

1.先准备好学生的数据,以对象形式存储在数组中

var datas = [{names: '彭于晏',subject: 'javascript',score: 87},{names: '小婷',subject: 'javascript',score: 100}, {names: '张大仙',subject: 'javascript',score: 99}, {names: '刘亦菲',subject: 'javascript',score: 60}
]

2.创建行tr

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);
}

3.创建行里面的单元格td

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);//3.行里面创建单元格tdfor (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次var td = document.createElement('td');tr.appendChild(td);
}

4.添加td里面的数据

每个单元格的数据可以用对象里的datas[i][k]来获取
我的写法:
我一开始想获取所有的td元素数组,然后设置一个flag来获取相应的td,但是我发现这样的话因为每次循环td个数都在增加,所以td的数组也在变化,所以intd[flag]并不能添加每一行的数据,每次添加都是添加到第一行,除非flag=3*i。后来想了个办法,可以使用tr.children[flag],这样就可以实现给每行的每个单元格添加相应的数据

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);//3.行里面创建单元格tdvar flag = 0;for (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次var td = document.createElement('td');tr.appendChild(td);// var intd = document.getElementsByTagName('td'); //这是获取所有的td,包括前几行,不对// intd[flag].innerHTML = datas[i][k];tr.children[flag].innerHTML = datas[i][k];flag++;}
}

看了老师的写法,我才知道我想多了……
其实只需要每次添加完td后,直接往td塞数据,然后再添加到tr里就行

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);//3.行里面创建单元格tdfor (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次var td = document.createElement('td');//给每个单元格塞数据td.innerHTML = datas[i][k];tr.appendChild(td);}
}

5.添加删除操作的链接

var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);//3.行里面创建单元格tdfor (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次var td = document.createElement('td');//4.给每个单元格先塞数据,再放到tr里td.innerHTML = datas[i][k];tr.appendChild(td);}//5.添加删除操作的链接var tdend = document.createElement('td');tdend.innerHTML = "<a href='javascript:;'>删除</a>";tr.appendChild(tdend);
}

6.最后一步,给删除操作添加删除事件

//2.先创建行tr,有几个人就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {//先创建,再添加,二者要绑定在一起var tr = document.createElement('tr');tbody.appendChild(tr);//3.行里面创建单元格tdfor (var k in datas[i]) {  //遍历对象,k是属性的个数,有几个属性就循环几次var td = document.createElement('td');//4.给每个单元格先塞数据,再放到tr里td.innerHTML = datas[i][k];tr.appendChild(td);}//5.添加删除操作的链接var tdend = document.createElement('td');tdend.innerHTML = "<a href='javascript:;'>删除</a>";tr.appendChild(tdend);
}//6.给删除按钮添加事件
var as = document.querySelectorAll('a'); //这里一定要是All
for (var i = 0; i < as.length; i++) {as[i].onclick = function () {tbody.removeChild(this.parentNode.parentNode);}
}

四、innerHTML和createElement创建元素谁效率更高?


如果innerHTML是拼接字符串标签的话,拼1000个要用3000ms,但是如果采用数组形式拼接,只用7ms
如果用createElement创建1000个同样的元素,大概18ms

DOM(三):节点操作——获取父子兄节点(查)、添加和删除元素节点相关推荐

  1. js添加和删除元素节点

    js添加和删除元素节点 <!DOCTYPE html> <html> <head><meta charset="UTF-8">< ...

  2. python列表的添加操作_python3_列表(修改,添加和删除元素操作)

    前言:列表的定义:列表是由一系列按特定顺序排列的元素组成.即列表是一个有序集合. 1.修改列表元素 由前言知列表是一个有序集合,因此在修改列表元素时我们需指定列表名和要修改的元素的索引,再指定该元素的 ...

  3. jquery的DOM节点操作(删除元素节点)

    1.删除元素节点 在操作页面时,删除多余或者指定的页面元素是非常必要的. jquery中提供了remove()方法来删除元素. 其语法格式如下: 删除元素节点示例代码: <!DOCTYPE ht ...

  4. html点击按钮清空元素,jQuery怎么删除元素节点

    jquery删除元素节点的方法非常简单,我们可以直接通过remove()方法来进行删除节点操作. 下面我们就结合简单的代码示例,给大家详细介绍jquery删除节点元素的方法. 代码实例如下: jque ...

  5. jquery追加html后删除,jquery动态增加删除元素节点

    jquery动态增加删除元素节点 对于语言编程,不同的思路有着不同的解决办法,Jquery对于动态的ul-li节点的增加删除实力操作思路: 1.做一个按钮用于增加li节点,使用Jquery:appen ...

  6. java对文本文件进行操作:读取、修改、添加、删除、重命名等

    java对文本文件进行操作:读取.修改.添加.删除.重命名等 Java IO 也称为IO流,IO = 流,它的核心就是对文件的操作,对于 字节 .字符类型的输入和输出流. IO是指对数据流的输入和输出 ...

  7. 节点操作之父子节点和下拉框

    1.父级节点:node.parentNode node.parentNode,返回某节点的父节点,返回最近一个父节点,如果没有父节点返回null. <!-- 父级节点:node.parentNo ...

  8. 节点操作-创建createElement||appendChild-/追加-/插入insertBefore-/替换replaceChild-/删除remove-克隆元素 cloneNode(增删改查)

    01-节点操作-创建元素·createElement||appendChild <body><div class="box"><span>我是前 ...

  9. javascript删除元素节点

    在javascript操作dom树的时候可能会经常遇到增加,删除节点的事情,比如一个输入框后一个增加按钮,一个删除按钮,点击增加就增加 个输入框,点击删除就删除对应的输入框.在一些js框架,如Prot ...

最新文章

  1. eclipse自动关闭的原因
  2. linux nand 坏块_Nand Flash 中的坏块(Bad Block)
  3. 信息学奥赛一本通 1312:【例3.4】昆虫繁殖
  4. mysql备份时过滤掉某些库 以及 去掉Warning: Using a password on the command line interface can be insecure.提示信息...
  5. 如何做好网站内部优化
  6. 月结 sap_SAP运行物料账的常见错误
  7. display:inline-block;在各浏览器下的问题和终极兼容办法
  8. Spark自定义排序
  9. sap后台配置原因代码_SAP FI后台配置清单
  10. SpringBoot 启动报 Stopping service [Tomcat]
  11. 2021-11-21 使用for循环打印出大写字母ascll码对照表。
  12. MBTI性格测试:你是哪种动物?准到可怕!
  13. win10更新后D盘变成CD驱动器
  14. 【ros】初学ROS的学习笔记——创建Publisher
  15. 硬件设计2---什么是电阻?
  16. 9.14 PreScan自动驾驶建模与仿真技术培训(第三期)
  17. 如何快速计算汉字笔画数
  18. 大数据之路系列之Linux命令(01)
  19. js中当等于最小值是让代码不执行_28 个JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已...
  20. 【MM系列】SAP SAP的账期分析和操作

热门文章

  1. C# Linq中的Join使用
  2. 青云QingCloud助力掌众金服挖掘数据价值
  3. vivado-vscode 新手使用说明 - verilog
  4. OpenCv 入门 -- 对小猪佩琪进行平滑处理
  5. 解决IPad和IPhone接收exchange邮件…
  6. count(字段),count(*)和count(1)的区别
  7. Valine - 自定义邮件回复提示
  8. 人物关系 人脸识别_「人脸识别」可以代替「人像鉴定」吗?
  9. EXCEL:隐藏的模块中的编译错误:mSetMenu
  10. 【汇智学堂】JAVA多线程实现的小游戏-弹球-1