建立基于 DOM 的 Web 应用程序

原创 2007年09月30日 09:37:00
 
在不刷新页面的情况下使用 DOM 改变网页界面
 
开发一个简单的 Web 应用程序,其用户界面可根据用户动作改变,当然要使用 DOM 来处理界面的改变。读完本文,就已经把关于 DOM 的技术和概念付诸应用了。请先切实掌握什么是 DOM 以及 Web 浏览器如何将提供给它的 HTML 和 CSS 转化成单个表示网页的树状结构(请查看本Blog中这两篇文章:1、利用DOM进行Web响应;2、操纵DOM ;在这两篇文章中有详细讲述)。
 
从一个示例应用程序开始
初始 HTML
清单 1 显示了这个网页的 HTML。除了标题和表单外,只有一个简单的图片和可以点击的按钮。
 
清单 1. 示例应用程序的 HTML
<html>
 <head>
 <title>Magic Hat</title>
 </head>
 
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" />
   </p>
 </form>                                                                     
 </body>
</html>
 
关于 HTML 的补充说明
 
应该 注意的重要一点是,清单 1中按钮的类型是 button 而不是提交按钮。如果使用提交按钮,单击该按钮将导致浏览器提交表单,当然表单没有 action 属性(完全是有意如此),从而会造成没有任何动作的无限循环。(应该自己试试,看看会发生什么。)通过使用一般输入按钮而不是提交按钮,可以把 javaScript 函数和它连接起来与浏览器交互而无需 提交表单。
 
向示例应用程序添加元素
 
现在用一些 JavaScript、DOM 操作和小小的图片戏法装扮一下网页。
 
使用 getElementById() 函数
 
完成这个 DOM 小戏法的第一步是找到网页中表示 img 元素的 DOM 节点。一般来说,最简单的办法是用 getElementById() 方法,它属于代表 Web 页面的 document 对象。前面已经见到过这个方法,用法如下:
 
var elementNode = document.getElementById("id-of-element");
HTML 添加 id 属性
这是非常简单的 JavaScript,但是需要修改一下 HTML:为需要访问的元素增加 id 属性。也就是希望(用带兔子的新图片)替换的 img 元素,因此将 HTML 改为清单 2 的形式。
清单 2. 增加 id 属性
<html>
 <head>
 <title>Magic Hat</title>
 </head>
 
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" />
   </p>
 </form>                                                                    
 </body>
</html>
 
如果重新加载(或者打开)该页面,可以看到毫无变化,增加 id 属性对网页的外观没有影响。不过,该属性可以帮助 JavaScript 和 DOM 更方便地处理元素。
抓住 img 元素
现在可以很容易地使用 getElementById() 了。已经有了需要元素的 ID,即 topHat,可以将其保存在一个新的 JavaScript 变量中。在 HTML 页面中增加清单 3 所示的代码。
清单 3. 访问 img 元素
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" />
   </p>
 </form>                                                                    
 </body>
</html>
 
现在打开或重新加载该网页同样没有什么惊奇的地方。虽然现在能够访问图片,但是对它还什么也没有做。
修改图片,麻烦的办法
完成所需修改有两种方法:一种简单,一种麻烦。和所有的好程序员一样,我也喜欢简单的办法;但是运用较麻烦的办法是一次很好的 DOM 练习,值得您花点时间。首先看看换图片比较麻烦的办法;后面再重新分析一下看看有没有更简单的办法。
 
用带兔子的新照片替换原有图片的办法如下:
 
创建新的 img 元素。
访问当前 img 元素的父元素,也就是它的容器。
在已有 img 元素之前 插入新的 img 元素作为该容器的子级。
删除原来的 img 元素。
结合起来以便在用户单击 Hocus Pocus! 按钮时调用刚刚创建的 JavaScript 函数。
创建新的 img 元素
 
记住 DOM 中最关键的是 document 对象。它代表整个网页,提供了 getElementById() 这样功能强大的方法,还能够创建新的节点。现在要用到的就是这最后一种性质。
 
具体而言,需要创建一个新的 img 元素。要记住,在 DOM 中一切都是节点,但是节点被进一步划分为三种基本类型:
 
元素
属性
文本节点
还有其他类型,但是这三种可以满足 99% 的编程需要。这里需要一个 img 类型的新元素。因此需要下列 JavaScript 代码:
 
var newImage = document.createElement("img");
 
 
 
这行代码可以创建一个 element 类型的新节点,元素名为 img。在 HTML 中基本上就是:
 
<img />
 
要记住,DOM 会创建结构良好的 HTML,就是说这个目前为空的元素包括起始和结束标签。剩下的就是向该元素增加内容或属性,然后将其插入到网页中。
 
对内容来说,img 是一个空元素。但是需要增加一个属性 src,它指定了要加载的图片。您也许认为要使用 addAttribute() 之类的方法,但情况并非如此。DOM 规范的制定者认为程序员可能喜欢简洁(的确如此!),因此他们规定了一个方法同时用于增加新属性和改变已有的属性值:setAttribute()。
 
如果对已有的属性调用 setAttribute(),则把原来的值替换为指定的值。但是,如果调用 setAttribute() 并指定一个不 存在的属性,DOM 就会使用提供的值增加一个属性。一个方法,两种用途!因此需要增加下列 JavaScript 代码:
 
var newImage = document.createElement("img");
newImage.setAttribute("src", "rabbit-hat.gif");
 
它创建一个图片元素然后设置适当的资源属性。现在,HTML 应该如清单 4 所示。
清单 4. 使用 DOM 创建新图片
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      var newImage = document.createElement("img");
      newImage.setAttribute("src", "rabbit-hat.gif");
    }
 </script>
 </head>
 
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" />
   </p>
 </form>                                                                    
 </body>
</html>
 
可以加载该页面,但是不要期望有任何改变,因为目前所做的修改实际上还没有影响页面。另外,如果再看看任务列表中的第 5 步,就会发现还没有调用我们的 JavaScript 函数!
 
获得原始图片的父元素
现在有了要插入的图片,还需要找到插入的地方。但是不能将其插入到已有的图片中,而是要将其插入到已有图片之前然后再删除原来的图片。为此需要知道已有图片的父元素,实际上这就是插入和删除操作的真正关键所在。
 
DOM 确实把网页看成一棵树,即节点的层次结构。每个节点都有父节点(树中更高层次的节点,该节点是它的一个子级),可能还有自己的子节点。对于图片来说,它没有子级 —— 要记住图片是空元素,但是它肯定有父节点。甚至不需要知道父节点是什么,但是需要访问它。
 
为此,只要使用每个 DOM 节点都有的 parentNode 属性即可,比如:
var imgParent = hatImage.parentNode;
 
确实非常简单!可以肯定这个节点有子节点,因为已经有了一个:原来的图片。此外,完全不需要知道它是一个 div、p 或者页面的 body,都没有关系!
 
插入新图片
现在得到了原来图片的父节点,可以插入新的图片了。很简单,有多种方法可以添加子节点:
insertBefore(newNode, oldNode)
appendChild(newNode)
因为希望把新图片放在旧图片的位置上,需要使用 insertBefore()(后面还要使用 removeChild() 方法)。可使用下面这行 JavaScript 代码把新图片元素插入到原有图片之前:
 
var imgParent = hatImage.parentNode;
imgParent.insertBefore(newImage, hatImage);
 
现在原图片的父元素有了两个子元素:新图片和紧跟在后面的旧图片。必须指出,这里包围 这些图片的内容没有变,而且这些内容的顺序也和插入之前完全相同。仅仅是这个父节点中增加了一个子节点,即旧图片之前的新图片。
 
删除旧图片
 
现在只需要删除旧图片,因为网页中只需要新图片。很简单,因为已经得到了旧图片元素的父节点。只要调用 removeChild() 并把需要删除的节点传递给它即可:
 
var imgParent = hatImage.parentNode;
imgParent.insertBefore(newImage, hatImage);
imgParent.removeChild(hatImage);
 
 
 
现在,用新图片替换旧图片的工作已基本完成了。HTML 应该如清单 5 所示。
 
清单 5. 用新图片替换旧图片
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      var newImage = document.createElement("img");
      newImage.setAttribute("src", "rabbit-hat.gif");
      var imgParent = hatImage.parentNode;
      imgParent.insertBefore(newImage, hatImage);
      imgParent.removeChild(hatImage);
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" />
   </p>
 </form>                                                                     
 </body>
</html>
 
连接 JavaScript
最后一步,可能也是最简单的,就是把 HTML 表单连接到刚刚编写的 JavaScript 函数。需要每当用户点击 Hocus Pocus! 按钮的时候运行 showRabbit() 函数。为此只要向 HTML 中增加一个简单的 onClick 事件处理程序即可。
<input type="button" value="Hocus Pocus!" onClick="showRabbit();" />
这种简单的 JavaScript 编程应该非常容易了。将其添加到 HTML 页面中,保存它然后在 Web 浏览器中打开。页面初看起来应该和图 1 相同,但是点击 Hocus Pocus!
 
替换图片,简单的办法
如果回顾替换图片的步骤,再看看节点的各种方法,可能会注意到方法 replaceNode()。该方法可用于把一个节点替换为另一个节点。再考虑一下前面的步骤:
 
创建新的 img 元素。
访问当前 img 元素的父元素,也就是它的容器。
在已有 img 元素之前 插入新的 img 元素作为该容器的子元素。
删除原来的 img 元素。
连接起来以便在用户点击 Hocus Pocus! 的时候调用刚刚创建的 JavaScript 函数。
使用 replaceNode() 可以减少需要的步骤数。可以将第 3 步和第 4 步合并在一起:
 
创建新的 img 元素。
访问当前 img 元素的父元素,也就是它的容器。
用创建的新元素替换旧的 img 元素。
连接起来以便在用户点击 Hocus Pocus! 的时候调用刚刚创建的 JavaScript 函数。
这看起来不是什么大事,但确实能够简化代码。清单 6 说明了这种修改:去掉了 insertBefore() 和 removeChild() 方法调用。
 
清单 6. 用新图片替换旧图片(一步完成)
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      var newImage = document.createElement("img");
      newImage.setAttribute("src", "rabbit-hat.gif");
      var imgParent = hatImage.parentNode;
      imgParent.replaceChild(newImage, hatImage);
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" onClick="showRabbit();" />
   </p>
 </form>                                                                     
 </body>
</html>
 
当然这不是什么大的修改,但是说明了 DOM 编码中一件很重要的事:执行一项任务通常有多种方法。如果仔细审阅可用 DOM 方法看看是否有更简单的方法可以完成任务,很多时候都会发现可以将四五个步骤压缩为两三个步骤。
 
替换图片,(真正)简单的办法
 
既然指出了执行一项任务几乎总是有更简单的方法,现在就说明用兔子图片替换帽子图片的简单得多的办法。阅读本文的过程中有没有想到这种方法?提示一下:与属性有关。
 
要记住,图片元素很大程度上是由其 src 属性控制的,他引用了某个地方的文件(不论是本地 URI 还是外部 URL)。到目前为止,我们一直用新图片替换图片节点,但是直接修改已有图片的 src 属性要简单得多!这样就避免了创建新节点、寻找父节点和替换旧节点的所有工作,只要一步就能完成了:
 
hatImage.setAttribute("src", "rabbit-hat.gif");
 
这样就够了!看看清单 7,它显示了这种解决方案,包括整个网页。
 
清单 7. 修改 src 属性
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      hatImage.setAttribute("src", "rabbit-hat.gif");
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" onClick="showRabbit();" />
   </p>
 </form>                                                                     
 </body>
</html>
 
这是 DOM 最棒的一点:更新属性的时候网页马上就会改变。只要图片指向新的文件,浏览器就加载该文件,页面就更新了。不需要重新加载,甚至不需要创建新的图片元素!结果仍然和图 3 相同,只不过代码简单得多了。
 
把兔子藏起来
现在网页看起来很漂亮,但是仍然有点原始。虽然兔子从帽子中跳出来了,但是屏幕下方的按钮仍然显示 Hocus Pocus! 和调用 showRabbit()。这就是说如果在兔子出来之后仍然点击按钮,就是在浪费处理时间。更重要的是,它毫无用处,而没有用的按钮不是好东西。我们来看看能否利用 DOM 再作一些修改,无论兔子在帽子里还是出来都让这个按钮派上用场。
 
修改按钮的标签
最简单的是当用户点击按钮之后改变它的标签。这样就不会看起来像还有什么魔法,网页中最糟糕的就是暗示用户错误的东西。在修改按钮的标签之前需要访问该节点,而在此之前需要引用按钮 ID。这是老套路了,清单 8 为按钮增加了 id 属性。
 
清单 8. 增加 id 属性
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      hatImage.setAttribute("src", "rabbit-hat.gif");
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" id="hocusPocus"
           onClick="showRabbit();" />
   </p>
 </form>                                                                    
 </body>
</html>
 
现在用 JavaScript 访问按钮很简单了:
function showRabbit() {
 var hatImage = document.getElementById("topHat");
 hatImage.setAttribute("src", "rabbit-hat.gif");
 var button = document.getElementById("hocusPocus");
}
 
当然,您可能已经输入了下面这行 JavaScript 来改变按钮的标签值。这里再次用到了 setAttribute():
 
function showRabbit() {
 var hatImage = document.getElementById("topHat");
 hatImage.setAttribute("src", "rabbit-hat.gif");
 var button = document.getElementById("hocusPocus");
 button.setAttribute("value", "Get back in that hat!");
}
 
通过这个简单的 DOM 操作,兔子跳出来之后按钮的标签马上就会改变。现在,HTML 和完成的 showRabbit() 函数如清单 9 所示。
 
清单 9. 完成的网页
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      hatImage.setAttribute("src", "rabbit-hat.gif");
      button.setAttribute("value", "Get back in that hat!");
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" id="hocusPocus"
           onClick="showRabbit();" />
   </p>
 </form>                                                                     
 </body>
</html>
 
把兔子收回去
从此新的按钮标签中可能已经猜到,现在要把兔子收回帽子中去。基本上和放兔子出来完全相反:将图片的 src 属性再改回旧图片。创建一个新的 JavaScript 函数来完成这项任务:
 
function hideRabbit() {
 var hatImage = document.getElementById("topHat");
  hatImage.setAttribute("src", "topHat.gif");
 var button = document.getElementById("hocusPocus");
 button.setAttribute("value", "Hocus Pocus!");
}
 
实际上仅仅把 showRabbit() 函数的功能翻转了过来。将图片改为原来的没有兔子的大礼帽,抓取按钮,将标签改为 Hocus Pocus!
 
事件处理程序
现在这个示例应用程序有一个大问题:虽然按钮的标签改变了,但是单击按钮时的动作没有 变。幸运的是,当用户单击按钮时可以使用 DOM 改变事件或者发生的动作。因此,如果按钮上显示 Get back in that hat!,点击的时候需要运行 hideRabbit()。相反,一旦兔子藏了起来,按钮又返回来运行 showRabbit()。
 
避免使用 addEventHandler()
除了 onclick 属性外,还有一个方法可用于添加 onClick 或 onBlur 这样的事件处理程序,毫不奇怪这个方法就叫 addEventHandler()。不幸的是,Microsoft™ Internet Explorer™ 不支持这个方法,如果在 JavaScript 中使用它,就会有数百万 Internet Explorer 用户除了错误外从网页中什么也看不到(可能还有抱怨)。不使用这个方法,应用本文中介绍的办法也能达到同样的效果,而且在 Internet Explorer 上也有效。
 
查看 HTML 就会发现这里处理的事件是 onClick。在 JavaScript 中,可以通过按钮的 onclick 的属性来引用该事件。(要注意,在 HTML 中该属性通常称为 onClick,其中 C 大写;而在 JavaScript 中则称为 onclick,全部小写。)因此可以改变按钮触发的事件:只要赋给 onclick 属性一个新的函数。
 
但是有点细微的地方:onclick 属性需要提供函数引用——不是函数的字符串名称,而是函数本身的引用。在 JavaScript 中,可以按名称引用函数,不需要带括号。因此可以这样修改点击按钮时执行的函数:
button.onclick = myFunction;
 
因此在 HTML 中作这种修改很简单。看看清单 10,它切换按钮触发的函数。
 
清单 10. 改变按钮的 onClick 函数
<html>
 <head>
 <title>Magic Hat</title>
 <script language="JavaScript">
    function showRabbit() {
      var hatImage = document.getElementById("topHat");
      hatImage.setAttribute("src", "rabbit-hat.gif");
      var button = document.getElementById("hocusPocus");
      button.setAttribute("value", "Get back in that hat!");
      button.onclick = hideRabbit;
    }
    function hideRabbit() {
      var hatImage = document.getElementById("topHat");
      hatImage.setAttribute("src", "topHat.gif");
      var button = document.getElementById("hocusPocus");
      button.setAttribute("value", "Hocus Pocus!");
      button.onclick = showRabbit;                                          
    }
 </script>
 </head>
 <body>
 <h1 align="center">Welcome to the DOM Magic Shop!</h1>
 <form name="magic-hat">
   <p align="center">
    <img src="topHat.gif" id="topHat" />
    <br /><br />
    <input type="button" value="Hocus Pocus!" id="hocusPocus"
           onClick="showRabbit();" />
   </p>
 </form>                                                                    
 </body>
</html>
 
这样就得到了一个完成的、可以使用的 DOM 应用程序。自己试试吧!
 
结束语
现在您应该非常熟悉 DOM 了。事实上,如果在 Ajax 和 JavaScript 世界中不使用 DOM 就很难做多少事,至少在一定程度上如此。无论要创建复杂的突出显示还是移动效果,或者仅仅处理文本块或图片,DOM 都提供了一种非常简单易用的访问 Web 页面的方式。
 

相关文章推荐

掌握 Ajax,第 6 部分: 建立基于 DOM 的 Web 应用程序

本系列的上一篇文章中考察了文档对象模型(DOM)编程中涉及到的概念——Web 浏览器如何把网页看作一棵树,现在您应该理解了 DOM 中使用的编程结构。本期教程将把这些知识用于实践,建立一个简单的包含一...

Ajax 入门1:如何用Ajax建立一个简单的web应用程序(html + javascript + php)

最近对 Ajax 产生了兴趣,花了

如何使用 Eclipse 插件和简洁的 Groovy 语言在 EC2 上快速地建立和运行简单的 Web 应用程序

您可能听说过 Standish Chaos Report,这份每年一次的报告研究成功和失败的 IT 项目。这份报告常常包含大量坏消息。(如果都是好消息,它就不应该称为 Chaos Report 了,对...

DOM应用程序实时操作ie浏览器内容---遍历网页中的元素

一、摘要   在我们编写的程序中,如果想要实现对浏览器打开的网页进行监视、模拟操纵、动态提取用户输入、动态修改......等功能,那么请你抽出宝贵的时间,继续往下阅读。本文介绍的知识和示例程序都是围...

WEB应用程序编码规范

  • 2015年12月16日 11:27
  • 220KB
  • 下载

使用 Bootstrap 快速开发网站和 Web 应用程序

了解如何使用 Bootstrap 快速开发网站和 Web 应用程序(包括移动友好型应用程序)。Bootstrap 以 LESS 项目为基础,由 Twitter 的内部工程师开发,它为 Web 应用程序...

第二章-Web应用程序开发环境.ppt

  • 2014年11月15日 20:12
  • 3.73MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:建立基于 DOM 的 Web 应用程序
举报原因:
原因补充:

(最多只允许输入30个字)