HTML DOM 探索

HTML DOM 探索

2017年2月10日20:54:11 CHJ_1993

1、前言

​ 因为最近比较忙,好久没有写博客了,记得我第一篇自我介绍的博客说经常给大家分享一些我学习的知识,但是时间过去这么久了,也没有更新几篇本章,可能刚开始写的文章也很烂。作为博客新手,希望大家原谅一下。

​ 今天有点时间, 我就来跟大家探讨一下 HTML DOM 的一些知识。好了下面开始正文.....

2、DOM的概念

DOM 是 (Document Object Model) 的缩写

  • DOM 是针对 XML 和 HTML 文档的一个 api (应用程序接口)
  • DOM 中描述了一个层级化的节点树
  • DOM 中允许开发人员对页面的某一部分内容进行修改,移除,添加

W3C 中 DOM标准化分类分成三种:

  • 核心 DOM ==== 针对任何结构化文档的标准模型
  • XML DOM ==== 针对XML文档的标准模板
  • HTML DOM ==== 针对HTML 文档的标准模板

DOM标准分化分为三种,那么前面两种我们今天不进行探索,我们今天主要来了解的是HTML DOM

3、HTML DOM 的探索

3.1 什么是HTML DOM ?

HTML DOM 是HTML的标准对象模型,也是HTML的标准编程接口

HTML DOM 定义了所有HTML元素的对象 ** 和 属性,以及访问他们的方法**

换句话说, HTML DOM 是关于如何获取、修改、添加或者删除HTML元素的标准

3.2 HTML DOM的节点

根据W3C(万维网) 的HTML DOM标准,HTML文档中所有的内容都是节点

  • 整个文档 是一个文档节点
  • 每个HTML元素都是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

下面我们引用网上的一张图来描述一下: (HTML DOM 的节点树结构)

3.2.1 HTML DOM 节点分类

HTML DOM 中个一共存在12 个节点类型,任何一个节点类型都属于这12个节点类型之一

如下表:

属性名称 代表中文含义
Node.ELEMENT_NODE 元素
Node.ATTRIBUTE_NODE 元素中的属性
Node.TEXT_NODE 纯文本(没有子节点)
Node.CDATA_SECTION_NODE 子节点是TextNode
Node.ENTITY_REFERENCE_NODE 文档中的实体引用
Node.ENTITY_NODE DTD中的实体定义
Node.PROCESSING_INSTRUCTION_NODE 一个文档处理程序中使用的特有指令
Node.COMMENT_NODE 注释
Node.DOCUMENT_NODE 最外层的 (根节点)
Node.DOCUMENT_TYPE_NODE 文档类型定义
Node.DOCUMENT_FRAGMENT_NODE 更小型的Docment 的节点,定义整个数据类型主要是为了方便只希望提取文档的某一部分时使用
Node.NOTATION_NODE DTD 的Nation定义

3.2.2 HTML DOM 文档节点的属性

文档节点的属性,我们今天主要认识的就只有三个:

  • nodeName

    节点名称,只读

  • nodeValue

    节点的值 ,可读可写

  • nodeType

    节点的类型,只读

3.3 HTML DOM 核心对象 document 对象

在JavaScript中 是通过Document 来表示文档的,Document 的属性如下:

  • document的节点类型 (nodeType) 为 9
  • document 的节点名称 (nodeName) 是 #document
  • document 的节点值(nodeValue) 为空(null)
  • document 是没有父节点(parentNode) 的
  • document 也没有根元素(ownerDocument)

3.3.1 通过document 来获取 元素(节点)

在JavaScript 获取元素的方式主要有以下中方法

  1. document.getElementById() 通过ID的方式来获取元素.
  2. document.getElementsByTagName() 根据标签名来获取元素
  3. document.getElementsByName() 通过标签的name属性的值来获取元素
  4. document.getElementsByClassName() 通过class 的属性值来获取元素
  5. querySelector() 通过选择器名称来获取元素(获取匹配到的第一个)
  6. querySelectorAll() 通过选择器名称来获取元素(获取全部)
3.3.1.1 document.getElementById()

通过元素中ID属性的属性值来查找元素

语法: node.getElementById("id");

注意:

  1. 使用该方法不能同时查找多个ID
  2. 如果有HTML中有相同ID,则只会返回一个元素
  3. 在 低于 IE 8 版本的IE浏览器中,对匹配元素的ID,该方法不区分大小写

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <h1 id="h1">我是标题</h1>
    </body>
    <script type="text/javascript">
        var eH1 = document.getElementById("h1");
        alert(eH1.innerHTML);
    </script>
</html>

3.3.1.2 document.getElementsByTagName()

根据标签名来获取元素

语法: node.getElementsByTagName(标签名称)

返回值: 返回多个同标签名的Element组成的集合

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1 id="myH1" class="myH1class">我是H1标签</h1>
        <h1 id="myH2" class="myH1class">我是H1标签</h1>
        <h1 id="myH3" class="myH1class">我是H1标签</h1>
        <h1 id="myH4" class="myH1class">我是H1标签</h1>
    </body>
    <script>
        var h1_ls  = document.getElementsByTagName("h1");
        console.log(h1_ls);
        for (var i = 0; i < h1_ls.length; i++) {
            console.log(h1_ls[i].id); //元素的ID
            console.log(h1_ls.item(i).id); //通过元素的Item 来获取Item内容
        }
    </script>
</html>

3.3.1.3 document.getElementsByName()

通过标签的name属性的值来获取元素,可能出现

语法: docuemnt.getElementsByName("name属性值");

返回值: 返回多个相同的name值的Element组成的集合

注意: 该方法存在严重的兼容性问题,在IE中,此方法还能获取ID属性匹配的值

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form action="" method="get">
            <input type="checkbox" name="input_name" value="洗澡" />洗澡
            <input type="checkbox" name="input_name"  value="喝水" />喝水
        </form>
    </body>
    <script type="text/javascript">
        var names = document.getElementsByName('input_name');
        for (var i = 0; i<names.length; i++) {
            console.log(names[i].value);
        }
    </script>
</html>

3.3.1.4 document.getElementsByClassName()

通过相同的class属性的值来获取元素

语法: document.getElementsByClassName(class属性值);

返回值: 返回多个相同的class属性值的Element组成的集合

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1 id="myH1" class="myH1class">我是H1标签</h1>
        <h2 id="myH2" class="myH1class">我是H2标签</h1>
        <h3 id="myH3" class="myH1class">我是H3标签</h1>
        <h4 id="myH4" class="myH1class">我是H4标签</h1>
    </body>
    <script type="text/javascript">
        var myClassLi = document.getElementsByClassName('myH1class');
        for (var i = 0; i<myClassLi.length; i++) {
            console.log(myClassLi[i].value);
        }
    </script>
</html>
3.3.1.4 querySelector()

通过CSS 选择器的放来来获取元素,

指定一个或者多个匹配的CSS选择器,id,class, 类型,属性

如果针对多个选择器,中间使用d"逗号分隔",

语法: document.querySelector("#demo")

返回值: 直接返回匹配到的第一个元素,如果没有找到则返回null

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        
    </head>
    <body>
        <p id="demo"></p>
    </body>
    <script type="text/javascript">
        var p_1 = document.querySelector("#demo");
        console.log(p_1);
    </script>
</html>

3.3.1.4 querySelectorAll()

HTML5引入的一种新的查找元素的方法

语法: document.querySelectorAll(".p_1")

返回值: 返回查找到的所有相同选择器的Element 集合

注意: 该方法不是实时返回的,只有调用的时候才会返回,因为这样开发人员通常可以利用伪类选择器( :hover , :visited ) 去访问用户的浏览习惯等,所以现在很多浏览器不支持该方法

代码示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div class="p_1"></div>
        <div class="p_1"></div>
        <div class="p_1"></div>
    </body>
    <script type="text/javascript">
        var all = document.querySelectorAll(".p_1");
        console.log(all)
    </script>
</html>

好了,说了上面一大推,篇幅有点长了,但是我觉得我还是要继续把下面几点说完

上面说了元素的获取的几种方法,那么现在我们可以获取到元素了,那么元素和元素之间的关系又是怎么样的? 那么下面我们来说 元素节点之间的关系

3.3.2 HTML DOM 中节点的关系

我们学过HTML 的都知道 HTML元素之间的关系 有父子关系,和兄弟关系(同级元素)

那么在DOM中节点关系有以下几种

  1. parent 父节点
  2. child子节点
  3. sibling 兄弟节点(同级节点)
  4. root 根节点

如图所示:

  • 父节点属性(parentNode)

    获取一个元素的父节点

    语法: node.parentNode

  • 兄弟节点属性(sibling)

    同级节点属性又分为两个小的属性:

    上一个同级节点(previousSibling)

    ​ 获取某个元素的上一个同级节点

    ​ 语法:node.previousSibling

    下一个同级节点(nextSibling)

    ​ 获取某个元素的下一个同级节点

    ​ 语法 node.nextSibling

    因为在使用者两种方法获取到,可能含有<div> </div> 中间的空格,又因为JavaScript 是一种弱类型语言,就衍生了下面的两种方法:

    上一个同级元素(previousElementSibling)

    ​ 获取某个元素的上一个同级元素

    ​ 语法:node.previousElementSibling

    下一个同级元素(nextElementSibling)

    ​ 获取某个元素的下一个同级元素

    ​ 语法 node.nextElementSibling

  • 根节点 ( ownerDocument)

    获取某个元素的根元素

    语法:node.ownerDocument

    获取一个元素的根节点

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="demo">
            <a href="###">搜狐</a><div id="div">DIV</div><div>
                <a href="#"></a>
            </div>
            <input type="text" />
        </div>
    </body>
    <script type="text/javascript">

        //parentNode 获取父节点
        var div = document.getElementById("demo");
        div.previousSibling;
        console.log(div.parentNode.nodeName); //BODY
        
        //previousSibling 获取元素的上一个同级节点
        var div1 = document.getElementById("div");
        var preSib= div1.previousSibling;
        console.log(preSib);
        
        //previousElementSibling  获取元素的上一个同级节点
        var preSib2= div1.previousElementSibling;
        console.log(preSib2);
        
        //nextSibling 获取元素的下一个同级节点
        var nextElement = div1.nextSibling;
        console.log(nextElement)
        
        //nextElementSibling 获取元素的下一个同级节点
        var nextElement2 = div1.nextElementSibling;
        console.log(nextElement2)
        
        //ownerDocument  获取元素的根节点
        var rootElement = div1.ownerDocument;
        console.log(rootElement)
    </script>
</html>

  • 子节点属性(ChildNodes)

    在这里要写的是三个小属性

    所有子节点(ChildNodes)

    ​ 用来获取一个元素的所有子节点

    ​ 返回值: 一个数组,只获取子节点,不能获取子节点的子节点

    ​ 语法:node.chilNodes

    第一个子节点(firstChild)

    ​ 获取元素的第一个子节点 ,如果匹配不到则返回null

    ​ 语法:node.firstChild

    最后一个子节点(lastChild)

    ​ 获取元素的最后一个子节点 ,如果匹配不到则返回null

    ​ 语法 node.lastChild

    因为在使用者两种方法获取到,可能含有<div> </div> 中间的空格,又因为JavaScript 是一种弱类型语言,就衍生了下面的两种方法:

    第一个子元素(firstElementChild)

    ​ 获取某个元素的第一个子元素

    ​ 语法:node.firstElementChild

    最后一个子元素(lastElementChild)

    ​ 获取某个元素的最后一个子元素

    ​ 语法 node.lastElementChild

    代码:

    <!DOCTYPE html>
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <div id="demo">
              <a href="###">简书</a>
              <a href="###">百度</a>
              <div>
                  <a href="###">博客</a>
              </div>
              <input type="text" name="input_name" id="input" value="" />
          </div>
      </body>
      <script type="text/javascript">
          //获取元素的所有子节点
          var nodes = document.getElementById("demo").childNodes;
          console.log(nodes);
          for (var i = 0;i<nodes.length; i++) {
              console.log(nodes[i].nodeName);
          }
          
          //获取所有子元素的个数
          var nodes = document.getElementById("demo").childElementCount;
          console.log(nodes);
          
          //firstChild 获取元素的第一个子节点
          var div = document.getElementById("demo");
          var firstChlid = div.firstChild;
          console.log(firstChild);
          console.log(firstChild.nodeName);
          //firstElementChild  获取元素的第一个子节点
          var firstChild2 = div.firstElementChild;
          console.log(firstChild2);
          console.log(firstChild2.nodeName);
          
          
          //firstChild 获取元素的第一个子节点
          var div = document.getElementById("demo");
          var lastCh = div.lastChild;
          console.log(lastCh);
          console.log(lastCh.nodeName);
          
          //firstElementChild  获取元素的第一个子节点
          var lastChild = div.lastElementChild;
          console.log(lastChild);
          console.log(lastChild.nodeName);
      </script>
    </html>
    
    

有比比了好久,说了那么多的元素之间的关系,那么我们平时获取元素,不仅仅只是想获取到他的一下属性,了解他的关系吧,同样我们有事需要对元素进行操作,那么下面我们来说说对Node节点的操作

3.3.2 HTML DOM 中节点增加 删除 修改 创建

由于文章篇幅比较长了,大家也是不想看到我说一大推的废话了 那么我下面直接贴出代码 给大家看 在代码中我也是注释的比较清楚,以后再来修改

代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="demo">
            
        </div>
        
        <ul id="language">
            <li>Java</li>
            <li>C#</li>
        </ul>
        <button onclick="addNode()">点击添加一个新的首节点</button>
        <button onclick="removeNode()">删除一个子节点</button>
        <button onclick="replaceNode()">替换首节点</button>
        <button onclick="cloneNodes()">克隆整个列表</button>
    </body>
    <script type="text/javascript">
        /*
        修改
         *  1.创建文本节点
         *      createTextNode(text)
         *          参数: text 文本
         *          返回值: 创建的文本标签
         *      该方法属于 document 的
         *  2.添加一个子节点
         *      addpendChild(node)
         *          参数:
         *              node: 必选参数,需要添加的节点
         *          返回值: 参数对象本身
         *      翻译过来时追加,如果本身已经有child ,则追加到child之后
         *      添加进去就是 lastChild
         *  3.创建新的元素节点  
         *      createElement(nodeName)
         *          参数:
         *              nodeName: 需要创建的元素名称
         *          返回值: 创建的元素节点
         *  4.在节点之前加入新的节点
         *      insertBefor(newNode,existingNode)
         *          参数:
         *              newNode:需要插入的新节点
         *              existingNode:  当前插入的目标节点
         *          会将新节点插入到目标节点之前
         *  5.移除一个子节点
         *      removeChild(node)
         *          参数:
         *              node:必选参数,表示需要移除的子节点
         *  6.替换一个子节点
         *      replaceChild(newNode,oldNode)
         *          参数:
         *              newNode: 新节点
         *              oldNode: 旧的节点
         *  7.克隆节点
         *      该方法用于创建指定的节点的精准拷贝所有的属性和属性值
         *      cloneNode(deep)
         *          参数:
         *              deep: true/ false
         *                  true: 将递归复制当前节点的所有节点
         *                  false: 只复制当前节点
         */
        
        var divDemo = document.getElementById("demo");
        //======创建一个文本节点====
        var textNode = document.createTextNode("hello world");
        console.log(textNode.nodeName);  // #text 
        console.log(textNode.nodeValue);  // hello world 
        
        //=====添加一个文本节点===
        var appendNode = divDemo.appendChild(textNode);
        console.log(appendNode.nodeValue);  //hello world
        
        //===== 创建元素节点====
        var newElement  = document.createElement("a");
        
        var newElementText = document.createTextNode("新建的元素内容");
        newElement.appendChild(newElementText);
        var divDemo = divDemo.appendChild(newElement);
        
        //====在节点之前加入新的节点===
        function addNode(){
            var newItem = document.createElement("li"); //创建一个新的li元素
            var newItemTextNode = document.createTextNode("Javascript");
            newItem.appendChild(newItemTextNode);
            
            var languageList = document.getElementById("language");
            //将新创建的Item添加到目标节点之前
            languageList.insertBefore(newItem,languageList.firstChild);
        }
        
        //=======移除子节点====
        function removeNode(){
            var languageList = document.getElementById("language");
            var li_lsit = languageList.getElementsByTagName("li");
            //移除li中的第一个
            languageList.removeChild(li_lsit[0]);
        }
        
        
        //============替换子节点=====
        function replaceNode(){
            
            var languageList = document.getElementById("language");
            
            var newLi = document.createElement("li");
            newLi.innerHTML="node.js"
            console.log(newLi.value);
            
            languageList.replaceChild(newLi,languageList.firstElementChild);
            
        }
        
        //==========克隆节点===========
    
        function cloneNodes(){
            var languageList = document.getElementById("language");
            
            var newList = languageList.cloneNode(false);
            document.getElementsByTagName("body")[0].appendChild(newList);
        }
    </script>
</html>

好了 看到这里 我的文章也就结束了,感谢您的浏览!

你们的支持,就是我前进的动力

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容