2

我一直在尝试使用 Ajax 构建一个问答应用程序。我需要帮助创建一个特定的功能。我创建了包含不同问题和答案的 XML 文件。基本思想是使用“get”函数(1)加载一个 XML 问题文件,(2)使用“display”和“math.random”函数显示一个随机的“question”元素(对应的“answer”元素将同时显示,但被 Javascript 隐藏。)这是我正在使用的 XML 文件的格式。这些节点由父节点 Words..

<WordQuestions>
    <Question>Question1</Question>
    <Answer>Answer1</Answer>
</WordQuestions>

<WordQuestions>
    <Question>Question2</Question>
    <Answer>Answer2</Answer>
</WordQuestions>

我需要创建一个函数,该函数可以从 XML 文件中随机选择一个问答元素,将其显示给用户,但不会在用户后续点击时再次显示。因此,一旦向用户显示问题,就需要将其从问题列表中删除,以便在下次单击时向用户显示。有人知道怎么做这个吗?

我创建了一个类似魅力的功能,但它的局限性在于它过于随机 - 可能永远不会选择问题和答案元素来向用户显示,或者它可能被选择的次数不成比例。用户需要练习所有的问题。这是此功能的精简版。

<script language = "javascript">


  function getCategory()
  {
    var XMLHttpRequestObject = false; 

    if (window.XMLHttpRequest) {
      XMLHttpRequestObject = new XMLHttpRequest();
      XMLHttpRequestObject.overrideMimeType("text/xml");
    } else if (window.ActiveXObject) {
      XMLHttpRequestObject = new 
        ActiveXObject("Microsoft.XMLHTTP");
    }


    if(XMLHttpRequestObject) {

    var P = document.LoadCategory.Load.value;
    if (P == "Category1") {XMLHttpRequestObject.open("GET", "Catgory1.xml", true)}
    if (P == "Category2") {XMLHttpRequestObject.open("GET", "Category2.xml", true)} 
    if (P == "Category3") {XMLHttpRequestObject.open("GET", "Category3.xml", true)}


      XMLHttpRequestObject.onreadystatechange = function() 
      { 
        if (XMLHttpRequestObject.readyState == 4 && 
          XMLHttpRequestObject.status == 200) { 
        var xmlDocument = XMLHttpRequestObject.responseXML;
        displayCategory(xmlDocument);
        } 
      } 

      XMLHttpRequestObject.send(null); 
    }
  }

  function displayCategory (xmldoc)
  {

    Questionnodes = xmldoc.getElementsByTagName("Question");
    Answernodes = xmldoc.getElementsByTagName("Answer");
    var i = Math.floor((Math.random()*1000)%Questionnodes.length);
    var i = Math.floor((Math.random()*1000)%Answernodes.length);        

    var displayText1 =
      Questionnodes[i].firstChild.nodeValue;

    var target = document.getElementById("targetDiv1");
    target.innerHTML=displayText1;        


    var displayText2 =
      Answernodes[i].firstChild.nodeValue;

    var target = document.getElementById("targetDiv2");
    target.innerHTML=displayText2;

  }

</script>

现在,我不知道我是否能够更改此代码以获得我想要的功能。我曾尝试将 XML 文件解析为 javascript 数组(然后随机选择并删除一个元素),但 atm 无处可去。如果有人有一些建议,我将不胜感激。再一次,我想要一个函数,它可以从 XML 文件中随机选择一个问答元素,但只向用户显示一次。干杯,伙计们。(对不起,这太啰嗦了)。

4

2 回答 2

0

用 var hasbeenshown、hasbeenanswered、useranswer、函数 getquestion、函数 getanswer 编写一个类。

实例化的类,在加载时填充您的 xml 文件中的值,您可以将其添加到数组中并使用您的随机数来选择一个随机问题。

于 2012-05-27T16:51:13.443 回答
0

这是一个示例的链接,说明我将如何做你想做的事情:http: //jsfiddle.net/dievardump/xL5mg/4/

我评论了代码的某些部分,并“模拟”了您的getCategory方法。

注意:从我的代码中,我认为没有做到的是“pickRandom”方法。我认为您几乎拥有完成其他部分所需的一切。

我在我的代码中做什么:

  • 我有一个问答集
  • 我有一个 QuestionAndAnswer 构造函数

当服务器结果出现时,我“解析”xml 文件并用 QuestionAndAnswer 对象填充集合。

HTML 中有一个“加载问题”按钮。当您单击它时,它会调用 displayQuestion 方法。

此方法从集合中选择(获取和删除)随机 QandA 对象,然后显示问题和一个按钮以查看相关答案。

就像我在评论中所说的那样,我决定一个接一个地添加问题,但是您可以通过只有一个问题和响应处理程序并修改其内容来改变它。

如果有一天 jsfiddle 决定不再工作,这是代码:

Javascript

(function() {   
// Question and Answer collection
var oQandACollection = {
    collection : [],
    length : 0,

    // get a QandA object
    get : function(i) {
        if (i < this.length) {
            return this.collection[i];
        }      
        return null;
    },

    // add a QandA object
    add : function(qanda) {
         this.collection.push(qanda);
         this.length++;
    },

    // remove a QandA object
    remove : function(i) {
        if (typeof this.collection[i] !== 'undefined') {
            this.collection.splice(i, 1);
            this.length--;
        }
    },

    // randomly pick an object from the collection
    pickRandom : function() {
        if (this.length === 0) return null; // return null if there is no object in the collection
        var i = Math.floor(Math.random() * this.length);
        var qanda = this.get(i);
        this.remove(i);
        return qanda;
    }

};

// Question and Answer Object
var QandA = function(xmlNode) {

    var question = xmlNode.getElementsByTagName('Question')[0] || null;
    var answer = xmlNode.getElementsByTagName('Answer')[0] || null;
    if (question && answer) {
        this.question = question.textContent;
        this.answer = answer.textContent;
    } else {
        return null;   
    }  
};

// function to use as ajax request handler
function fillQandA(xmlDoc) {
    // get all WordQuestions elements
    var wrappers = xmlDoc.getElementsByTagName('WordQuestions');
    for(var i = 0, l = wrappers.length, qanda = null; i < l; i++) {
        // create a new question from the current wrapper
        // we could have perfom the getElementsByTagName('Question') here
        // but since the code is really specific to your example i putted it in the constructor of QandA
        // You can change it
        qanda = new QandA(wrappers[i]);
        if (qanda) {
            oQandACollection.add(qanda);  
        }
    }
};


var eList = document.getElementById('qa-list'),
    eLoadQuestion = document.getElementById('load-qanda');

// functions to display a question
// i choosed to add question the one after the others,
// so i re-create html elements at every display
// but you also can modify it to have just one question at a time
// matter of choice
function displayQuestion() {
    var qanda = oQandACollection.pickRandom(); // get a question

    if (qanda) { // if there is a question

        // create elements
        var eQuestion = document.createElement('p'),
            eAnswer = document.createElement('p'),
            eBtn = document.createElement('button');

        eQuestion.textContent = qanda.question;
        eAnswer.textContent = qanda.answer;

        eQuestion.classNAme += ' question';
        eAnswer.className += ' answer';
        eBtn.textContent = 'Show Answer';


        // add click event listener to the button to show the answer
        eBtn.addEventListener('click', function() {
            eAnswer.style.display = 'block';
            eList.removeChild(eBtn);
        }, false);

        eList.appendChild(eQuestion);
        eList.appendChild(eAnswer);
        eList.appendChild(eBtn);
    }
};

// add click event handler on display
eLoadQuestion.addEventListener('click', displayQuestion, false);



// simulate xhr request
function getCategory() {
    // fill fake Q&A xml document
    var xmlDoc = document.createElement('root');
    for(var i = 0, wrapper = null, question = null, answer = null; i < 10; i++) {
        wrapper = document.createElement('WordQuestions');                   
        question = document.createElement('Question');
        question.textContent = 'Question ' + (i+1);                  
        answer = document.createElement('Answer');
        answer.textContent = 'Answer ' + (i+1);

        wrapper.appendChild(question);
        wrapper.appendChild(answer);

        xmlDoc.appendChild(wrapper);

    }   

    // us as xhr request handler like : fillQandA(XMLHttpRequestObject.responseXML);
    fillQandA(xmlDoc);        
}

getCategory();

// test function
function test() {
    for(var i = oQandACollection.length; i--; ) {
        displayQuestion();
    }
}

//test();
})();

HTML

<div class="wrapper">
<div id="qa-list">
</div>
<button id="load-qanda" value="Load new question">Load new question</button>

</div>

CSS

    .wrapper {
    width : 500px;      
}

.wrapper > div {
    position : relative;
    width : 100%    
}

.answer {
    display : none;    
}
于 2012-05-27T18:17:22.827 回答