JavaScript中DOM

1、DOM对象介绍

(1)什么是DOM
DOM:Document Object Model,文档对象模型。
作用:是一套规范文档内容的通用型标准。

(2)DOM HTML节点树
DOM HTML指的是DOM中为操作HTML文档提供的属性和方法。
文档(Document)表示HTML文件。
文档中的标签称为元素(Element)。
文档中的所有内容称为节点(Node)。
因此,一个HTML文件可以看作是所有元素组成的一个节点树,各元素节点之间有级别的划分 。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>测试</title>
  </head>
  <body>
    <a href="#">链接</a>
    <p>段落...</p>
  </body>
</html>

在这里插入图片描述
HTML文档根据节点作用,分为标签节点、文本节点、属性节点和注释节点。
各节点之间的关系,又可分为以下几个方面:
a、根节点:标签是整个文档的根节点,有且仅由一个。
b、子节点:指的是某一个节点的下级节点。
c、父节点:指的是某一个节点的上级节点。
d、兄弟节点:两个节点同属于一个父节点。

(3)DOM对象的继承关系

<div id="test"></div>
<script>
  var test = document.getElementById('test');
  console.log(test);  	      // 输出结果:<div id="test"></div>
  console.log(test.__proto__);   // 输出结果:HTMLDivElement { …… }
</script>

在这里插入图片描述
总结
document和Element是两种不同类型的节点(Node)对象。
它们不仅能够使用Node对象的一系列属性和方法完成节点操作。
也可以使用特有的属性和方法完成不同类型节点的操作。

<div id="test"></div>
<script>
  var test = document.getElementById('test');
  console.log(test.nodeName);        // 通过节点方式获取节点名,输出结果:DIV
  console.log(test.tagName);         // 通过元素方式获取标签名,输出结果:DIV
  console.log(document.nodeName);    // document属于节点,输出结果:#document
  console.log(document.tagName);     // document不属于元素,输出结果:undefined
</script>

除了document和Element对象,还有其他几种类型的节点对象也继承Node对象,如文本(Text)、注释(Comment)等。
在这里插入图片描述

<script>
  var test = document.getElementById('test');
  test.nodeType === Node.ELEMENT_NODE;         // 比较结果:true
  document.nodeType === Node.DOCUMENT_NODE;    // 比较结果:true
<script>

注意:DOM与document的关系
当浏览器下载到一个网页,通常是 HTML,这个 HTML 就叫 document(当然,这也是 DOM 树中的一个 node),document 通常是整个 DOM 树的根节点。这个 document 包含了标题(document.title)、URL(document.URL)等属性,可以直接在 JS 中访问到。

在一个浏览器窗口中可能有多个 document,例如,通过 iframe 加载的页面,每一个都是一个 document。

在 JS 中,可以通过 document 访问其子节点(其实任何节点都可以),如

document.body;document.getElementById(‘xxx’);

2、HTML元素操作

(1)获取操作的元素
a、通过document对象的方法和属性
document对象提供了一些用于查找元素的方法,利用这些方法可以根据元素的id、name和class属性以及标签名称的方式获取操作的元素。
在这里插入图片描述

<ul id="ul">
  <li>PHP</li><li>JavaScript</li>
  <ul><li>jQuery</li><ul>
</ul>
<script>
  var lis = document.getElementById('ul').getElementsByTagName('li');
  console.log(lis);    // 输出结果:(3) [li, li, li]
</script>

<script>
  var lis = document.getElementById('ul').children;
  console.log(lis);    // 输出结果:(3) [li, li, ul]
</script>

<li id="test" name="test">test</li>
<script>
  var lis1 = document.getElementsByTagName('li');    // 获取标签名为li的对象集合
  var test = document.getElementById('test');        // 获取id为test的li元素对象
  console.log(lis1.test === test);                   // 比较结果:true
  var lis2 = document.getElementsByName('test');     // 获取name名为test的对象集合
  console.log(lis1.test === lis2[0]);                // 比较结果:true
</script>

除了document.getElementById()方法返回的是拥有指定id的元素外,其他方法返回的都是符合要求的一个集合。若要获取其中一个对象,可以通过下标的方式获取,默认从0开始。

document对象提供一些属性,可用于获取文档中的元素。例如,获取所有表单标签、图片标签等。
在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script>
      var body = document.getElementsByTagName('body')[0];    // 获取body元素
      var html = document.getElementsByTagName('html')[0];    // 获取html元素
      console.log(document.body === body);                    // 比较返回结果,输出结果:true
      console.log(document.documentElement === html);         // 比较返回结果,输出结果:true
    </script>
  </body>
</html>

在这里插入图片描述
document对象的body属性用于返回body元素。
document对象的documentElement属性用于返回HTML文档的根节点html元素。

注意:
通过document对象的方法与document对象的属性获取的操作元素表示的都是同一对象。如document.getElementsByTagName(‘body’)[0]与document.body全等。

HTML5新增的document对象方法
HTML5中为更方便获取操作的元素,为document对象新增了两个方法,分别为querySelector()和querySelectorAll()。
a、querySelector()方法用于返回文档中匹配到指定的元素或CSS选择器的第1个对象的引用。
b、querySelectorAll()方法用于返回文档中匹配到指定的元素或CSS选择器的对象集合。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>获取操作的元素</title>
  </head>
  <body>
    <div id="box">box</div>
    <div class="bar">bar</div>
    <div name="main">main</div>
    <script>
      console.log(document.getElementById('box'));            // 获取id为box的元素
      console.log(document.getElementsByClassName('bar'));    // 获取所有class为bar的元素
      console.log(document.getElementsByTagName('div'));      // 获取所有标签为div的元素
      console.log(document.getElementsByName('main'));        // 获取所有name为main的元素
    </script>
    <script>
      var box = document.getElementById('box');               // 根据id获取元素对象
      var divs = document.getElementsByTagName('div');        // 根据标签名获取对象集合
      console.log(divs[0] === box);                           // 输出结果:true
    </script>
    <script>
      console.log(document.querySelector('div'));             // 获取匹配到的第1个div
      console.log(document.querySelector('#box'));            // 获取id为box的第1个div
      console.log(document.querySelector('.bar'));            // 获取class为bar的第1个div
      console.log(document.querySelector('div[name]'));       // 获取含有name属性的第1个div
      console.log(document.querySelector('div.bar'));         // 获取文档中class为bar的第1个div
      console.log(document.querySelector('div#box'));         // 获取文档中id为box的第1个div
    </script>
  </body>
</html>

元素对象提供了children属性用来获取指定元素的子元素

<body>
<ul id="ul">
  <li>PHP</li><li>JavaScript</li>
  <ul><li>jQuery</li><ul>
</ul>
</body>
<script>
var lis = document.getElementById('ul').children;
console.log(lis);		// 输出结果:(3) [li, li, ul]
</script>

元素对象的children属性返回的也是对象集合,若要获取其中一个对象,也需通过下标的方式获取,默认从0开始。
另外,document对象中也有children属性,它的第一个子元素通常是html元素。

(2)元素内容
JavaScript中,若要对获取的元素内容进行操作,则可以利用DOM提供的属性和方法实现。
在这里插入图片描述
属性属于Element对象,方法属于document对象。
innerHTML在使用时会保持编写的格式以及标签样式。
innerText则是去掉所有格式以及标签的纯文本内容。
textContent属性在去掉标签后会保留文本格式。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>元素内容操作</title>
  </head>
  <body>
    <div id="box">
      The first paragraph...
      <p>
        The second  paragraph...
        <a href="http://www.example.com">third</a>
      </p>
    </div>
    <script>
      var box = document.getElementById('box');
      console.log(box.innerHTML);
      console.log(box.innerText);
      console.log(box.textContent);
    </script>
  </body>
</html>

注意:
innerText属性在使用时可能会出现浏览器兼容的问题。因此,推荐在
开发时尽可能的使用innerHTML获取或设置元素的文本内容。同时,innerHTML属性和document.write()方法在设置内容时有一定的区别,前者作用于指定的元素,后者则是重构整个HTML文档页面。因此,读者在开发中要根据实际的需要选择合适的实现方式

案例:改变盒子大小

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <style>
      .box{width:50px;height:50px;background:#eee;margin:0 auto;}
    </style>
  </head>
  <body>
    <div id="box" class="box"></div>
    <script>
      var box = document.getElementById('box');
      var i = 0;                     // 保存用户单击盒子的次数
      box.onclick = function() {     // 处理盒子的单击事件
        ++i;
        if (i % 2) {                 // 单击次数为奇数,变大
          this.style.width = '200px';
          this.style.height = '200px';
          this.innerHTML = '大';
        } else {                     // 单击次数为偶数,变小
          this.style.width = '50px';
          this.style.height = '50px';
          this.innerHTML = '小';
        }
      };
    </script>
  </body>
</html>

(3)元素属性
在DOM中,为了方便JavaScript获取、修改和遍历指定HTML元素的相关属性,提供了操作的属性和方法。
在这里插入图片描述
利用attributes属性可以获取一个HTML元素的所有属性,以及所有属性的个数length。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>元素属性操作</title>
    <style>
      .gray{background: #CCC;}
      #thick{font-weight: bolder;}
    </style>
  </head>
  <body>
    <div>test word.</div>
    <script>
      // 获取div元素
      var ele = document.getElementsByTagName('div')[0];
      // ① 输出当前ele的属性个数
      console.log('未操作前属性个数:' + ele.attributes.length);
      // ② 为ele添加属性,并查看属性个数
      ele.setAttribute('align', 'center');
      ele.setAttribute('title', '测试文字');
      ele.setAttribute('class', 'gray');
      ele.setAttribute('id', 'thick');
      ele.setAttribute('style', 'font-size:24px;border:1px solid green;');
      console.log('添加属性后的属性个数:' + ele.attributes.length);
      // ③ 获取ele的style属性值
      console.log('获取style属性值:' + ele.getAttribute('style'));
      // ④ 删除ele的style属性,并查看剩余属性情况
      ele.removeAttribute('style');
      console.log('查看所有属性:');
      for (var i = 0; i < ele.attributes.length; ++i) {
        console.log(ele.attributes[i]);
      }
    </script>
  </body>
</html>

(4)元素样式
回顾:通过元素属性的操作修改样式。
元素样式语法:style.属性名称。
要求:需要去掉CSS样式名里的中横线“-”,并将第二个英文首字母大写。
举例:设置背景颜色的background-color,在style属性操作中,需要修改为backgroundColor。
在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <div id="box"></div>
    <script>
      var ele = document.getElementById('box');    // 获取元素对象
      ele.style.width = '100px';
      ele.style.height = '100px';
      ele.style.backgroundColor = 'red';
      ele.style.transform = 'rotate(7deg)';
    </script>
  </body>
</html>

注意:
CSS中的float样式与JavaScript的保留字冲突,在解决方案上不同的浏览器
存在分歧。例如IE911、Chrome、FireFox可以使用“float”和“cssFloat”,Safari浏览器使用“float”,IE68则使用“styleFloat”。

问题:一个元素的类选择器可以有多个,在开发中如何对选择器列表进行操作?
原来的解决方案:利用元素对象的className属性获取,获取的结果是字符型,然后再根据实际情况对字符串进行处理。
HTML5提供的办法:新增的classList(只读)元素的类选择器列表。

举例:若一个div元素的class值为“box header navlist title”,如何删除header?
HTML5解决方案:div元素对象.classList.toggle(“header”);

除此之外,classList属性还提供了许多其他相关操作的方法和属性。
在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>classList的使用</title>
    <style>
      .bg{background:#ccc;}
      .strong{font-size:24px;color:red;}
      .smooth{height:30px;width:120px;border-radius:10px;}
    </style>
  </head>
  <body>
    <ul>
      <li>PHP</li>
      <li class="bg">JavaScript</li>
      <li>C++</li>
      <li>Java</li>
    </ul>
    <script>
      // 获取第2个li元素
      var ele = document.getElementsByTagName('li')[1];
      // 若li元素中没有strong类,则添加
      if (!ele.classList.contains('strong')) {
        ele.classList.add('strong');
      }
      // 若li元素中没有smooth类,则添加;若有删除
      ele.classList.toggle('smooth');
      console.log('添加与切换样式后:');
      console.log(ele);
    </script>
    <script>
      ele.classList.remove('bg');
      console.log('删除后:');
      console.log(ele);
    </script>
  </body>
</html>

3、DOM节点操作

(1)获取节点
由于HTML文档可以看做是一个节点树,因此,可以利用操作节点的方式操作HTML中的元素。
在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script>
      // 访问document节点的第1个子节点
      console.log(document.firstChild);                // 访问结果:<!DOCTYPE html>
      // 访问document节点的第2个子节点
      console.log(document.firstChild.nextSibling);    // 访问结果:<html>……</html>
    </script>
  </body>
</html>

注意:
childNodes属性与前面学习过的children属性的区别。
相同点:都可以获取某元素的子元素。
不同点: childNodes属性用于节点操作,返回值中还会包括文本节点等其他类型的节点,是一个NodeList对象的集合。 children属性用于元素操作,返回的是HTMLCollection对象的集合

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>节点操作</title>
  </head>
  <body>
    <ul id="ul">
      <li>JS</li>
      <li>BOM</li>
      <li>DOM</li>
      <!--注释-->
    </ul>
    <script>
      var ul = document.getElementById('ul');    // 根据id获取ul的元素对象
      console.log(ul.childNodes);                // 查看ul下的所有节点
    </script>
  </body>
</html>

(2)节点追加
在获取元素的节点后,还可以利用DOM提供的方法实现节点的添加。
在这里插入图片描述
create系列的方法是由document对象提供的,与Node对象无关。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>节点追加</title>
  </head>
  <body>
    <script>
      var h2 = document.createElement('h2');                     // 创建h2元素节点
      var text = document.createTextNode('Hello JavaScript');    // 创建文本节点
      var attr = document.createAttribute('align');              // 创建属性节点
      attr.value = 'center';                                     // 为属性节点赋值
      h2.setAttributeNode(attr);                                 // 为h2元素添加属性节点
      h2.appendChild(text);                                      // 为h2元素添加文本节点
      document.body.appendChild(h2);                             // 将h2节点追加为body元素的子节点
      console.log(document.getElementsByTagName('h2')[0]);
    </script>
  </body>
</html>

(3)节点删除
语法:removeChild()和removeAttributeNode()方法实现。
返回值:是被移出的元素节点或属性节点。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>删除节点和节点属性</title>
  </head>
  <body>
    <ul>
      <li>PHP</li><li>JavaScript</li><li class="strong">UI</li>
    </ul>
    <script>
      var child = document.getElementsByTagName('li')[2];    // 获取第3个li元素
      var attr = child.getAttributeNode('class');            // 获取元素的class属性值
      console.log(child.removeAttributeNode(attr));          // 删除元素的class属性值
      console.log(child.parentNode.removeChild(child));      // 删除元素
    </script>
  </body>
</html>

案例:列表的增删和移动

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>列表的增删和移动</title>
    <style>
      body{background:#ddd;text-align:center}
      .list{display:inline-block;margin-top:20px;padding:40px;border-radius:8px;background:#fff;color:#333;text-align:left;font-size:13px}
      .list-ul{list-style:none;margin:0;padding:0}
      .list-option{padding:6px 0;}
      .list-input{width:300px;border:1px solid #ccc;padding:4px;font-size:14px;color:#333}
      .list-input:hover{background:#effaff}
      .list-btn span{color:#0065A0;;cursor:pointer}
      .list-btn span:hover{text-decoration:underline}
      .list-btn b{text-align:center;background-color:#D6EDFF;border-radius:6px;width:20px;height:20px;display:inline-block;margin:0 2px;cursor:pointer;color:#238FCE;border:1px solid #B3DBF8;float:left}
      .list-bottom{margin-top:5px}
      .list-add-show{color:#f60;cursor:pointer}
      .list-add-show:before{position:relative;top:1px;margin-right:5px;content:"+";font-weight:700;font-size:16px;font-family:arial}
      .list-add-show span:hover{text-decoration:underline}
      .list-add-area{margin-top:5px}
      .list-add-add{cursor:pointer;margin-left:5px}
      .list-add-cancel{cursor:pointer;margin-left:4px}
      .list-add-input{width:180px;border:1px solid #ccc;padding:4px;font-size:14px;color:#333}
      .list-add-input:hover{background:#effaff}
      .list-tmp{display:none}
      .list-hide{display:none}
    </style>
  </head>
  <body>
    <form>
      <div class="list">
        <ul class="list-ul">
          <li class="list-option">
            <input class="list-input" type="text" name="list[]">
            <span class="list-btn">
              <span class="list-up">[上移]</span>
              <span class="list-down">[下移]</span>
              <span class="list-del">[删除]</span>
            </span>
          </li>
        </ul>
        <div class="list-bottom">
          <span class="list-add-show"><span>添加项目</span></span>
          <div class="list-add-area list-hide">
            添加到列表:
            <input class="list-add-input" type="text" name="list[]">
            <input class="list-add-add" type="button" value="添加">
            <input class="list-add-cancel" type="button" value="取消">
          </div>
        </div>
      </div>
    </form>
    <script src="SmartList.js"></script>
    <script>
      SmartList('list', ['PHP', 'JavaScript']);
    </script>
  </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值