简体   繁体   English

如何以每次加载一次随机顺序获取带有Jquery和显示元素的XML文件?

[英]How to Get XML file with Jquery and Display Elements in Random Order ONCE per load?

I have been trying to build a question and answer app with Ajax. 我一直在尝试用Ajax构建一个问答软件。 I need help creating a particular function. 我需要创建特定功能的帮助。 I have created XML files with different questions and answers. 我创建了具有不同问题和答案的XML文件。 The basic idea is to use the "get" function to (1) load an XML questions file and (2) use the "display" and "math.random" functions to display a random "question" element (the corresponding "answer" element will be shown at the same time, but hidden from view by Javascript.) This is the format of the XML files I am using. 基本思想是使用“获取”功能来(1)加载XML问题文件,以及(2)使用“显示”和“ math.random”功能来显示随机的“问题”元素(相应的“答案”元素将同时显示,但被Javascript隐藏。)这是我正在使用的XML文件的格式。 These nodes are enclosed by a parent node, Words.. 这些节点由父节点Words包围。

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

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

I need to create a function that can choose a question & answer element at random from the XML file, show it to the user, but NOT show it again on subsequent clicks by the user. 我需要创建一个函数,该函数可以从XML文件中随机选择一个问题和答案元素,并向用户显示,但在用户随后的点击中不再显示。 So, once a question is shown to the user, it needs to be removed from the list of questions to be shown to the user on the next click. 因此,一旦向用户显示了一个问题,就需要将其从问题列表中删除,以便在下次单击时向用户显示。 Does anybody know how to do this? 有人知道怎么做这个吗?

I have created a similar function that works like a charm, but it is limited in that it is too random - a questions & answer element may never be selected to show to the user, or it could be selected a disproportionate number of times. 我创建了一个类似超级按钮的功能,但是它的局限性在于它太随机了-可能永远不会选择向用户显示问题和答案元素,或者可能会选择不成比例的次数。 The user needs to practice with all of the questions. 用户需要练习所有问题。 Here is a stripped-down version of this function. 这是此功能的精简版本。

<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>

Right now, I do not know if I am able to alter this code to get the function I want. 现在,我不知道我是否能够更改此代码来获得所需的功能。 I have tried parsing an XML file into a javascript array (and then randomly select and remove an element) but have gotten nowhere atm. 我曾尝试将XML文件解析为javascript数组(然后随机选择和删除一个元素),但没有获得atm。 If anyone has a few suggestions, I would be most grateful. 如果有人有什么建议,我将不胜感激。 Once again, I want a function that can randomly select a question & answer element from an XML file, but only show it to the user ONCE. 再一次,我想要一个可以从XML文件中随机选择问题和答案元素,但仅向用户显示一次的函数。 Cheers guys. 干杯们。 (sorry this was so long-winded). (对不起,这是如此冗长)。

write a class with a var hasbeenshown, hasbeenanswered, useranswer, function getquestion, function getanswer. 编写一个具有变种的类,该变种已被显示,已被回答,用户回答,函数getquestion,函数getanswer。

the instanciated classes, filled with values from your xml file on load you can add to an array and use your random number to choose a random question. 实例化的类,在加载时用xml文件中的值填充,您可以将其添加到数组中,并使用随机数选择随机问题。

here is a link to an example of how I would do what you're trying to : http://jsfiddle.net/dievardump/xL5mg/4/ 这是指向我将如何执行您要执行的操作的示例的链接: http : //jsfiddle.net/dievardump/xL5mg/4/

I commented some parts of the code and I 'simulate' your getCategory method. 我注释了代码的某些部分,并“模拟”了您的getCategory方法。

Note : From my code, I think what didn't manage to do is the 'pickRandom' method. 注意:从我的代码中,我认为没有成功做的是'pickRandom'方法。 I think you have almost all you need to do other parts. 我认为您几乎需要做其他部分。

What I do in my code : 我在我的代码中做什么:

  • I have a collection of Question and Answers 我有一个问答集
  • I have a QuestionAndAnswer constructor 我有一个QuestionAndAnswer构造函数

When the server result come, I 'parse' the xml file and fill the collection with QuestionAndAnswer objects. 当服务器结果到来时,我将“解析” xml文件,并用QuestionAndAnswer对象填充集合。

In the HTML is a 'load a question' button. HTML中的是“加载问题”按钮。 When you click on it, it call the displayQuestion method. 当您单击它时,它将调用displayQuestion方法。

This method picks (get and remove from) a random QandA object from the collection, then display the question and a button to see the associated answer. 此方法从集合中选择一个随机QandA对象(从中获取和删除),然后显示问题和按钮以查看关联的答案。

Like i said in the comments, i decided to add question the one after the other, but you can change that by having only one question and response handler and modify its content. 就像我在评论中说的那样,我决定一个接一个地添加问题,但是您可以通过只设置一个问题和响应处理程序并修改其内容来更改该问题。

Here is the code if one day jsfiddle decide to not work anymore : 如果有一天jsfiddle决定不再工作,这是以下代码:

Javascript Java脚本

(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 的HTML

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

</div>

CSS 的CSS

    .wrapper {
    width : 500px;      
}

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

.answer {
    display : none;    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM