zoukankan      html  css  js  c++  java
  • JavaScript(18):HTML DOM

    通过 HTML DOM,JavaScript 能够访问和改变 HTML 文档的所有元素。

    一、HTML DOM(文档对象模型)

    当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。

    1、什么是 DOM?

    DOM 是一项 W3C (World Wide Web Consortium) 标准。

    DOM 定义了访问文档的标准:

    “W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”

    W3C DOM 标准被分为 3 个不同的部分:

    • Core DOM - 所有文档类型的标准模型
    • XML DOM - XML 文档的标准模型
    • HTML DOM - HTML 文档的标准模型

    2、什么是 HTML DOM?

    HTML DOM 是 HTML 的标准对象模型和编程接口。它定义了:

    • 作为对象的 HTML 元素
    • 所有 HTML 元素的属性
    • 访问所有 HTML 元素的方法
    • 所有 HTML 元素的事件

    换言之:HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准

    3、对象的 HTML DOM 树

    HTML DOM 模型被结构化为对象树

    DOM HTML 树

    通过这个对象模型,JavaScript 获得创建动态 HTML 的所有力量:

    • JavaScript 能改变页面中的所有 HTML 元素
    • JavaScript 能改变页面中的所有 HTML 属性
    • JavaScript 能改变页面中的所有 CSS 样式
    • JavaScript 能删除已有的 HTML 元素和属性
    • JavaScript 能添加新的 HTML 元素和属性
    • JavaScript 能对页面中所有已有的 HTML 事件作出反应
    • JavaScript 能在页面中创建新的 HTML 事件

    通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。所有 HTML 元素(节点)均可被修改,也可以创建或删除节点。

    4、节点父、子和同胞

    节点树中的节点彼此拥有层级关系。

    父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。

    • 在节点树中,顶端节点被称为根(root)
    • 每个节点都有父节点、除了根(它没有父节点)
    • 一个节点可拥有任意数量的子
    • 同胞是拥有相同父节点的节点

    下面的图片展示了节点树的一部分,以及节点之间的关系:

    DOM 节点关系

    <html>
    
       <head>
           <title>DOM 教程</title>
       </head>
    
      <body>
           <h1>DOM 第一课</h1>
           <p>Hello world!</p>
       </body>
    
    </html>

    从以上的 HTML 中您能读到以下信息:

    • <html> 是根节点
    • <html> 没有父
    • <html> 是 <head> 和 <body> 的父
    • <head> 是 <html> 的第一个子
    • <body> 是 <html> 的最后一个子

    同时:

    • <head> 有一个子:<title>
    • <title> 有一个子(文本节点):"DOM 教程"
    • <body> 有两个子:<h1> 和 <p>
    • <h1> 有一个子:"DOM 第一课"
    • <p> 有一个子:"Hello world!"
    • <h1> 和 <p> 是同胞

    二、HTML DOM Document 对象

    每个载入浏览器的 HTML 文档都会成为 Document 对象。

    描述当前窗口或指定窗口对象的文档。它包含了文档从<head>到</body>的内容。
      用法:

    document (当前窗口)
    或 <窗口对象>.document (指定窗口)

    Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。

    1、Document 对象集合

    • all[]:提供对文档中所有 HTML 元素的访问。
    • anchors[]:返回对文档中所有 Anchor 对象的引用。
    • applets:返回对文档中所有 Applet 对象的引用。
    • forms[]:返回对文档中所有 Form 对象引用。
    • images[]:返回对文档中所有 Image 对象引用。
    • links[]:返回对文档中所有 Area 和 Link 对象引用。

    images[]; Image 图片对象详解:

    document.images[] 是一个数组,包含了文档中所有的图片(<img>)。要引用单个图片,可以用 document.images[x]。如果某图片包含“name”属性,也就是用“<img name="...">”这种格式定义了一幅图片,就可以使用“document.images['...']”这种方法来引用图片。在 IE 中,如果某图片包含 ID 属性,也就是用“<img id="...">”这种格式定义了一幅图片,就可以直接使用“<imageID>”来引用图片。

    单个 Image 对象的属性:name; src; lowsrc; width; height; vspace; hspace; border 这些属性跟<img>标记里的同名属性是一样的。在 Netscape 里,除了 src 属性,其它属性(几乎全部)都不能改的,即使改了,在文档中也不能显示出效果来。这些属性最有用的就是 src 了,通过对 src 属性赋值,可以实时的更改图片。

    事件:onclick

    不显示在文档中的 Image 对象是用 var 语句定义的:

    var myImage = new Image(); 或
    var myImage = new Image(<图片地址字符串>);

    然后就可以像一般 Image 对象一样对待 myImage 变量了。不过既然它不显示在文档中,以下属性:lowsrc, width, height, vspace, hspace, border 就没有什么用途了。一般这种对象只有一个用:预读图片(preload)。因为当对对象的 src 属性赋值的时候,整个文档的读取、JavaScript 的运行都暂停,让浏览器专心的读取图片。预读图片以后,浏览器的缓存里就有了图片的 Copy,到真正要把图片放到文档中的时候,图片就可以立刻显示了。现在的网页中经常会有一些图像连接,当鼠标指向它的时候,图像换成另外一幅图像,它们都是先预读图像的。

    预读图像的 JavaScript 例子

    以下例子适合预读少量图片。

    var imagePreload = new Image();
    
    imagePreload.src = '001.gif';
    imagePreload.src = '002.gif';
    imagePreload.src = '003.gif';

    以下例子适合预读大量图片。

    function imagePreload() {
      var imgPreload = new Image();
      for (i = 0; i < arguments.length; i++) {
        imgPreload.src = arguments[i];
      }
    }
    
    imagePreload('001.gif', '002.gif', '003.gif', '004.gif', '005.gif');

    2、Document 对象属性

    • body:提供对 <body> 元素的直接访问。对于定义了框架集的文档,该属性引用最外层的 <frameset>。
    • cookie:设置或返回与当前文档有关的所有 cookie。
    • domain:返回当前文档的域名。
    • lastModified:返回文档被最后修改的日期和时间。
    • referrer:返回载入当前文档的文档的 URL。
    • title:返回当前文档的标题。
    • URL:返回当前文档的 URL。
    • fgColor :指<body>标记的 text 属性所表示的文本颜色。
    • bgColor :指<body>标记的 bgcolor 属性所表示的背景颜色。
    • linkColor :指<body>标记的 link 属性所表示的连接颜色。
    • alinkColor :指<body>标记的 alink 属性所表示的活动连接颜色。
    • vlinkColor :指<body>标记的 vlink 属性所表示的已访问连接颜色

    3、Document 对象方法

    • getElementById():返回对拥有指定 id 的第一个对象的引用。
    • getElementsByName():返回带有指定名称的对象集合。
    • getElementsByTagName():返回带有指定标签名的对象集合。
    • open():打开一个流,以收集来自任何 document.write() 或 document.writeln() 方法的输出。
    • write():向文档写 HTML 表达式 或 JavaScript 代码。
    • writeln():等同于 write() 方法,不同的是在每个表达式之后写一个换行符。
    • close():关闭用 document.open() 方法打开的输出流,并显示选定的数据。
    • clear() :清空当前文档。

    open方法实例:弹出式更新通知:

    var whatsNew = open('','_blank','top=50,left=50,width=200,height=300,' +
                    'menubar=no,toolbar=no,directories=no,location=no,' +
                    'status=no,resizable=no,scrollbars=yes');
    whatsNew.document.write('<center><b>更新通知</b>< /center>');
    whatsNew.document.write('<p>最后更新日期:00.08.01');
    whatsNew.document.write('<p>00.08.01:增加了“我的最爱”栏目。');
    whatsNew.document.write('<p align="right">' +
                    '<a href="javascript:self.close()">关闭窗口</a>');
    whatsNew.document.close();

    当然也可以先写好一个 HTML 文件,在 open() 方法中直接 load 这个文件。

    三、查找 HTML 元素

    首个 HTML DOM Level 1 (1998),定义了 11 个 HTML 对象、对象集合和属性。它们在 HTML5 中仍然有效。

    后来,在 HTML DOM Level 3,加入了更多对象、集合和属性。

    • document.anchors:返回拥有 name 属性的所有 <a> 元素。
    • document.baseURI:返回文档的绝对基准 URI
    • document.body:返回 <body> 元素
    • document.cookie:返回文档的 cookie
    • document.doctype:返回文档的 doctype
    • document.documentElement:返回 <html> 元素
    • document.documentMode:返回浏览器使用的模式
    • document.documentURI:返回文档的 URI
    • document.domain:返回文档服务器的域名
    • document.embeds:返回所有 <embed> 元素
    • document.forms:返回所有 <form> 元素
    • document.head:返回 <head> 元素
    • document.images:返回所有 <img> 元素
    • document.implementation:返回 DOM 实现
    • document.inputEncoding:返回文档的编码(字符集)
    • document.lastModified:返回文档更新的日期和时间
    • document.links:返回拥有 href 属性的所有 <area> 和 <a> 元素
    • document.readyState:返回文档的(加载)状态
    • document.referrer:返回引用的 URI(链接文档)
    • document.scripts:返回所有 <script> 元素
    • document.strictErrorChecking:返回是否强制执行错误检查
    • document.title:返回 <title> 元素
    • document.URL:返回文档的完整 URL

    通常,通过 JavaScript,您需要操作 HTML 元素。

    1、通过 HTML 对象选择器查找 HTML 对象

    本例查找 id="frm1" 的 form 元素,在 forms 集合中,然后显示所有元素值:

    var x = document.forms["frm1"];
    var text = "";
     var i;
    for (i = 0; i < x.length; i++) {
        text += x.elements[i].value + "<br>";
    }
    document.getElementById("demo").innerHTML = text;

    以下 HTML 对象(和对象集合)也是可访问的:

    2、通过 id 查找 HTML 元素

    在 DOM 中查找 HTML 元素的最简单的方法,是通过使用元素的 id。

    本例查找 id="intro" 元素:

    var x=document.getElementById("intro");

    如果找到该元素,则该方法将以对象(在 x 中)的形式返回该元素。

    如果未找到该元素,则 x 将包含 null。

    3、通过标签名查找 HTML 元素

    本例查找 id="main" 的元素,然后查找 id="main" 元素中的所有 <p> 元素:

    var x=document.getElementById("main");
    var y=x.getElementsByTagName("p");

    4、通过类名找到 HTML 元素

    本例通过 getElementsByClassName 函数来查找 class="intro" 的元素:

    var x=document.getElementsByClassName("intro");

    5、通过 CSS 选择器查找 HTML 元素

    如果您需要查找匹配指定 CSS 选择器(id、类名、类型、属性、属性值等等)的所有 HTML 元素,请使用 querySelectorAll() 方法。

    本例返回 class="intro" 的所有 <p> 元素列表:

    var x = document.querySelectorAll("p.intro");

    querySelectorAll() 不适用于 Internet Explorer 8 及其更早版本。

    四、DOM - 导航

      1、导航节点关系

      通过 JavaScript,您可以使用以下节点属性在节点之间导航:

      • parentNode
      • childNodes[nodenumber]
      • firstChild
      • lastChild
      • nextSibling
      • previousSibling
      <html>
      <body>
      
      <p>Hello World!</p>
      <div>
        <p>DOM 很有用!</p>
        <p>本例演示节点关系。</p>
      </div>
      
      </body>
      </html>

      firstChild 属性可用于访问元素的文本:

      <html>
      <body>
      
      <p id="intro">Hello World!</p>
      
      <script>
      x=document.getElementById("intro");
      document.write(x.firstChild.nodeValue);
      </script>
      
      </body>
      </html>

      2、DOM 根节点

      这里有两个特殊的属性,可以访问全部文档:

      • document.documentElement - 全部文档
      • document.body - 文档的主体
      <html>
      <body>
      
      <p>Hello World!</p>
      <div>
      <p>DOM 很有用!</p>
      <p>本例演示 <b>document.body</b> 属性。</p>
      </div>
      
      <script>
      alert(document.body.innerHTML);
      </script>
      
      </body>
      </html>

      3、子节点和节点值

      文本节点的值能够通过节点的 innerHTML 属性进行访问:

      var myTitle = document.getElementById("demo").innerHTML;

      访问 innerHTML 属性等同于访问首个子节点的 nodeValue:

      var myTitle = document.getElementById("demo").firstChild.nodeValue;

      也可以这样访问第一个子节点:

      var myTitle = document.getElementById("demo").childNodes[0].nodeValue;

      以下三个例子取回 <h1> 元素的文本并复制到 <p> 元素中:

      document.getElementById("id02").innerHTML  = document.getElementById("id01").innerHTML;
      document.getElementById("id02").innerHTML = document.getElementById("id01").firstChild.nodeValue;
      document.getElementById("id02").innerHTML = document.getElementById("id01").childNodes[0].nodeValue;

      4、nodeName 属性

      nodeName 属性规定节点的名称。

      • nodeName 是只读的
      • 元素节点的 nodeName 等同于标签名
      • 属性节点的 nodeName 是属性名称
      • 文本节点的 nodeName 总是 #text
      • 文档节点的 nodeName 总是 #document
      <h1 id="id01">我的第一张网页</h1>
      <p id="id02">Hello!</p>
      
      <script>
      document.getElementById("id02").innerHTML  = document.getElementById("id01").nodeName;
      </script>

      注释:nodeName 总是包含 HTML 元素的大写标签名。

      5、nodeValue 属性

      nodeValue 属性规定节点的值。

      • 元素节点的 nodeValue 是 undefined
      • 文本节点的 nodeValue 是文本文本
      • 属性节点的 nodeValue 是属性值

      6、nodeType 属性

      nodeType 属性返回节点的类型。nodeType 是只读的。

      <h1 id="id01">我的第一张网页</h1>
      <p id="id02">Hello!</p>
      
      <script>
      document.getElementById("id02").innerHTML  = document.getElementById("id01").nodeType;
      </script>

      最重要的 nodeType 属性和类型是:

      • ELEMENT_NODE:1
      • ATTRIBUTE_NODE:2
      • TEXT_NODE:3
      • COMMENT_NODE:8
      • DOCUMENT_NODE:9
      • DOCUMENT_TYPE_NODE:10

      Type 2 在 HTML DOM 中已弃用。XML DOM 中未弃用。

      五、改变 HTML 元素的内容

      改变 HTML 元素

      • element.innerHTML = new html content:改变元素的 inner HTML
      • element.attribute = new value:改变 HTML 元素的属性值
      • element.setAttribute(attribute, value):改变 HTML 元素的属性值
      • element.style.property = new style:改变 HTML 元素的样式

      1、改变 HTML 输出流

      JavaScript 能够创建动态的 HTML 内容:

      今天的日期是: Fri Feb 21 2020 16:34:17 GMT+0800 (中国标准时间)

      在 JavaScript 中,document.write() 可用于直接向 HTML 输出流写内容。

      <!DOCTYPE html>
      <html>
      <body>
      
      <script>
      document.write(Date());
      </script>
      
      </body>
      </html>

      注意:绝对不要在文档(DOM)加载完成之后使用 document.write()。这会覆盖该文档。

      2、改变 HTML 内容

      修改 HTML 内容的最简单的方法是使用 innerHTML 属性。

      如需改变 HTML 元素的内容,请使用这个语法:

      document.getElementById(id).innerHTML=新的 HTML

      本例改变了 <p>元素的内容:

      <html>
      <body>
      
      <p id="p1">Hello World!</p>
      
      <script>
      document.getElementById("p1").innerHTML="新文本!";
      </script>
      
      </body>
      </html>

      本例改变了 <h1> 元素的内容:

      <!DOCTYPE html>
      <html>
      <body>
      
      <h1 id="header">Old Header</h1>
      
      <script>
      var element=document.getElementById("header");
      element.innerHTML="新标题";
      </script>
      
      </body>
      </html>

      3、改变 HTML 属性

      如需改变 HTML 元素的属性,请使用这个语法:

      document.getElementById(id).attribute=新属性值

      本例改变了 <img> 元素的 src 属性:

      <!DOCTYPE html>
      <html>
      <body>
      
      <img id="image" src="smiley.gif">
      
      <script>
      document.getElementById("image").src="landscape.jpg";
      </script>
      
      </body>
      </html>

      4、改变 HTML 样式

      如需改变 HTML 元素的样式,请使用这个语法:

      document.getElementById(id).style.property=新样式

      下面的例子会改变 <p> 元素的样式:

      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="utf-8">
      <title>菜鸟教程(runoob.com)</title>
      </head>
      <body>
       
      <p id="p1">Hello World!</p>
      <p id="p2">Hello World!</p>
      <script>
      document.getElementById("p2").style.color="blue";
      document.getElementById("p2").style.fontFamily="Arial";
      document.getElementById("p2").style.fontSize="larger";
      </script>
      <p>以上段落通过脚本修改。</p>
       
      </body>
      </html>

      本例改变了 id="id1" 的 HTML 元素的样式,当用户点击按钮时:

      <!DOCTYPE html>
      <html>
      <body>
      
      <h1 id="id1">我的标题 1</h1>
      <button type="button"
      onclick="document.getElementById('id1').style.color='red'">
      点我!</button>
      
      </body>
      </html>

      六、添加和移除HTML元素(节点)

      添加和删除元素

      • document.createElement(element):创建 HTML 元素
      • document.removeChild(element):删除 HTML 元素
      • document.appendChild(element):添加 HTML 元素
      • document.replaceChild(element):替换 HTML 元素
      • document.write(text):写入 HTML 输出流


      1、创建新的 HTML 元素 (节点) - appendChild()

      要创建新的 HTML 元素 (节点)需要先创建一个元素,然后在已存在的元素中添加它。

      <div id="div1">
      <p id="p1">这是一个段落。</p>
      <p id="p2">这是另外一个段落。</p>
      </div>
       
      <script>
      var para = document.createElement("p");
      var node = document.createTextNode("这是一个新的段落。");
      para.appendChild(node);
       
      var element = document.getElementById("div1");
      element.appendChild(para);
      </script>

      2、创建新的 HTML 元素 (节点) - insertBefore()

      以上的实例我们使用了 appendChild() 方法,它用于添加新元素到尾部。

      如果我们需要将新元素添加到开始位置,可以使用 insertBefore() 方法:

      <div id="div1">
      <p id="p1">这是一个段落。</p>
      <p id="p2">这是另外一个段落。</p>
      </div>
       
      <script>
      var para = document.createElement("p");
      var node = document.createTextNode("这是一个新的段落。");
      para.appendChild(node);
       
      var element = document.getElementById("div1");
      var child = document.getElementById("p1");
      element.insertBefore(para, child);
      </script>

      3、移除已存在的元素

      要移除一个元素,你需要知道该元素的父元素。

      <div id="div1">
      <p id="p1">这是一个段落。</p>
      <p id="p2">这是另外一个段落。</p>
      </div>
       
      <script>
      var parent = document.getElementById("div1");
      var child = document.getElementById("p1");
      parent.removeChild(child);
      </script>

      注意:早期的 Internet Explorer 浏览器不支持 node.remove() 方法。

      注意:如果能够在不引用父元素的情况下删除某个元素,就太好了。不过很遗憾。DOM 需要清楚您需要删除的元素,以及它的父元素。

      以下代码是已知要查找的子元素,然后查找其父元素,再删除这个子元素(删除节点必须知道父节点):

      var child = document.getElementById("p1");
      child.parentNode.removeChild(child);

      4、替换 HTML 元素 - replaceChild()

      我们可以使用 replaceChild() 方法来替换 HTML DOM 中的元素。

      <div id="div1">
      <p id="p1">这是一个段落。</p>
      <p id="p2">这是另外一个段落。</p>
      </div>
       
      <script>
      var para = document.createElement("p");
      var node = document.createTextNode("这是一个新的段落。");
      para.appendChild(node);
       
      var parent = document.getElementById("div1");
      var child = document.getElementById("p1");
      parent.replaceChild(para, child);
      </script>

      七、HTML DOM 集合

      1、HTMLCollection 对象

      getElementsByTagName() 方法返回 HTMLCollection 对象。

      HTMLCollection 对象是类数组的 HTML 元素列表(集合)。

      下面的代码选取文档中的所有 <p> 元素:

      var x = document.getElementsByTagName("p");

      该集合中的元素可通过索引号进行访问。

      如需访问第二个 <p> 元素,您可以这样写:

      y = x[1];

      注释:索引从 0 开始。

      2、HTML HTMLCollection 长度

      length 属性定义了 HTMLCollection 中元素的数量:

      var myCollection = document.getElementsByTagName("p");
      document.getElementById("demo").innerHTML = myCollection.length;

      length 属性在您需要遍历集合中元素时是有用的:

      改变所有 <p> 元素的背景色:

      var myCollection = document.getElementsByTagName("p");
      var i;
      for (i = 0; i < myCollection.length; i++) {
          myCollection[i].style.backgroundColor = "red";
      }

      注意:HTMLCollection 也许看起来像数组,但并非数组。

      您能够遍历列表并通过数字引用元素(就像数组那样)。

      不过,您无法对 HTMLCollection 使用数组方法,比如 valueOf()、pop()、push() 或 join()。

      八、HTML DOM 节点列表NodeList

      NodeList 对象是一个从文档中获取的节点列表 (集合) 。

      NodeList 对象类似 HTMLCollection 对象。

      一些旧版本浏览器中的方法(如:getElementsByClassName())返回的是 NodeList 对象,而不是 HTMLCollection 对象。

      所有浏览器的 childNodes 属性返回的是 NodeList 对象。

      大部分浏览器的 querySelectorAll() 返回 NodeList 对象。

      以下代码选取了文档中所有的 <p> 节点:

      var myNodeList = document.querySelectorAll("p");

      NodeList 中的元素可以通过索引(以 0 为起始位置)来访问。

      访问第二个 <p> 元素可以是以下代码:

      y = myNodeList[1];

      1、NodeList 对象 length 属性

      NodeList 对象 length 属性定义了节点列表中元素的数量。

      var myNodelist = document.querySelectorAll("p");
      document.getElementById("demo").innerHTML = myNodelist.length;

      修改节点列表中所有 <p> 元素的背景颜色:

      var myNodelist = document.querySelectorAll("p");
      var i;
      for (i = 0; i < myNodelist.length; i++) {
          myNodelist[i].style.backgroundColor = "red";
      }

      2、HTMLCollection 与 NodeList 的区别

      HTMLCollection 是 HTML 元素的集合,NodeList 是一个文档节点的集合。

      NodeList 与 HTMLCollection 都与数组对象有点类似,可以使用索引 (0, 1, 2, 3, 4, ...) 来获取元素。

      NodeList 与 HTMLCollection 都有 length 属性。都不是一个数组!

      HTMLCollection 元素可以通过 name,id 或索引来获取。NodeList 只能通过索引来获取。

      只有 NodeList 对象有包含属性节点和文本节点。

    • 相关阅读:
      mysql的用户权限设置
      Jmeter——BeanShell PreProcessor的用法
      zhlan--巧用Python中的正则表达式符号
      【直播预告】云栖直播:阿里热修复产品HotFix2.0升级详解
      双十一 手淘技术用了这几招
      用户说体验 | 关于阿里百川HotFix你需要了解的一些细节
      阿里百川码力APP监控 来了!
      淘宝直播技术分享:如何打造体验优秀的“直播+”产品?
      云栖大会上宣布即将开源的手淘Atlas什么来头?
      推进"五通一平":手淘技术"三大容器 五大方案"首次整体亮相 百川开放升级
    • 原文地址:https://www.cnblogs.com/springsnow/p/12341911.html
    Copyright © 2011-2022 走看看