
您将通过本动手实验室了解如何使用 Dojo 工具包开发高响应、交互式、且基于 AJAX 的 Web 应用程序。本文旨在帮助您尽快入门。有关 Dojo 工具包的详细信息,请参见 Resources section of Dojo Toolkit。
您将在本动手实验室接触到以下技术:(1)如何使用 dojo.io.bind() 调用进行远程访问(2)如何使用 dojo.event.connect() 调用处理包含函数调用在内的各种类型的事件(3)如何使用 Dojo 工具包随附的部件(4)如何使用 JSON 数据格式(5)如何从服务器中获取数据。
有关创建 Dojo 工具包部件将在另一个动手实验室里进行介绍。
预计时间:120 分钟
本动手实验室假定您拥有以下技术的基本知识或者具备相关编程经验:
开始之前,需要在您的计算机上安装以下软件。 本动手实验室压缩文件中已经包含了 Dojo 工具包 0.4.3,不必自行下载。
在本练习中,将要修改 "ajax-validation" 示例程序,来使用 dojo.io.bind() 调用。 也将使用 Dojo 工具包的 DOM 处理工具。您将要修改的这个示例应用程序,是一个可供打开的 NetBeans 项目,名称为 ajax-validation,是动手实验室压缩文件(4260_ajaxdojointro.zip)的组成部分。
0. 启动 NetBeans IDE。
1. 打开 ajax-validation NetBeans 项目。
2. 生成并运行 ajax-validation 项目。

图 1.12:运行项目
3. 注意到 Firefox 浏览器显示出来。
4. 在 User Id: 字段处键入一些字符,如 sa 。
5. 注意到
Valid User Id 字符串显示在文本字段的右侧。(如下图 1.13 所示)本例是一个 AJAX 用法的示例,由服务器通过 AJAX 对输入数据进行验证。

图 1.13:运行 "Data Validation using AJAX" 示例应用程序
可以直接修改 ajax-validation 项目。 但只要将原始项目保留在当前表单中,我们将通过把 ajax-validation 项目复制到一个新项目中来创建这个新项目。将新项目命名为 ajax-validation-dojo.io.bind。
1. 右键单击ajax-validation 项目节点并选择 复制项目。 出现了 复制项目 对话框。
2. 在 项目名称:Project Name: 字段处键入 ajax-validation-dojo.io.bind。单击 复制 按钮。(下图 1.14) ajax-validation-dojo.io.bind 项目出现在项目选项卡窗口中。

图 1.14:复制项目对话框
3. 更改新项目的上下文路径(只针对 NetBeans 5.0. 在 NetBeans 5.5.1 中这一步是自动完成的)

图 1.15:改变上下文路径来反映新项目的上下文路径
1. 右键单击 ajax-validation-dojo.io.bind 项目。
2. 在项目属性窗口,选择 "源" 选项。
3. 在项目属性窗口右侧的窗格中,单击 "Web 页文件夹" 的 "浏览"按钮。
4. 复制 "文件名称" 中的内容。这给出 web 文件夹的位置,Dojo toolkit JavaScript 库文件要复制到这个文件夹中。
5. 打开 Windows 浏览器,到以上所选的文件夹(例如 C:\Sang-Ajaxcourse\ajax-validation-dojo.io.bind\web)。
6.
将整个 dojo-release-1.0.1 文件夹复制到 ...\ajax-validation-dojo.io.bind\web。

图 1.16:复制 Web 文件夹路径
7. Netbeans 项目将自动刷新,并显示 netbeans 项目的新内容。

图 1.17:NetBeans 项目自动刷新并显示出复制的文件夹
返回练习顶部
在本步骤中,将修改 index.jsp 文件以使用 dojo.io.bind(),而无需直接创建 XMlHttpRequest JavaScript 对象并用它来执行和服务器间的异步通信。
1. 双击 ajax-validation-dojo.io.bind 项目的 index.jsp,在源编辑器窗口中打开它。
(如图 1.18 所示)

图 1.18:在源编辑器中打开 index.jsp
2. 修改 index.jsp 文件,如下所示。 需要添加的新的代码段突出显示为 蓝色粗体字,而需要删除的旧代码段则突出显示为 红色粗体字。 保持不变的代码段显示为常规字体。 请留意注释,其解释了为什么有些代码段被删除,而有些被添加进来。 (这是 index.jsp 文件的完整代码。 因此您可以对其进行复制粘贴。)
在 dojo 1.0.x 中,dojo.io.bind()(用于 dojo 0.9 之前的版本)被替换为更加具体的函数,更明确地指示出使用哪种 IO 传输。然而,使用一个对象参数,其具有属性细化 IO 调用的这种形式仍在使用。 新的 xhr 函数如下所示:
|
<html> // Use dojo.xhrGet() for remoting load: function(response, ioArgs) { //The ERROR function will be called in an error case. } /*********** commented out ****************** </script> |
3. 右键单击 ajax-validation-dojo.bo.bind 项目并选择 运行。 新项目应和 以上 ajax-validation 项目的运行方式一样。
故障排除: 如果您遇到问题,例如,在 User Id: 字段处键入一个字符串,而没有生成 Valid User Id 消息(如下图 1.19 所示),请打开 JavaScript 控制台,查看所显示的调试消息(下图 1.19 所示)。

图 1.19:打开 Firebug 控制台进行调试

图 1.20:Firebug 控制台显示出在 JavaScript 中发现的错误。 以上显示出您还没有将 dojo.js 文件复制到项目,或者在 index.jsp 页面中没有正确指定将文件复制到的目录。
| <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> dojo.require("dojox.data.dom"); var target; // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.xhrGet() for remoting dojo.xhrGet( { // URL - location of the data you want to get url: "validate?id=" + escape(target.value), handleAs: "xml", timeout: 5000, // Time in milliseconds load: function(response, ioArgs) { processRequest(response); }, // The ERROR function will be called in an error case. error: function(response, ioArgs) { alert("dojo Error alert !!"); }, }); } // This is the modified processRequest() function function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojox.data.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); setMessageUsingDOM(message); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { //mdiv = document.getElementById("userIdMessage"); mdiv = dojo.byId("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style=\"color:red\">Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style=\"color:green\">Valid User Id</div>"; } } function setMessageUsingDOM(message) { //var userMessageElement = document.getElementById("userIdMessage"); var userMessageElement = dojo.byId("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; messageText = "Valid User Id"; } userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; } </script> |
| // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); dojo.xhrGet( { // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), url: "validateInvalidURL?id=" + escape(target.value), handleAs: "xml", timeout: 5000, // Time in milliseconds load: function(response, ioArgs) { processRequest(response); }, // The ERROR function will be called in an error case. error: function(response, ioArgs) { alert("dojo Error alert !!"); }, }); } |

请注意您过去将 "text/xml" 作为 "mimetype" 的值。它所做的是当接收到来自于服务器的数据时,将其解析为一个 XML 文档。这就是在如下所示的 proceRequest(data) 函数中可以将数据作为 DOM 对象来提取的原因。既然它是一个 DOM 对象,您就可以使用 getElementByTagName(..) 或 dojo.dom.textContent(..) DOM 方法。
| // This is the modified processRequest() function. Note that you don't need to // check if the readyState of the XMLHttpRequest is 4 or not. function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojox.data.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); setMessageUsingDOM(message); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } |
| // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.xhrGet() for remoting processRequest(response); }, ERROR 函数将在发生错误时调用。 |

| // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.xhrGet() for remoting // Send form data."myform" 是输入表单的 ID。 load: function(response, ioArgs) { ERROR 函数将在发生错误时调用。 |
| <form id="myform" name="updateAccount" action="validate" method="post"> <input type="hidden" name="action" value="create"/> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td><b>User Id:</b></td> <td> <input type="text" size="20" id="userid" name="id" onkeyup="validateUserId()"> </td> <td> <div id="userIdMessage"></div> </td> </tr> <tr> <td align="right" colspan="2"> <input id="submit_btn" type="Submit" value="Create Account"> </td> <td></td> </tr> </table> </form> |

| <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> dojo.require("dojox.data.dom"); dojo.require("dojo.back"); djConfig = { //dojoIframeHistoryUrl: "dojo-1.0.0/dojo/resources/iframe_history.html", //for xdomain preventBackButtonFix: false }; var state = { back: function() { alert("BackButton was pressed !"); }, forward: function() { alert("Forward Button was pressed !"); }, }; dojo.back.init(); dojo.back.setInitialState(state); //var req; // No longer needed since we don't need to deal with XMLHttpRequest //var isIE; // No longer needed since wd don't need to deal with browser difference var target; /********************* Commented out ******************* * We don't need to do the low-level XMLHttpRequest handling anymore * since it is handled by dojo.io.bind(). function initRequest(url) { if (window.XMLHttpRequest) { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { isIE = true; req = new ActiveXObject("Microsoft.XMLHTTP"); } } function validateUserId() { if (!target) target = document.getElementById("userid"); var url = "validate?id=" + escape(target.value); initRequest(url); req.onreadystatechange = processRequest; req.open("GET", url, true); req.send(null); } ******************************************************/ // This is the modified validateUserId() function function validateUserId() { dojo.back.addToHistory(state); //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.xhrGet() for remoting dojo.xhrGet( { // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // Send form data."myform" 是输入表单的 ID。 form: dojo.byId("myform"), handleAs: "xml", timeout: 5000, // Time in milliseconds load: function(response, ioArgs) { processRequest(response); }, // The ERROR function will be called in an error case. error: function(response, ioArgs) { alert("dojo Error alert !!"); }, }); } /********************* commented out ************************************** * We don't need to check the status and readyState anymore since it is handled by dojo.io.bind() function processRequest() { if (req.readyState == 4) { if (req.status == 200) { var message = req.responseXML.getElementsByTagName("valid")[0].childNodes[0].nodeValue; setMessageUsingDOM(message); var submitBtn = document.getElementById("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } } } ***********************************************************************/ // This is the modified processRequest() function. Note that you don't need to // check if the readyState of the XMLHttpRequest is 4 or not. function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojox.data.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); setMessageUsingDOM(message); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { //mdiv = document.getElementById("userIdMessage"); mdiv = dojo.byId("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style='color:red; font-family:Arial; font-size:14px; font-weight:bold;'>Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style='color:green; font-family:Arial; font-size:14px; font-weight:bold;'>Valid User Id</div>"; } } function setMessageUsingDOM(message) { //var userMessageElement = document.getElementById("userIdMessage"); var userMessageElement = dojo.byId("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; userMessageElement.style.fontFamily = "Arial"; userMessageElement.style.fontSize = "14px"; userMessageElement.style.fontWeight = "bold"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; userMessageElement.style.fontFamily = "Arial"; userMessageElement.style.fontSize = "14px"; userMessageElement.style.fontWeight = "bold"; messageText = "Valid User Id"; } /*********** commented out ****************** var messageBody = document.createTextNode(messageText); // if the messageBody element has been created simple replace it otherwise // append the new element if (userMessageElement.childNodes[0]) { userMessageElement.replaceChild(messageBody, userMessageElement.childNodes[0]); } else { userMessageElement.appendChild(messageBody); } *******************************************/ // Use innerHTML instead of raw DOM API userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; } </script> <title>Form Data Validation using AJAX</title> </head> |


| // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // The server code in this ajax-validation // sample application expects "GET". It // uses "POST" for account creation. Probably // not a good practice but that is the way // the server side code is written for now. method: "GET", // Send form data. "myform" is the id of the input form. formNode: dojo.byId("myform"), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling // backButton: function() { alert("back button pressed"); }, // New backward button behavior backButton: function() { // Blank out the User Id field value target.value=""; // Display a message indicating Backward button is pressed var userMessageElement = dojo.byId("userIdMessage"); userMessageElement.innerHTML = "Backward button pressed. Start again!"; // Disable the submit button var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; }, forwardButton: function() { alert("forward button pressed");}, // Type of data you want to receive mimetype: "text/xml" }); } |

在本步骤中,将把 JavaScript 代码移入另一个名称为 myjavascript.js 的文件。这是一个可选步骤。
1. (假设您安装了 NetBeans JavaScript 编辑器插件),右键单击 ajax-validation-dojo.io.bind 项目节点下的 Web 页 并选择 New->JSTemplate.js。
2. 注意到出现了 New JSTemplate.js 对话框。
3. 在文件名称字段处键入 myjavascript。单击 完成 按钮。(如图 1.100 所示)

图 1.100:创建 myjavascript.js 文件
注意:如果还没安装 NetBeans JavaScript 编辑器插件,请在 Web Pages 目录下创建一个名称为 myjavacript.js 的新文件。
| dojo.require("dojox.data.dom"); dojo.require("dojo.back"); djConfig = { //dojoIframeHistoryUrl: "dojo-1.0.0/dojo/resources/iframe_history.html", preventBackButtonFix: false }; var state = { back: function() { // Blank out the User Id field value target.value=""; // Display a message indicating Backward button is pressed var userMessageElement = dojo.byId("userIdMessage"); userMessageElement.innerHTML = "Backward button pressed. Start again!"; // Disable the submit button var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; }, forward: function() { alert("Forward Button was pressed !"); }, }; dojo.back.init(); dojo.back.setInitialState(state); //var req; // No longer needed since we don't need to deal with XMLHttpRequest //var isIE; // No longer needed since wd don't need to deal with browser difference var target; /********************* Commented out ******************* * We don't need to do the low-level XMLHttpRequest handling anymore * since it is handled by dojo.io.bind(). function initRequest(url) { if (window.XMLHttpRequest) { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { isIE = true; req = new ActiveXObject("Microsoft.XMLHTTP"); } } function validateUserId() { if (!target) target = document.getElementById("userid"); var url = "validate?id=" + escape(target.value); initRequest(url); req.onreadystatechange = processRequest; req.open("GET", url, true); req.send(null); } ******************************************************/ // This is the modified validateUserId() function function validateUserId() { dojo.back.addToHistory(state); //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.xhrGet() for remoting dojo.xhrGet( { // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // Send form data."myform" 是输入表单的 ID。 form: dojo.byId("myform"), handleAs: "xml", timeout: 5000, // Time in milliseconds load: function(response, ioArgs) { processRequest(response); }, // The ERROR function will be called in an error case. error: function(response, ioArgs) { alert("dojo Error alert !!"); }, }); } /********************* commented out ************************************** * We don't need to check the status and readyState anymore since it is handled by dojo.io.bind() function processRequest() { if (req.readyState == 4) { if (req.status == 200) { var message = req.responseXML.getElementsByTagName("valid")[0].childNodes[0].nodeValue; setMessageUsingDOM(message); var submitBtn = document.getElementById("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } } } ***********************************************************************/ // This is the modified processRequest() function. Note that you don't need to // check if the readyState of the XMLHttpRequest is 4 or not. function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojox.data.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); setMessageUsingDOM(message); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { //mdiv = document.getElementById("userIdMessage"); mdiv = dojo.byId("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style='color:red; font-family:Arial; font-size:14px; font-weight:bold;'>Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style='color:green; font-family:Arial; font-size:14px; font-weight:bold;'>Valid User Id</div>"; } } function setMessageUsingDOM(message) { //var userMessageElement = document.getElementById("userIdMessage"); var userMessageElement = dojo.byId("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; userMessageElement.style.fontFamily = "Arial"; userMessageElement.style.fontSize = "14px"; userMessageElement.style.fontWeight = "bold"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; userMessageElement.style.fontFamily = "Arial"; userMessageElement.style.fontSize = "14px"; userMessageElement.style.fontWeight = "bold"; messageText = "Valid User Id"; } /*********** commented out ****************** var messageBody = document.createTextNode(messageText); // if the messageBody element has been created simple replace it otherwise // append the new element if (userMessageElement.childNodes[0]) { userMessageElement.replaceChild(messageBody, userMessageElement.childNodes[0]); } else { userMessageElement.appendChild(messageBody); } *******************************************/ // Use innerHTML instead of raw DOM API userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; } |
| <%-- Copyright 2005 Sun Microsystems, Inc. All rights reserved. You may not modify, use, reproduce, or distribute this software except in compliance with the terms of the License at: http://developer.sun.com/berkeley_license.html $Id: index.jsp,v 1.4 2005/06/15 05:39:43 gmurray71 Exp $ --%> <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script language="JavaScript" type="text/javascript" src="myjavascript.js"> </script> <title>Form Data Validation using AJAX</title> </head> <body onload="disableSubmitBtn()"> <h1>Form Data Validation using AJAX</h1> <hr/> <p><font face="Arial" size="2"> This example shows how you can use AJAX to do server-side form data validation without a page reload. <br><br> In the form below enter a user id. By default the user ids "greg" and "duke" are taken. If you attempt to enter a user id that has been taken an error message will be displayed next to the form field and the "Create Account" button will be disabled. After entering a valid user id and selecting the "Create Account" button that user id will be added to the list of user ids that are taken. </font></p> <form id="myform" name="updateAccount" action="validate" method="post"> <input type="hidden" name="action" value="create"/> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td><b>User Id:</b></td> <td> <input type="text" size="20" id="userid" name="id" onkeyup="validateUserId()"> </td> <td> <div id="userIdMessage"></div> </td> </tr> <tr> <td align="right" colspan="2"> <input id="submit_btn" type="Submit" value="Create Account"> </td> <td></td> </tr> </table> </form> </body> </html> |
12. 右键单击 ajax-validation-dojo.bo.bind 项目并选择 运行。
在本练习中,修改了使用 XMLHttpRequest 的示例应用程序,而代替为使用 Dojo 工具包中的 dojo.io.bind()。
在本练习中,将练习 Dojo 工具包的几个事件编程模型。
您可以从头创建一个新 NetBeans 项目,但也可以通过复制 ajax-validation-dojo.io.bind 项目,来创建一个包含 Dojo 工具包库文件的项目。我们将其命名为 dojo-event1 项目。
1. 右键单击 ajax-validation-dojo.io.bind 项目并选择 复制项目。 出现了 复制项目 对话框。
2. 在 项目名称: 字段处键入 dojo-event1。(如下图 2.10 所示)复制项目可能需要一些时间。dojo-event1 项目出现在 项目 选项卡窗口中。

图 2.10:通过复制创建 dojo-event1 项目
3. 改变新项目的上下文路径。(您做此操作,只针对 NetBeans 5.0。在 NetBeans 5.5 中是自动完成的。)

图 2.11:将上下文路径改为 /dojo-event1
现在我们要修改 index.jsp,我们将在其中使用 dojo.event.connect()。
注意:如果不想改变原始代码,可以通过复制当前项目创建一个新项目。但如果您决定要这样做的话,要确保将 上下文路径: 加以改变,以反映新项目名称。
1. 右键单击 dojo-event1 项目的 index.jsp 文件,在 源编辑器 中打开它。除非您想要改变 ajax-validation-dojo.io.bind 项目的 index.jsp 文件,否则请确保其不变。
2. 用下面代码(代码 2.20)替换 index.jsp 文件的完整内容。请仔细研究 dojo.event.connect() 调用是如何把 myHandler 事件处理程序注册到 mylink 节点的 onclick 属性中的。
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> window.onload = function () { var link = document.getElementById("mylink"); // "myHandler" event handler is registered to the // "onclick" property of the "mylink" node. dojo.connect(link, "onclick", myHandler); } // Define an event handler named as "myHandler" function myHandler(evt) { alert("myHandler: invoked - this is a named event handler" + "\r\n" + "If you see this, that means calling dojo.connect() was successful."); } </script> <title>Simple Dojo Event Handler</title> </head> <body> <h1>Simple Dojo Event Handler</h1> <hr/> <p><font face="Arial" size="2"> This example shows the usage of dojo.event.connect() registering an event handler to a DOM node. When a user clicks on "Click Me" link, it should pop up an alert, which is invoked within the event handler. </font></p> <a href="#" id="mylink">Click Me</a> </body> </html> |
3. 右键单击 dojo-event1 项目并选择 清理并生成
4. 右键单击 Rdojo-event1 项目并选择 运行。 将会看到以下页面。(如图 2.21 所示)

图 2.21:简单 Dojo 事件处理程序页面

1. 修改 index.jsp,将 dojo.connect() 调用用于窗口加载事件。(如下面 2.30 所示)需要添加的新代码段突出显示为 蓝色粗体字,而需要删除的旧代码段则显示为 红色粗体字。 保持一样的代码段显示为常规字体。
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> //window.onload = function () { function myInit() { var link = document.getElementById("mylink"); // "myHandler" event handler is registered to the // "onclick" property of the "mylink" node. dojo.connect(link, "onclick", myHandler); } // Use dojo.connect to register "myInit" function to "onload" event. dojo.connect(window, "onload", myInit); // Define an event handler named as "myHandler" function myHandler(evt) { alert("myHandler: invoked - this is a named event handler" + "\r\n" + "If you see this, that means calling dojo.connect() was successful." + "\r\n" + "In this call we are using dojo.connect to register \"myInit\" function to \"onload\" event."); } </script> <title>Simple Dojo Event Handler</title> </head> <body> <h1>Simple Dojo Event Handler</h1> <hr/> <p><font face="Arial" size="2"> This example shows the usage of dojo.event.connect() registering an event handler to a DOM node. When a user clicks on "Click Me" link, it should pop up an alert, which is invoked within the event handler. This example also shows how to use dojo.event.connect to register "myInit" function to "onload" event. </font></p> </p> <a href="#" id="mylink">Click Me</a> </body> </html> |
1. 修改 index.jsp 来使用 dojo.connect() 调用,这是用于将一个 JavaScript 对象的函数附加到 DOM 节点的事件处理程序中,从而,当调用 DOM 节点的事件处理程序时,JavaScript 对象的那个函数也被调用。
需要添加的新代码段将突出显示为 蓝色粗体字,而需要删除的原始代码段将突出显示为 红色粗体字。保留不变的代码段将显示为常规字体。
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> function myInit() { var link = document.getElementById("mylink"); // Create exampleObj JavaScript object, which contains foo function var exampleObj = { foo: function(){ alert("exampleObj.foo: invoked !!" + "\r\n" + "If you see this alert, it means the attachment of the exampleObj.foo function " + "to the event handler of a DOM node succeeded" ); }, }; // The "foo" function of the exampleObj is registered for the // "onclick" property of "mylink" node. dojo.connect(link, "onclick", exampleObj, "foo"); // "myHandler" event handler is registered to the // "onclick" property of the "mylink" node. //dojo.connect(link, "onclick", myHandler); } // Define an event handler named as "myHandler" function myHandler(evt) { alert("myHandler: invoked - this is a named event handler" + "\r\n" + "If you see this, that means calling dojo.connect() was successful." + "\r\n" + "In this call we are using dojo.connect to register \"myInit\" function to \"onload\" event."); } // Use dojo.connect to register "myInit" function to "onload" event. dojo.connect(window, "onload", myInit); </script> <title>Attaching a function of an object to a DOM node's event handler</title> </head> <body> <h1>Attaching a function of an object to a DOM node's event handler</h1> <hr/> <p><font face="Arial" size="2"> This example shows the usage of dojo.event.connect() attaching a function of an object to DOM node's event handler. When a user clicks on "Click Me" link, it should pop up an alert, which is invoked within the function of the object. </font></p> <a href="#" id="mylink">Click Me</a> </body> </html> |
2. 右键单击 dojo-event1 项目与选择 运行。
3. 在浏览器中单击 Click Me 连接。 您会看到一条在一个 JavaScript 对象的函数中触发的警告消息。(如下图 2.42 所示) 单击 OK 关闭该警告消息框。

1. 修改 index.jsp 来使用 dojo.event.connect() 调用,这样做是为了注册多事件处理程序。
需要添加的新代码段将突出显示为 蓝色粗体字,而需要删除的原始代码段将突出显示为 红色粗体字。保持不变的代码段将显示为常规字体。
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> function myInit() { var link = document.getElementById("mylink"); // Create exampleObj JavaScript object, which contains foo function var exampleObj = { foo: function(){ alert("exampleObj.foo: invoked !!" + "\r\n" + "If you see this alert, it means the attachment of the exampleObj.foo function " + "to the event handler of a DOM node succeeded" ); }, }; var exampleObj2 = { bar: function(){ alert("exampleObj2.bar: invoked !!" + "\r\n" + "If you see this alert, it means the attachment of the exampleObj2.bar function " + "to the event handler of a DOM node succeeded" ); }, }; // The "foo" function of the exampleObj is registered for the // "onclick" property of "mylink" node. dojo.connect(link, "onclick", exampleObj, "foo"); // The "bar" function of the exampleObj2 is registered for the // "onclick" property of "mylink" node. dojo.connect(link, "onclick", exampleObj2, "bar"); } // Define an event handler named as "myHandler" function myHandler(evt) { alert("myHandler: invoked - this is a named event handler" + "\r\n" + "If you see this, that means calling dojo.connect() was successful." + "\r\n" + "In this call we are using dojo.connect to register \"myInit\" function to \"onload\" event."); } // Use dojo.connect to register "myInit" function to "onload" event. dojo.connect(window, "onload", myInit); </script> <title>Registration of multiple handlers</title> </head> <body> <h1>Registration of multiple handlers</h1> <hr/> <p><font face="Arial" size="2"> This example shows how to register multiple handlers. When a user clicks on "Click Me" link, it should pop up three alerts, one from exampleObj.foo, and the second one from exampleObj2.bar, and the third one from myHandler. </font></p> <a href="#" id="mylink">Click Me</a> </body> </html> |
2. 右键单击 dojo-event1 项目与选择 运行。
3. 在浏览器中单击 Click Me 连接。 您会看到一条在一个 JavaScript 对象的函数中触发的警告消息。(如下图 2.51 所示) 单击 确定 按钮关闭警告消息框。

图 2.51:来自第一个事件处理程序的警告消息
4. 观察从第二个事件处理程序中触发的第二条警告消息。(如下图 2.52 所示) 单击 确定 按钮关闭警告消息框。

图 2.52:来自第二个事件处理程序的警告消息
1. 修改 index.jsp 以使用 dojo.connect() 和 disconnect。
修改过的代码显示在以下部分中,请注意我们创建了两个按钮,一个用于创建 dojo 连接,而另一个则用于断开一个现有连接。
和之前的例子一样,我们也使用 dojo.connect 将 "myInit" 函数注册到"onload" 事件,这反过来也将 "mylink" 的 "onclick: 事件连接到 exampleObj 函数。
当用户单击 "Connect New Function",将调用 callDojoConnect,它将 exampleObj.bar 和 exampleObj.foo 连接起来。Dojo 连接返回一个连接句柄,它被存储起来用于在以后断开连接。
当用户单击 "Disconnect Functions",它调用 dojo.disconnect,使用之前存储的 connectionHandle。这样做将把 example.bar 从和 example.foo 的连接中断开。
需要添加的新代码段将突出显示为 蓝色粗体字,而需要删除的原始代码段将突出显示为 红色粗体字。保持不变的代码片段将显示为常规字体。
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-release-1.0.1/dojo/dojo.js"> </script> <script type="text/javascript"> var connectionHandle; var link = document.getElementById("mylink"); // Create exampleObj JavaScript object var exampleObj = { counter: 0, foo: function(){ this.counter++; alert("exampleObj.foo: invoked, counter = " + this.counter ); }, bar: function(){ this.counter++; alert("exampleObj.bar: invoked, counter = " + this.counter ); }, }; function myInit() { connectionHandle = dojo.connect(link, "onclick", exampleObj, "foo"); } function callDojoConnect() { alert("Connected exampleObj.foo with exampleObj.bar"); connectionHandle = dojo.connect(exampleObj, "foo", exampleObj, "bar"); } function callDojoDisConnect() { alert("Disconnected exampleObj.bar from exampleObj.foo"); dojo.disconnect(connectionHandle); } // Use dojo.event.connect to register "myInit" function to "onload" event. dojo.connect(window, "onload", myInit); </script> <title>Registration of multiple handlers</title> </head> <body> <h1>Registration of multiple handlers</h1> <hr/> <p><font face="Arial" size="2"> This example shows how to connect dojo functions and disconnect those. When the user clicks on "Connect new function" button, the bar function is connected to the foo function. register multiple handlers. When a user clicks on "Click Me" link, it should pop up three alerts, one from exampleObj.foo, and the second one from exampleObj2.bar, and the third one from myHandler. </font></p> <a href="#" id="mylink">Click Here to test dojo handler</a> <br><br> <form name="myTestForm"> <input type="button" name="btnTestConnect" onclick="callDojoConnect()" value="Connect New Function "> <br><br> <input type="button" name="btnTestDisConnect" onclick="callDojoDisConnect()" value="Disconnect Functions"> </form> </body> </html> |
2. 右键单击 dojo-event1 项目并选择 运行项目。
3. 在浏览器中单击 Click Me 连接。 您会在 exampleObj JavaScript 对象的 foo 函数中看到一条警告消息。(如图 2.61 所示所示) 单击 确定 按钮关闭警告消息框。

图 2.61:单击 "mylink" 时调用的 foo 函数
4. 现在单击 "Connect New Function" 按钮。将出现一条警告,表示 exampleObj.foo 已经连接到了 exampleObj.bar。

图 2.62:bar 函数连接到了 foo 函数。


图 2.64:dojo.disconnect() 中断了处理程序。
在本练习中,您通过 dojo.event.connect() 调用,实验了几种编程模型。
返回顶部