开发者问题收集

Javascript 测验答案值不正确

2021-12-24
156

我正在用 javascript 做一个个人测验,看看你想要什么衣服。大部分都很好用,只是我按下答案时给出的值不正确。

Html:

<div className="container">
    <div id="question"></div>
    <div id="answer"></div>
    <button onClick="NextQuestion()" id="nextbtn">Next</button>
    <button onClick="PrevQuestion()" id="prevbtn" style="display: none;">Previous</button>
    <div id="finalLink"></div>
</div>

JS:

document.getElementById("finalLink").innerHTML +=
        "<a id='FLink' href='https://www.voetbalshop.nl/voetbalschoenen.html#' onClick='location.href=this.href+getLink(url);return false;'>Result</a>";

    class QuizPart {
        constructor(questionDescription, chosenAnswer, prefix) {
            this.questionDescription = questionDescription;
            this.chosenAnswer = chosenAnswer;
            this.prefix = prefix;
        }
    }

    class ChosenAnswer {
        constructor(id, name) {
            this.id = id;
            this.name = name;
        }
    }

    let Quiz = [
        new QuizPart('Whats your size?', [
            new ChosenAnswer('6595', '41'),
            new ChosenAnswer('6598', '42'),
            new ChosenAnswer('6601', '43'),
        ], 'bd_shoe_size_ids='),

        new QuizPart('What color would you like?', [
            new ChosenAnswer('6053', 'Red'),
            new ChosenAnswer('6044', 'Blue'),
            new ChosenAnswer('6056', 'Yellow'),
            new ChosenAnswer('6048', 'Green'),
        ], 'color_ids='),

        new QuizPart('What brand would you like?', [
            new ChosenAnswer('5805', 'Adidas'),
            new ChosenAnswer('5866', 'Nike'),
            new ChosenAnswer('5875', 'Puma'),
        ], 'manufacturer_ids='),
    ]
    // console.log(Quiz);

    let url = [];

    let questionNumber = -1;
    let button = document.getElementById('answer');
    let questionName = document.getElementById('question');
    let nextbtn = document.getElementById('nextbtn');
    let prevbtn = document.getElementById('prevbtn')
    let resultbtn = document.getElementById('FLink');

    function NextQuestion() {
        // adds 1 to question to see a different question
        questionNumber++;

        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
            answerButton.style.display = 'none';
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y++) {
            let item = question.chosenAnswer[y];
            // Display answer buttons
            let btn = document.createElement('button');
            btn.value = item.id;
            btn.className = "filter_anwser";
            btn.textContent = item.name;
            button.appendChild(btn);
        }
        // Check if your at the last question so the next button will stop being displayed.
        if (questionNumber > 0) {
            prevbtn.style.display = 'block';
        } else {
            prevbtn.style.display = 'none';
        }

        if (Quiz.length - 1 <= questionNumber) {
            nextbtn.style.display = 'none';
            resultbtn.style.display = 'grid';
        } else {
            nextbtn.style.display = 'block';
            resultbtn.style.display = 'none';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";
    }

    function PrevQuestion() {
        questionNumber--;
        let oldAnswerButton = document.querySelectorAll('.filter_anwser');

        // Deletes old question when the next question is clicked
        for (let answerButton of oldAnswerButton) {
            answerButton.style.display = 'none';
        }

        let question = Quiz[questionNumber];

        // Displays answers of the questions
        for (let y = 0; y < question.chosenAnswer.length; y++) {
            let item = question.chosenAnswer[y];
            // Display answer buttons

            let btn = document.querySelector('button[value="' + item.id + '"]');
            btn.style.display = 'block';
        }
        //Check if your at the last question so the next button will stop being displayed.
        if (questionNumber < Quiz.length - 1) {
            nextbtn.style.display = 'block';
        }
        if (questionNumber <= 0) {
            prevbtn.style.display = 'none';
        } else {
            prevbtn.style.display = 'block';
        }

        if (Quiz.length - 1 <= questionNumber) {
            resultbtn.style.display = 'grid';
        } else {
            resultbtn.style.display = 'none';
        }

        // Displays Question
        questionName.textContent = question.questionDescription;
        questionName.id = "questionID";
    }

    /**
     * Returns the paremeters for the URL.
     *
     * @param {Array} url The parameters .... .
     */
    function getLink(url) {
        let tmp = [];
        for (let i = 0; i < url.length; i++) {
            // Check if question is from the same quiz part and adds a , between chosen answers and add the right prefix at the beginning
            if (url[i].length > 0) {
                tmp.push("" + Quiz[i].prefix + url[i].join(","))
            }
        }
        /// If answers are from different quiz parts add a & between answers.
        console.log(url, questionNumber);
        return "" + tmp.join("&");
    };

    button.addEventListener("click", function (e) {
        const tgt = e.target;

        // clear the url array if there's nothing clicked
        if (url.length < questionNumber) {
            url.push([]);
        }

        let quizUrl = url[questionNumber - 1];

        // Check if a button is clicked. Changes color and adds value to the url array.
        if (quizUrl.indexOf(tgt.value) === -1) {
            quizUrl.push(tgt.value);
            e.target.style.backgroundColor = "orange";
            // Check if a button is clicked again. If clicked again changes color back and deletes value in the url array.
        } else {
            quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
            e.target.style.backgroundColor = "white";
        }
        console.log(getLink(url));
    })

当我打开我的网站时,它显示开始,当我开始测验时,我会看到我的第一个问题及其下面的所有答案,但是当我点击第一个问题的答案时,我收到一个错误,对于第二个问题,它显示了正确的值,但在第一个问题的前缀中等等。它基本上总是将值设置为上一个问题。

为了更清楚起见,您给出的所有答案都收集在一个变量(url)中。 最后它看起来像这样:

bd_shoe_size_ids=6732,4765&color_ids=3846,4635&manufacturer_ids=4563,3456

变量中的文本是问题,id 是您单击的答案。当我单击属于 manufacturers_ids 的答案时,它会将答案设置为 color_ids,而当单击属于 color 的答案时,它会设置为鞋子尺码。

有人能帮我吗?

第一个问题给出的错误如下:

(index):188 Uncaught TypeError: Cannot read properties of undefined (reading 'indexOf') at HTMLDivElement. ((index):188)

2个回答

要清除数组,请将其设置为 [] 或调用 splice。

不正确

if (url.length < questionNumber) {
   url.push([]);
}

正确

url = []
// or
url.splice(0, url.length)

然后是这个

let quizUrl = url[questionNumber - 1];

如果清除它而不返回,则会引发错误。

在此行之前放置一个日志语句。

console.log(url)
let quizUrl = url[questionNumber - 1];

因为这一行可能是罪魁祸首。

quizUrl.indexOf(quizUrl)

事实上,除了推送一个空数组之外,我甚至没有看到您在 url 数组中添加任何内容。

Steven Spungin
2021-12-24

我很惊讶没人发现这个显而易见的问题。您有:

let questionNumber = -1;
//...
function NextQuestion() {
    questionNumber++;
    //...
}
function PreviousQuestion() {
    questionNumber--;
    //...
}

所以您的 questionNumber 是从 0 开始的(第一个问题为 0,第二个为 1,等等)。

您获取当前 quizUrl 的方式是错误的:

let quizUrl = url[questionNumber - 1];

对于第一个问题( questionNumber=0 ),您得到的 url[-1] 是未定义的,因此您犯了错误。

您应该使用:

let quizUrl = url[questionNumber];

您可以使用调试器轻松调试此类错误。 (例如,如果您使用 Chrome,请参阅 https://developer.chrome.com/docs/devtools/javascript/

Pierre
2021-12-28