javascript文档_JavaScript和文档对象模型

javascript文档

编者注:在撰写本文中的信息时,它是最新的,但是在最近几年中,这项技术已发生了变化。 如果您对更多当前信息感兴趣,请参阅使用JavaScript遍历文档对象模型

注意:本文使用与DOM兼容的浏览器,例如Netscape 6.x,Internet Explorer 6或Mozilla 1.0。 熟悉Java技术或其他语言的文档对象模型很有帮助,但不是必需的。 但是,您应该总体上熟悉JavaScript。

为什么要使用DOM而不是DHTML?

在本文中,我将从文档对象模型的角度研究Web页面的结构,检查子级和父级,以及在现有文档中添加节点和在其中编辑节点。 为了说明这一点,我构建了一个页面,用户可以在其中创建对该页面的一系列注释并编辑其内容。 (页面不会太花哨;我将保留内容,四处移动,调整大小等内容。)由于使用DHTML技术可以毫无困难地完成此工作,所以为什么还要打扰DOM?

XML的发展背后的驱动力之一是HTML的碎片化,而DHTML遵循了这一趋势。 有些事情已经成为标准,但是在浏览器如何处理各个方面方面仍然存在重大分歧。 DOM是一组标准的接口,可以全面实现,从而使程序员仅编写其页面的一个版本。

此外,网页还是正朝着XML迈进。 XHTML 1.0是将HTML 4.0.1重构为XML的方式,并且XML越来越多地用于生成Web页面。 最终,DOM将成为访问这些页面中的元素和文本的主要技术。 (您也可以在XSLT样式表中使用它。)

基本页面

让我们从基本页面开始,该页面包括一个工作区和一个表单,用于指示已经创建了多少笔记:

清单1.基本页面
<html>
  <head>
    <title>Getting Sticky</title>
    <style type="text/css">
      * {font-family: sans-serif}
      a {font-size: 6pt}
      .editButton {font-size:6pt}
    </style>

  </head>
  <body>
    <div id="mainDiv" style="height:95%; width:95%; border:3px solid red; 
                                                           padding: 10px;">
    
       <h1>Getting Sticky</h1>

       <form id="noteForm">
           Current number of notes:
                       <input type="text" name="total" value="0" size="3"/>
           <input type="button" value="Add a new note"/>
       </form>

    </div>
  </body>
</html>

Lisitng 1显示了一个具有几种样式的基本页面(只是为了使其美观一点)。 页面的主体包括单个div元素,其中包括标题元素( h1 )和form元素。 即使在DOM之前的浏览器中,访问表单中的信息也不是问题。

图1.基本页面
基本页面

DHTML方式

使用DHTML,您可以访问表单字段中的信息,甚至进行更改。 例如,您可以创建一个脚本,该脚本将当前表单值增加1,然后在用户按下按钮时告诉页面执行脚本:

清单2.增加当前数量
<html><head>
    <title>Getting Sticky</title>
    <style type="text/css">
      * {font-family: sans-serif}
      a {font-size: 6pt}
      .editButton {font-size:6pt}
    </style>

    <script type="text/javascript">
      function incrementCurrent() {
        current = parseInt(document.forms["noteForm"].total.value);
        document.forms["noteForm"].total.value = current + 1;
      }
    </script>

  </head><body>
    <div id="mainDiv" style="height:95%; width:95%; border:3px solid red; 
                                                           padding: 10px;">
    
       <h1>Getting Sticky</h1>

       <form id="noteForm">
           Current number of notes:
                      <input type="text" name="total" value="0" size="3"/>
           <input type="button" value="Add a new note" 
                                             onclick="incrementCurrent()"/>
       </form>

    </div>
</body></html>

清单2中noteForm incrementCurrent()函数采用document对象,然后将noteForm对象从页面内的表单数组中拉出。 该函数从noteForm对象获取名为total的表单字段并检索该值。 然后,它将在页面内更新此值。

这些变化是实时的 。 如果您对页面进行更改,重新加载并重复按下按钮,您会看到文本字段每次都会更新。

同样,您可以使用DHTML属性检索div元素的文本。 因为它的idmainDiv ,所以可以使用属性innerHTML ,如下所示:

theText = mainDiv.innerHTML;

在这种情况下,您会看到两种DHTML技术: forms数组,以及基于属性值的名称而不是元素名称或整体结构来调用元素。 这里的问题是它不能很好地适用于泛化。 是的,您可以使用变量作为表单的名称,但是如果备用演示文稿实际上未使用表单怎么办?

DOM和JavaScript

如果一个原则定义了文档对象模型,则将信息安排为父子层次结构。 例如,以下XML:

<parentElement><childElement>My Text Node</childElement></parentElement>

具有三个节点: 根节点是parentElement 。 它有一个孩子childElementchildElement元素的父元素为parentElement ,其子节点为值为“ My Text Node”的文本节点。 文本节点将childElement作为其父级。 共享父级的两个节点被视为同级。 请注意,文本是其自己的节点。 元素实际上没有值,它们仅具有文本节点子代。

您可能熟悉使用Java技术或另一种语言读取XML文档结构的想法。 这样做时,您将使用具有明确定义的函数和对象属性的API。 例如,该文档的根元素为html元素,其中有两个子元素headbody 。 (为简化起见,我已经删除了通常在这些元素之间出现的空白;浏览器在如何处理该空白方面还不一致。)要使用Java技术访问body元素,可以使用几种不同的表达式,假设您已将Document对象document命名。

第一种方法是获取元素的所有子元素的列表,然后从列表中选择特定项,如下所示:

bodyElement = document.getChildNodes().item(0).getChildNodes().item(1);

在这里,您首先获取html元素,它是文档的第一个子元素,然后获取其第二个子元素body 。 ( getChildNodes()从零开始。)一种替代方法是直接将html元素作为第一个子元素访问,然后移到其第一个子元素( head ),然后移至该元素的下一个兄弟姐妹(第二个子元素body ):

bodyElement = document.getFirstChild().getFirstChild().getNextSibling();

从那里可以得到节点的类型:

typeInt = bodyElement.getNodeType()

节点类型以整数形式返回,并允许您适当地处理每个节点。 元素(类型1 )具有名称,但没有值,而文本节点(类型3 )具有值,但没有名称。

一旦知道了所拥有的内容,就可以检索元素的名称:

elementName = bodyElement.getNodeName();

或其文字内容:

elementContent = bodyElement.getFirstChild().getNodeValue();

(请记住,元素的文本是其自身的节点,以该元素为其父元素。)

将这些功能移至JavaScript时,将使用相同的基本API,但处理方式略有不同。 例如,属性是直接访问的,而不是通过getset方法访问的,因此JavaScript中的相同语句将表示为

bodyElement = document.childNodes.item(0).childNodes.item(1);
bodyElement = document.firstChild.firstChild.nextSibling;

从那里,您可以获取元素的类型和名称以及其内容:

ElementType = bodyElement.nodeType;
elementName = bodyElement.nodeName;
elementContent = bodyElement.firstChild.nodeValue;

但是请注意,只有属性会更改此名称。 返回对象的函数保持不变。 例如,您可以根据其ID检索特定对象,如下所示:

formElement = document.getElementById("noteForm");

这是基本思想。 让我们来看看它的作用。

添加新笔记

实际的笔记本身只是一个带有标准文本和链接的小盒子,使用户可以在以后编辑文本, 如图2所示

图2.新笔记
新笔记

这等效于以下HTML:

清单3.目标HTML
<div id="note1" style="width: 100; height:100; border: 1px solid blue; 
                       background-color: yellow; position: absolute; 
                       top: 150; left: 135">
    <a href="javascript:editNote('note1')">edit</a>
    <br />
    New note
</div>

添加实际元素使用标准的DOM技术,如清单4所示

清单4.添加新的note元素
<html>
  <head>
    <title>Getting Sticky</title>
    <style type="text/css">
      * {font-family: sans-serif}
      a {font-size: 6pt}
      .editButton {font-size:6pt}
    </style>

    <script type="text/javascript">
...
      function getCurrentNumber() {
        formElement = document.getElementById("noteForm");
        return formElement.childNodes.item(1).value;
      }

      function makeNewNote(){
        mainDivElement = document.getElementById("mainDiv");

        newNote = document.createElement("div");
        newNote.setAttribute("id", "note"+getCurrentNumber());

        mainDivElement.appendChild(newNote);

        incrementCurrent();

      }
    </script>
  </head>
  <body>
    <div id="mainDiv" style="height:85%; width:85%; border:3px solid red; 
                                             padding: 10px; z-index: -100" >
    
       <h1>Getting Sticky</h1>

       <form id="noteForm">
           Current number of notes  <input type="text" name="total" value="0" 
                                             size="3"/>
           <input type="button" value="Add a new note" 
                                             onclick="makeNewNote()"/>
       </form>

    </div>
  </body>
</html>

在这种情况下,您已经更改了按钮,以使其执行makeNewNote()而不是makeNewNote() incrementCurrent() ,尽管该函数仍在makeNewNote()中使用。 首先,使用getElementById()获取对最终将包含注释的主要div元素的引用。 然后,您可以像使用任何其他语言一样,使用document对象创建一个名为div的新元素。 要设置id属性,只需在新元素上使用setAttribute()方法。

每个便笺将具有唯一的id属性,因此您需要知道当前总数。 要获取此信息,请从表单元素本身的级别开始。 从那里,您可以获取孩子列表。 第一个(索引为0 )是文本,第二个(索引为1 )是实际的input元素。

但是.value呢? 那不是错字吗? 不应该是nodeValue吗?

其实没有 请记住,元素没有值。 乍一看,似乎我在混合DOM和DHTML属性,但是实际上,这里检索的元素不仅仅是org.w3c.dom.Element的实现,而是org.w3c.dom.Element的实现org.w3c.dom.html.HTMLInputElement ,还包括一个value属性,该属性表示表单字段的值。 通过这种方式,DOM模仿了DHTML可用的某些(尽管不是全部)属性。

设置属性后,您只需将新的div元素追加到mainDiv元素(将在其中显示)即可。 至少,如果它具有任何演示文稿属性或文本,它就会。

要添加样式信息,您实际上将使用DHTML样式对象:

清单5.添加样式信息
...
      function makeNewNote(){
        mainDivElement = document.getElementById("mainDiv");

        newNote = document.createElement("div");
        newNote.setAttribute("id", "note"+getCurrentNumber());

        newNote.style.width="100";
        newNote.style.height="100";
        newNote.style.border="1px solid blue";
        newNote.style.backgroundColor="yellow";
        newNote.style.position="absolute";
        newNote.style.top=(150);
        newNote.style.left=(25 + 110*getCurrentNumber());

        mainDivElement.appendChild(newNote);

        incrementCurrent();

      }
...

结果是一个带有蓝色边框的黄色小盒子, 如图3所示。

图3.空框
空盒子

请注意,便笺的left属性取决于当前便笺数,添加每个便笺后便会增加。 这样,您可以添加一系列框, 如图3所示。

添加内容

添加div的内容存在一些问题。 我可以使用innerHTML属性:

newNote.innerHTML = "<a href=\"javascript:editNote('note"  
                     +getCurrentNumber()+")\">edit</a><br />New note";

但是如何使用直接的DOM方法呢? 首先想到的是简单地设置div元素的text节点子元素的值:

noteText = document.createTextNode(
          "<a href=\"javascript:editNote('note"+getCurrentNumber()+")\">"+
          "edit</a><br />New note");
newNote.appendChild(noteText);

确实确实添加了文本,但是结果可能并不完全符合您的期望, 如图4所示。

图4.框中的文本
框中的文字

问题是您不是真正在添加文本,而是在混合内容,包括文本和元素。 浏览器假定您将其表示为CDATA(按字面意义使用),并且未创建元素。 您需要实际添加每个元素,而不是简单地将所有内容添加到一个块中:

清单6.添加内容
...
  function makeNewNote(){
    mainDivElement = document.getElementById("mainDiv");

    newNote = document.createElement("div");
    newNote.setAttribute("id", "note"+getCurrentNumber());
...

      editLink = getEditLink("note"+getCurrentNumber());
      newNote.appendChild(editLink);
      newNote.appendChild(document.createElement("br"));
 
      noteText = document.createTextNode("New Form");
      newNote.appendChild(noteText);

    mainDivElement.appendChild(newNote);

    incrementCurrent();

  }

    function getEditLink(thisId){
      editLink = document.createElement("a");
      linkText = document.createTextNode("edit");

      editLink.setAttribute("href", "javascript:editNote('"+thisId+"')");
        
      editLink.appendChild(linkText);
      return editLink;
    }
...

首先,您创建了一个新函数getEditLink ,该函数返回一个对象。 该对象是a使用标准DOM方法创建a元素。 接下来,添加标准的中断标签br ,最后添加包含实际注释文本的节点。

结果便是完整的注释,其中元素完整且可以使用。

更改现有节点

现在您有了内容,但是如何更改它呢? 由于您是分别添加元素的,因此您仅可以编辑表示笔记文本的单个文本节点。 您可以通过三种方式执行此操作。 首先,您可以删除有问题的节点并添加一个新节点:

清单7.删除节点并添加替换项
...
      function editNote(editLink){
        theDiv = document.getElementById(editLink);
        newText = prompt("What should the note say?");

        oldNode = theDiv.firstChild.nextSibling.nextSibling;
        theDiv.removeChild(oldNode);

        newNode = document.createTextNode(newText);
        theDiv.appendChild(newNode);

      }
...

另一个选择是简单地替换现有节点:

清单8.替换节点
...
      function editNote(editLink){
        theDiv = document.getElementById(editLink);
        newText = prompt("What should the note say?");

        oldNode = theDiv.firstChild.nextSibling.nextSibling;
        newNode = document.createTextNode(newText);
        theDiv.replaceChild(newNode, oldNode);
      }
...

在这种情况下,将oldNode替换为newNode ,并相应地更改文档。

最后,您可以简单地更改现有节点的文本:

清单9.更改现有节点
...
      function editNote(editLink){
        theDiv = document.getElementById(editLink);
        newText = prompt("What should the note say?");

        theDiv.firstChild.nextSibling.nextSibling.nodeValue=newText;
      }
...

因为editNote适当divid值,所以相同的函数可以用于任何注释, 如图5所示

图5.最后一页
最后一页

摘要

在本文中,您已经非常基本地了解了Web页面JavaScript中DOM的使用。 您可以在使用JavaScript的任何地方(例如在XSLT样式表中)使用相同的原理。

文档对象模型将XML文档中的元素,文本和其他类型的节点表示为一系列父子关系。 通过操纵这些单独的节点,您可以影响页面本身。 除了DOM Core方法之外,XHTML页面还可以公开属于DOM HTML模块的属性和方法,该模块试图集成程序员多年使用的许多DHTML属性。


翻译自: https://www.ibm.com/developerworks/web/library/wa-jsdom/index.html

javascript文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值