1. 程式人生 > >React.js學習 隨機出題模組

React.js學習 隨機出題模組

React.js小專案——隨機出題模組

功能簡介

如下圖,在網頁上出一張試卷,該試卷由簡單題、一般題、難題按比例組成,並且每題是從對應題庫中隨機抽取,且答對的題目不會再出現。

效果圖gif

實現思路:

  • 確定模組:開始按鈕、試卷元件、題目元件、提交按鈕

  • 確定模組結構: 開始按鈕 (呼叫) 試卷元件 (呼叫) 題目元件
                    試卷元件 (呼叫) 提交按鈕 (呼叫) 開始按鈕

具體流程:

1. 首先是建立三個用於測試的題庫,新建三個js檔案,在其中宣告二維陣列,分別用於存放不同難度的題目(easyQuestions, simpleQuestions, hardQuestions),如圖為簡單題的題庫:

let easyQuestions = [
    [ 'easyQuestion1',                      //問題
        'A',                                //選項
        'B',
        'C',
        'D',
        'A' ],                              //答案
    [ 'easyQuestion2',
        'A',
        'B',
        'C',
        'D',
        'A' ],
    [ 'easyQuestion3'
, 'A', 'B', 'C', 'D', 'A' ], [ 'easyQuestion4', 'A', 'B', 'C', 'D', 'A' ], [ 'easyQuestion5', 'A', 'B', 'C', 'D', 'A' ] ];

2.將題庫引入,接下來的問題就是如何做到隨機出題。在此我新建了一個專門用於生成隨機數陣列的函式,並且生成的隨機數陣列長度不超過題庫中題目的數量,根據隨機數陣列中的數字來索引題庫中的題目,思路如圖:
隨機出題實現思路


程式碼如下:

    /*
       函式功能:生成隨機數陣列,通過該隨機數陣列來獲取題庫中題目
    */
    function setRandomArr(arrIndex) {
        let originalArr = [];
        for (let i = 0; i < arrIndex.length; ++i){
            originalArr[i] = i;
        }
        originalArr.sort(function() {
            return 0.5 - Math.random();
        });
        return originalArr;
    }

    //生成對應不同難度題庫的隨機數陣列
    let randomNumbersOfEasyQuestions = setRandomArr(easyQuestions);
    let randomNumbersOfSimpleQuestions = setRandomArr(simpleQuestions);
    let randomNumbersOfHardQuestions = setRandomArr(hardQuestions);

3.生成題目元件,將題目按照格式展示到網頁上,此處的題目元件只是做出了樣式,並沒有繫結展示的題目,展示的題目在生成試卷模組時決定,程式碼如下:

class Question extends React.Component {
        constructor(props){
            super(props);
        }
        render() {
            return (
                <div className="questions" id = {this.props.id}>
                    <p>({this.props.order}){this.props.questionsType}</p>
                    <form action="">
                        <div className = "option">
                            <input type="radio" name={this.props.name} value="A"/> A
                        </div>
                        <div className = "option">
                            <input type="radio" name={this.props.name} value="B"/> B
                        </div>
                        <div className = "option">
                            <input type="radio" name={this.props.name} value="C"/> C
                        </div>
                        <div className = "option">
                            <input type="radio" name={this.props.name} value="D"/> D
                        </div>
                    </form>
                </div>
            );
        }
    }
    Question.propTypes = {
        id : React.PropTypes.number.isRequired,     //為每一個題目設定一個id
        order: React.PropTypes.number.isRequired,  //設定每個題目的序號
        questionsType : React.PropTypes.string.isRequired, //設定題目型別,簡單題/中等題/難題
        name : React.PropTypes.string.isRequired    //將每題的選項繫結一個name,防止題目選項勾選出問題
    };

4.生成試卷模組,這一個模組的功能比較多,主要有:
(1)對應著隨機陣列中的隨機數序列索引題庫中的題目,實現隨機出題
(2)呼叫上面的Question元件,將索引出的題目按照格式展現在網頁上
(3)生成提交按鈕元件
(4)點選提交按鈕後,將提交的答案與正確答案比較
(5)比較完畢後,將每題的正誤情況返回,展示在網頁上,並呼叫開始測試按鈕,方便使用者進行下一輪測試
(6)在使用者正確答題的情況下,將該題在隨機數陣列中的對應的隨機數索引刪除,保證該題下次不再出現
程式碼如下:

//設定簡單題的數量
const easyQuestionsLength = 2;  
//設定中等題的數量  
const simpleQuestionsLength = 1;
//設定難題的數量   
const hardQuestionsLength = 1;  
//三組題目需要一個共同的計數單位   
let nCount = 0;     
//暫且設定正確答案為A,若想對應到每題具體的答案,可以在submitAnswers()中將其改變成對應題目陣列中的答案                
let correctAnswer = "A";            
class Paper extends React.Component {
    constructor(props){
        super(props);
        this.initialPaper = this.initialPaper.bind(this);
    }
    initialPaper(questionArr, length, questionType, randomNumbersOfQuestionType) {
        for (let i = 0; i < length; ++i) {
           questionArr.push(
               <Question
                       id = {nCount}
                       order = {nCount + 1}
                       questionsType = {questionType[randomNumbersOfQuestionType[i]][0]}
                       name = {"question" + nCount}
                       key = {nCount}
               />);
           ++nCount;
        }
    }
    submitAnswers() {
        nCount = 0; //提交答案的時候將nCount清零,用於下一次生成試卷時計數
        let questionLength = (easyQuestionsLength + simpleQuestionsLength + hardQuestionsLength);
        let answers = [];  //用於儲存使用者選擇的答案
        let resultsArr = [];//用於儲存使用者選擇的答案的正誤
        //向answers陣列中push已經被選中的答案
        for (let i = 0; i < questionLength; ++i) {
            let options = document.getElementsByName("question" + i);
            for (let j = 0; j < options.length; ++j) {
                if (options[j].checked) {
                    answers.push(options[j].value);
                    break;
                }
            }
        }
        //將answers陣列中的答案與正確答案比較,向resultsArr中push最終結果
        let easyCount, simpleCount, hardCount = 0;
        for (let i = 0; i < questionLength; ++i) {
            if (answers[i] == correctAnswer) {
                resultsArr.push(<p key={i} className="results">第{i+1}題:正確</p>);
                //答題正確則刪除相應題庫隨機陣列中的序號,保證下次出題不再出現
                if (i < easyQuestionsLength) {
                    randomNumbersOfEasyQuestions.splice(i - easyCount, 1);
                    ++easyCount;
                }
                else if(easyQuestionsLength <= i && i < (easyQuestionsLength + simpleQuestionsLength)) {
                    randomNumbersOfSimpleQuestions.splice(i - simpleCount - easyQuestionsLength, 1);
                    ++simpleCount;
                }
                else {
                    randomNumbersOfHardQuestions.splice(i - hardCount - easyQuestionsLength - simpleQuestionsLength, 1);
                    ++hardCount;
                }
            }else {
                resultsArr.push(<p key={i} className="results">第{i+1}題:錯誤</p>);
            }
        }
        //將答案渲染到網頁上
        ReactDOM.render(
            <div>
                {resultsArr}
                <StartButton/>
            </div>,
            document.getElementById("container")
        );
    }
    render() {
        let questionArr = [];
        this.initialPaper(questionArr, easyQuestionsLength, easyQuestions, randomNumbersOfEasyQuestions);
        this.initialPaper(questionArr, simpleQuestionsLength, simpleQuestions, randomNumbersOfSimpleQuestions);
        this.initialPaper(questionArr, hardQuestionsLength, hardQuestions, randomNumbersOfHardQuestions);
        return (
            <div>
                {questionArr}
                <button id = "submitButton" onClick = {this.submitAnswers}>提交答案</button>
            </div>
        );
    }
}

5.生成開始按鈕元件,現在主體模組以及完成,接下來就是生成一個開始按鈕元件呼叫試卷元件就行啦,程式碼如下:

class StartButton extends React.Component {
        constructor(props){
            super(props);
            this.showPaper = this.showPaper.bind(this);
        }
        showPaper() {
            ReactDOM.render(
                <Paper/>,
                document.getElementById("container")
            );
        }
        render() {
            return(
                    <button id = "startButton" onClick = {this.showPaper}>開始測試</button>
            );
        }
    }

6.渲染入口,將開始測試按鈕渲染到頁面上,程式碼如下:

ReactDOM.render(
        <StartButton/>,
        document.getElementById("container")
    );

相關推薦

React.js學習 隨機出題模組

React.js小專案——隨機出題模組 功能簡介: 如下圖,在網頁上出一張試卷,該試卷由簡單題、一般題、難題按比例組成,並且每題是從對應題庫中隨機抽取,且答對的題目不會再出現。 實現思路: 確定模組:開始按鈕、試卷元件、題目元件、提交按鈕 確定

React.js學習知識小結(一)

知識 學習 瀏覽器兼容 防止 阻止 渲染 開頭 鼠標事件 幫我 學習React也有半個月了吧,這裏對所學的基礎知識做個簡單的總結。自己先是跟著官方文檔學,差不多學了四五天,也跟著入門教程做了一個簡單的小栗子。然後跟著阮一峰老師的教程上手了幾個小Demo,後來在網上發現了一本

React.js學習之codecademyJSX測試

1.Question:What's a difference between a DOM object and a virtual DOM object?     Answer:A virtual DOM object can update much faster than

React.js學習筆記(二)構造渲染

//構造 constructor(...args) {                 //必須先呼叫父類構造                 super(...args);                 //狀態引數                 this.s

Node.js學習之內建模組fs

IDE為VSCode .js內建的fs模組就是檔案系統模組,負責讀寫檔案 'use strict' var fs = require('fs'); //非同步讀取檔案(文字)編碼格式指定為ut

Node.js學習(9)----核心模組

核心模組是 Node.js 的心臟,它由一些精簡而高效的庫組成,為 Node.js 提供了基本的API。主要內容包括:  全域性物件;  常用工具;  事件機制;  檔案系統訪問;  HTT

React.js學習筆記(一)生命週期

componentWillMount(){         console.log( “建立之前”) } componentDidMount(){          console.log( “建立之後”) } componentWillUpdate(){

Node.js學習之內建模組http

'use strict' //導包 var http = require('http'); var url = require('url') var path = require('path')

Node.js學習筆記--fs模組

1. fs.readFile(path,callback(err,data)):讀取檔案有兩個引數,第一個是檔案的完整路徑,當前目錄寫./(必須要寫,為了相容Windows系統和Linux系統),第二個引數是回撥函式,表示檔案讀取完成之後做的事情//可以證明事件環機制 var

React JSReact-Native學習指南

cno example part div roman javascrip add pull tree 自己在學習React-Native過程中整理的一份學習指南,包含 教程、開源app和資源網站等,還在不斷更新中。歡迎pull requests! React-Native學

ReactiveX 學習筆記(26)使用 RxJS + React.js 呼叫 REST API

JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一個用於測試的 REST API 網站。 以下使用 RxJS6 + React.js 呼叫該網站的 REST API,獲取字串以及 JSON 資料。

node.js學習筆記——模組與包

1.模組 1.1 模組概述 在node中,一個檔案就是一個模組,每個模組都有自己的作用域。 Node中模組分為兩類:一類是Node提供的模組,稱為核心模組;另一類是使用者編寫的模組,稱為檔案模組。 核心模組在node原始碼的編譯過程中就編譯進了二進位制執行檔案

React Native 學習筆記十三(原生模組之Toast)

 在學習官網上的Toast 的過程中 出現很多的坑  廢話就不說了 官網上都有 官網講解 實現思路 : 我們之前已經將react-native 嵌入原生了 那麼 我們就在之前的基礎上進行修改就好了    建立ToastUtils.java 繼承ReactContextBas

node.js學習筆記(10)--mysql模組連線mysql資料庫

1.安裝 我們需要一個mysql 和node環境,這裡我自己的電腦沒有安裝mysql,用navicat連的同事的。 注意如果碰到這個 “Host''xxx.xx.xxx.xxx''isnot allowedtoconnectto this MySQL server"

node.js學習筆記(8)--multer模組檔案上傳

1.簡介 multer是一個node.js檔案上傳中介軟體,它是在 busboy的基礎上開發的! multer必須指定 enctype="multipart/form-data". 2.安裝 npm

react專案實戰(許可權模組開發八)js檔案分開打包

才開發幾個介面就發現打包出的index.js檔案就有700多kb了,由於部分外掛的js檔案是不會變化的,單獨打包可以充分利用瀏覽器的快取功能。 第一步:在專案跟目錄下面新增一個webpack.config.js檔案 第二步:為了將原有的js分開打,需要修

node.js學習筆記(5)——excel-export模組匯出excel表

一、excel-export模組 生成的表格為xlsx格式,支援多個sheet。本文只介紹一個sheet表的生成。 二、例項 1. 在package.json中引入excel-export模組,使用npm install 命令安裝 2. 在js檔案中寫入var n

react專案學習心得--後臺管理模組前端實踐總結(antd)

最近在用react做一個專案中的一個小模組,差不多半個月第一個版本上線雖然還是存在不少問題,後面再慢慢優化。先寫篇文章總結一下近期自己的心得。剛開始接觸react時覺得它和傳統的bootstrap jquery這些框架實現方式很不一樣,react中頁面程式碼幾乎都是js檔案,

結合基礎與實戰學習React.js 獨立開發新聞頭條平臺

href 表達式 nodejs ebp 登錄 以及 網盤下載 更新 五個 第1章 課程簡介課程導讀,介紹了課程的基本結構、課程的特點、最終實戰項目演示、前置知識點以及源碼打包結構和後期相關學習資料的更新方式。第2章 React 簡介對 React 進行了詳細地簡介並對課程的

React-Native_學習筆記1: Unable to resolve module Dimensions from “...js” Invalid directory /Users/node_m

在使用第三方的元件的時候遇到如題的錯誤提示,原因是第三方組建中呼叫Dimensions 發生的錯誤,解決方法:修改第三方元件 “。js”檔案中的程式碼 var screen = require('D