AS基础教程整理

 更新时间:2007年03月22日 00:00:00   作者:  

第十四章 最后一个版本选择题

上一个版本面向对象的代码对我们这个基于XML的版本很有帮助,上一个版本我们是用对象的数组来存我们的数据,这个版本里面,我们使用外部的XML文件
下面先看看XML文件的结构:
<QUIZ>
  <QUESTION TEXT="at which version of flash were movie clips introduced?" ANSWER="2">
    <CHOICE>version 1</CHOICE>
    <CHOICE>version 2</CHOICE>
    <CHOICE>version 3</CHOICE>
    <CHOICE>version 4</CHOICE>
    <CHOICE>version 5</CHOICE>
    <CHOICE>version 6</CHOICE>
  </QUESTION>

  <QUESTION TEXT="when was actionscript formally declared a scripting language?" ANSWER="2">
    <CHOICE>version 3</CHOICE>
    <CHOICE>version 4</CHOICE>
    <CHOICE>version 5</CHOICE>
  </QUESTION>

  <QUESTION TEXT="are regular expressions supported by flash 5 actionscript?" ANSWER="1">
    <CHOICE>yes</CHOICE>
    <CHOICE>no</CHOICE>
  </QUESTION> 

  <QUESTION TEXT="which sound format offers the best compression?" ANSWER="0">
    <CHOICE>mp3</CHOICE>
    <CHOICE>aiff</CHOICE>
    <CHOICE>wav</CHOICE>
  </QUESTION> 

  <QUESTION TEXT="true or false: the post-increment operator (++) returns the value of its operand + 1." ANSWER="1">
    <CHOICE>true</CHOICE>
    <CHOICE>false</CHOICE>
  </QUESTION> 

  <QUESTION TEXT="actionscript is based on..." ANSWER="3">
    <CHOICE>java</CHOICE>
    <CHOICE>javascript</CHOICE>
    <CHOICE>c++</CHOICE>
    <CHOICE>ecma-262</CHOICE>
    <CHOICE>perl</CHOICE>
  </QUESTION> 
</QUIZ>

这个XML里面,QUIZ是我们的根元素
每一题都放在QUESTION元素内,题目正文为其属性TEXT,正确答案为其属性ANSWER(ANSWER=1代表选第二个答案)
每一题的选项则是QUESTION的子节点CHOICE
其实根本就不用解释,大家直接看都能看懂
使用了外部XML之后,我们升级题目只需改动XML文件即可,而上一个版本,修改外部AS文件之后还是需要EXPORT一次。

这个版本里面,将保留上个版本大部分的代码,除了输入题目数据的部分,将用XML来代替。
以下代码写到questionsArray.as中覆盖其原来内容
首先仍然定义一个数组来存放数据
var questionsArray = new Array(); 
然后我们定义一个XML对象来存放XML数据
var quizDoc = new XML(); 
之后是建立将XML解释为我们存放题目的对象格式的函数buildQuestionsArray(),同时将它连接到新建的XML对象的onLoad函数,让XML下载完成之后执行这个函数
quizDoc.onLoad = buildQuestionsArray
然后是执行下载XML的AS
quizDoc.load("quiz.xml");

最后我们详细解说一下解释XML的函数
// *** builds an array of question objects based on the dom tree in quizDoc
function buildQuestionsArray () {
  // first, strip unwanted whitespace nodes from the tree.
  // 除去无用的节点,上一章已经有介绍无用节点是如何出现的
  stripWhitespaceDoublePass(quizDoc);

  // now assign a convenient reference to the root QUIZ node
  // XML文件的根节点QUIZ节点就是 quizDoc.childNodes[1],这里将其指名为quizNode,以便运用
  var quizNode = quizDoc.childNodes[1];
  // for each question node that is a child of the QUIZ node...
  // 下面的循环将逐个提取QUIZ节点的子节点,即每条题目
  for(var k = 0; k < quizNode.childNodes.length; k++) {
    // make an array of the text nodes from each CHOICE node
    // 为每条题目建立一个选项数组
    var choicesArray = new Array();
    // 下面的循环则是将题目的子节点,即各选项的nodeValue输入到choicesArray数组中
    for(var j = 0; j < quizNode.childNodes[k].childNodes.length; j++) {
      choicesArray[j] = quizNode.childNodes[k].childNodes[j].firstChild.nodeValue;
    }

    // construct a question object for each QUESTION node,
    // and store it in questionsArray
    // 用题目正文、选项数组、正确答案(正确答案目前还是字符串,所以用Number函数将之转为数字)作为参数,建立Question对象(定义Question对象的代码已经在上个例子中解释了)
    // 将新建的Question对象作为questionsArray数组的一个元素
    questionsArray[k] = new Question (
            Number(quizNode.childNodes[k].attributes.answer),
            quizNode.childNodes[k].attributes.text,
            choicesArray);
  }

  // done loading and processing the quiz questions
  loadMsg = "";

  // begin the quiz
  // 调用函数makeQuestion,之后的进度就同上一个例子了
  makeQuestion(currentQuestion);
}


// *** Strips whitespace nodes from an XML document
// *** by passing twice through each level in the tree
// 下面函数用于除去无用的空白节点,参数是需要处理的XML的根元素(我们已经将其指名为XMLnode了)
function stripWhitespaceDoublePass(XMLnode) {
  // Loop through all the children of XMLnode
  // 循环依次将根元素的子元素提取出来
  for (var k = 0; k < XMLnode.childNodes.length; k++) {
    // If the current node is a text node...
    // 如果该节点是一个文本节点,就开始以下检查 ...
    if(XMLnode.childNodes[k].nodeType == 3) {

      // ...check for any useful characters in the node.
      var j = 0;
      var emptyNode = true;
        for(j = 0;j < XMLnode.childNodes[k].nodeValue.length; j++) {
          // A useful character is anything over 32 (space, tab, 
          // new line, etc are all below).
          // 因为空格、TAB或换行等空白无意义字符的ASCII码都小于32,检查若大于32,即为有数据的节点,同时用break;跳出检查的循环
          if(XMLnode.childNodes[k].nodeValue.charCodeAt(j) > 32) {
            emptyNode = false;
            break;
        }
      }

      // If no useful charaters were found, delete the node.
      // 若该节点没有数据,就是解释时的错误,将其删除
      if(emptyNode) {
        XMLnode.childNodes[k].removeNode();
      }
    }
  }

  // Now that all the whitespace nodes have been removed from XMLnode,
  // call stripWhitespaceDoublePass on its remaining children.
  // 但是还没完,我们只检查了所有子节点,而没有检查子节点的子节点,所以以下的循环将所有子节点也送到本函数再继续检查
  // 这种函数自己调用自己的方法,称为递归,它将一直检查子节点的子节点的子节点的……一直到该节点没有子节点为止
  for(var k = 0; k < XMLnode.childNodes.length; k++) {
    stripWhitespaceDoublePass(XMLnode.childNodes[k]);
  }


现在,我们可以把SWF和XML组成的题目交给一个不会编FLASH的老师了,他只要就会用记事本修改XML文件就行了

全教程完

相关文章

最新评论