前端之页面元素的API(DOM) 2

1. 节点

1.1 什么是节点:

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点(文档,标签,文本,属性,注释)

  • 整个文档是一个文档节点

  • 每个HTML标签是一个标签节点/元素节点

  • HTML 标签内的文本是文本节点

  • 每个HTML标签的属性是属性节点

  • 注释是注释节点

1.2 什么是DOM树

当浏览器加载文档的时候,会将文档中每一个节点,以树状的结构组织起来,我们将这种结构称为之节点树或DOM树

1.3 节点中常用的属性和方法

1.3.1 节点类型的属性

  • nodeType 节点的类型

    • 1 元素节点

  • nodeName 节点的名称

  • nodeValue 节点值

    • 元素节点的nodeValue始终是null

  var box = document.getElementById('box');
//  console.log(box); //浏览器的优化行为: 当做标签打印在控制台上
 console.dir(box); // 以对象的形式打印在控制台上
//
//  box.nodeType  //返回节点的类型  标签节点是 1
//  box.nodeName  //返回的是节点的名称  大写的标签名
//  box.nodeValue // 标签节点的nodeValue 永远是null
  // console.log(box.childNodes); //返回box里面的所有子节点

1.3.2 节点层级的属性

  • 找儿子的属性:

    • children 返回包含所有子元素(子标签节点)的伪数组

    • childNodes 返回包含所有的子节点的伪数组

  • 找父亲的属性:

    • parentNode 返回父节点

  • 找兄弟

    • nextElementSibling 返回下一个兄弟元素

    • previousElementSibling 返回上一个兄弟元素

1.3.3 操作节点的方法

  • appendChild() 往节点的内容后面添加一个子节点

    语法: 父节点.appendChild(子节点)

//html
<div id="far">
    <div id="one"></div>
</div>
<div id="two"></div>

//js
var far = document.getElementById('far');
var two = document.getElementById('two');
far.appendChild(two);

//js执行之后的效果
<div id="far">
    <div id="one"></div>
	<div id="two"></div>
</div>
//appendChild方法会将一个节点添加到另一个节点内容的尾部,如果这个被添加的节点是本身在页面上存在的,则会有剪切的效果

insertBefore() 往节点里面添加一个子节点,这个子节点的位置在参考子节点之前

语法: node.insertBefore(要插入的节点, 参考子节点)

 //html
  <div id="far">
      <div id="one"></div>
  </div>
  <div id="two"></div>

  //js
  var far = document.getElementById('far');
  var one = document.getElementById('one');
  var two = document.getElementById('two');
  far.insertBefore(two,one)

  //js执行之后的效果
  <div id="far">
      <div id="two"></div>
      <div id="one"></div>
  </div>
  //insertBefore是插入到参考节点之前,也有剪切的效果

removeChild() 移除某个子节点

语法: node.removeChild(要被删除的节点); 返回被移除的节点

//html
<div id="far">
    <div id="son"></div>
</div>

//js
var far = document.getElementById('far');
var son = document.getElementById('son');
var result = far.removeChild(son);
console.log(result);  //<div id="son"></div>

//js执行之后的效果
<div id="far">
</div>

replaceChild() 替换节点使用其他节点替换掉自己的某个子节点

语法: element.replaceChild(替换的节点, 被替换的子节点);

//html
<div id="far">
    <div id="one"></div>
</div>
<div id="two"></div>

//js
var far = document.getElementById('far');
var one = document.getElementById('one');
var two = document.getElementById('two');
far.replaceChild(two,one);

//js执行之后的效果
<div id="far">
    <div id="two"></div>
</div>
//也有剪切的效果

cloneNode() 克隆节点

语法: element.cloneNode([true]) ;

参数是boolean值,不传参数默认是false,为浅拷贝.传true,则是深拷贝

//html
<div id="box">
    div里面的内容
	<p>p元素</p>
</div>

//js
var box = document.getElementById('box');
console.log(box.cloneNode()); //<div id="box"></div>

console.log(box.cloneNode(true)) //<div id="box">  div里面的内容 <p>p元素</p> </div>

小结:

  • 有剪切效果的方法:

    • appendChild()

    • insertBefore()

    • replaceChild()

  • 移除的方法

    • removeChild()

  • 需要传递两个参数的方法:

    • insertBefore(要插入的节点, 参考节点)

    • replaceChild(替换的节点, 被替换的节点)

2. 创建元素的三种方式

2.1 innerHTML

语法: element.innerHTML = '标签字符串'

//html
<div id="box">
    这是div中的内容
</div>

//js
var box = document.getElementById('box');
box.innerHTML = '<p>这是动态增加的p标签</p>'

//js代码执行完毕之后的结果
<div id="box">
    <p>这是动态增加的p标签</p>
</div>

2.2 docuement.write()

语法: document.write('标签字符串')

//html
<body>
</body>

//js
document.write('<div>这是动态增加的p标签</div>')

//js代码执行完毕之后的结果
<body>
    <div>
    	这是动态增加的p标签
	 </div>
</body>

2.3 document.createElement()

语法: document.createElement('标签名')

///html
<div id="box">
</div>

//js
var newElement = document.createElement('p'); //此时新创建出来的newElement并没有加入到DOM树中
var box = document.getElementById('box');
box.appendChild(newElement);// 通过appendChild这个方法,将新元素添加到已经在DOM树中的元素中,这样新
//创建出来的元素才会添加到DOM树中,然后渲染到页面上展示出来


//js代码执行完毕之后的结果
<div id="box">
    <p></p>
</div>

小结:

innerHTML 会覆盖原来元素里面的内容,并且会将新的元素直接渲染到页面上,但是不推荐用来创建表格(常用)

document.write() 也会直接渲染到页面上,并且在事件中执行的话,会覆盖原来页面的内容(慎用)

 document.write('<h1>doucment.write加上来的</h1>'); // 直接写在script里面,不会覆盖原来的内容
  
 var btn  = document.getElementById('btn');
 btn.onclick = function(){
   document.write('<h1>点击之后添加的</h1>'); //放大事件函数里面,会覆盖原来的内容
 }

docuement.createElement() 只是在内存中创建出来一个元素,但是并没有添加到DOM树中(常用)

2.4 动态创建列表案例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<button id="btn"> 点击按钮,假装去服务器拿数据</button>
<div id = "container">
  
</div>

<script>
  var arr = ['html', 'css', 'es5.0js', 'dom']
  //需求: 点击按钮,根据arr的数据,动态的创建无序列表,之后,每
  
//  1. 根据arr的数据,动态的创建无序列表
//  1.1 获取元素 btn container
    var btn = document.getElementById('btn');
    var container = document.getElementById('container');
  
//  1.2 给按钮注册点击事件
    btn.onclick = function(){
      //  1.3 在事件处理函数中,根据arr创建无序列表 innerHTML
//      container.innerHTML = '<ul><li>html</li><li>css</li><li>es5.0js</li><li>dom</li></ul>';
//      1.3.1 根据arr的数据,把字符串拼出来
      var str = '<ul>';
      for(var i = 0; i < arr.length; i++) {
         str += '<li>'+arr[i]+'</li>';
      }
      str += '</ul>';
      console.log(str);
//      1.3.2 直接赋值即可
      container.innerHTML = str;
  
      //    2. 鼠标移入到li,当前li高亮
//  2.1 获取元素
      var lis = document.getElementsByTagName('li');
//  2.2 给每一个li注册mouseover事件
      for(var i = 0; i < lis.length; i++) {
        lis[i].onmouseover = fn;
      }
  
      function fn(){
        //  2.3 在事件处理函数中
//    2.3.1 先排他
        for(var i = 0; i < lis.length; i++) {
          lis[i].style.backgroundColor = '';
        }
        //    2.3.2 让当前的里高亮 this
        this.style.backgroundColor = '#ccc';
      }
      
    }
  
</script>
</body>
</html>

2.4 动态创建表格案例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    table{
      border-collapse: collapse;
    }
  </style>
</head>
<body>
 <!--<table border="1px" width="300px">-->
   <!--<thead style="background-color: #ccc">-->
    <!--<tr>-->
      <!--<th>haha </th>-->
      <!--<th>hehe  </th>-->
    <!--</tr>-->
   <!--</thead>-->
   <!--<tbody align="center">-->
    <!--<tr>-->
      <!--<td>123</td>-->
      <!--<td>345</td>-->
    <!--</tr>-->
   <!--</tbody>-->
 <!--</table>-->
</body>
<script>
  // 数据行 中的数据
  var bodyData = [
    {name: 'zs', subject: '语文', score: 100},
    {name: 'ls', subject: '数学', score: 80},
    {name: 'sdb', subject: '体育', score: 0},
    {name: 'gw', subject: '英语', score: 59},
    {name: 'bzr', subject: '数学', score: 50}
  ];
  // 表头数据
  var headData = ['姓名', '科目', '成绩', '操作']; 
  //需求:根据数据动态创建表格, 还要增加一个删除的操作
// 1. 先创建表格的基本机构
//  1.1. 创建table标签
  var table = document.createElement('table');
  table.border = '1px';
  table.width = '500px';
//    1.2 创建thead
  var thead = document.createElement('thead');
  thead.style.backgroundColor = '#ccc';
  table.appendChild(thead);
//  1.3 创建tbody
  var tbody = document.createElement('tbody');
  tbody.align = 'center';
  table.appendChild(tbody);
  
//  2. 完成表头部分
//   2.1 创建表头中的tr
  var tr = document.createElement('tr');
  thead.appendChild(tr);
//   2.2 根据headdata中的数据,创建tr中的th
    for(var i = 0; i < headData.length; i++) {
      var th = document.createElement('th');
      th.innerText = headData[i];
      tr.appendChild(th);
    }
     
    //3. 完成表体
//  3.1.根据bodyData中对象的个数,决定创建多少个tr
  for(var i = 0; i < bodyData.length; i++) {
    var tr = document.createElement('tr');
    //3.2 创建每一个tr的td  td的个数是对象中键值对的个数 + 1
    for(var key in bodyData[i]){
      var td = document.createElement('td');
      td.innerText = bodyData[i][key];
      tr.appendChild(td);
      
    }
    // 加上后面的那个td
    var td = document.createElement('td');
    //删除是一个a元素
    var a = document.createElement('a');
    a.innerText = '删除';
    a.href = ''; //没有href属性,a元素就相当于一个普通的标签.没有超链接的效果
    td.appendChild(a);
    tr.appendChild(td);
    tbody.appendChild(tr);
    
    //给每一个a注册点击事件,在事件处理函数中,删除当前行
    a.onclick = fn;
  }
//  删除点击时,调用的函数
  function fn(){
//    删除当前行  tbody.removeChild(tr)
//    console.log(this.parentNode.parentNode);
      var result = confirm('您确定要删除吗?');
      if(result){
        tbody.removeChild(this.parentNode.parentNode);
      }
    
    return false;
  }
  
  //最后把table加到dom树上,这样就只会渲染一次
  document.body.appendChild(table);
  
   
//   //for..in
//   var obj = {
//     name: 'zs',
//     age: 18,
//     score : 100
//   }
  
//   for(var key in obj){
// //    console.log(key);
// //    console.log(obj[]);
// //    console.log(obj['age']); //中括号语法里面,允许写字符串/数字/变量
// //    console.log(obj.key); //.后面写什么就去对象中找对应的那个属性
//     console.log(obj[key]);
//   }
  
</script>
</html>

3. 扩展内容@

3.1 节点层级的其他属性

  • firstChild 返回第一个子节点

  • lastChild 返回最后一个子节点

  • firstElementChild 返回第一个子元素

  • lastElementChild 返回最后一个子元素

  • nextSibling 返回下一个兄弟节点

  • previousSibling 返回上一个兄弟节点

3.2 节点属性的兼容性问题:

  • children 在ie6-8浏览器中返回的内容会包含注释节点

  • firstElementChild ie9+才支持

  • lastElementChild ie9+ 才支持

  • nextElementSibling ie9+才支持

  • previousElementSibling ie9+才支持

3.3 创建元素的三种方式的效率问题

  • document.write() 和 innerHTML都是解析字符串执行效率相同

  • document.createElement 直接创建元素,执行效率比前两者高很多

  • document.write() 和 innerHTML优化后的代码效率跟document.createElement类似

   var d1 = +new Date();
        
        for ( var i = 0; i < 1000; i++ ) {
            document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
        }
        var d2 = +new Date();
        console.log( d2 - d1 );
    }
    fn();
   function fn() {
        var d1 = +new Date();
        var array = [];
        for ( var i = 0; i < 1000; i++ ) {
            array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
        }
//        console.log(array);
        document.body.innerHTML = array.join('');
        var d2 = +new Date();
        console.log( d2 - d1 );
    }
    fn();

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值