繁体   English   中英

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

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

我一直在尝试用Ajax构建一个问答软件。 我需要创建特定功能的帮助。 我创建了具有不同问题和答案的XML文件。 基本思想是使用“获取”功能来(1)加载XML问题文件,以及(2)使用“显示”和“ math.random”功能来显示随机的“问题”元素(相应的“答案”元素将同时显示,但被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文件中随机选择问题和答案元素,但仅向用户显示一次的函数。 干杯们。 (对不起,这是如此冗长)。

编写一个具有变种的类,该变种已被显示,已被回答,用户回答,函数getquestion,函数getanswer。

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

这是指向我将如何执行您要执行的操作的示例的链接: http : //jsfiddle.net/dievardump/xL5mg/4/

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

注意:从我的代码中,我认为没有成功做的是'pickRandom'方法。 我认为您几乎需要做其他部分。

我在我的代码中做什么:

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

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

HTML中的是“加载问题”按钮。 当您单击它时,它将调用displayQuestion方法。

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

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

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

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

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

暂无
暂无

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

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