简体   繁体   中英

How to repeat a function with OOP JavaScript

I am attempting to create a basic flash card game, where you fill in a question and an answer and after you click the save button the flash card is created, by clicking on the show hide anchor link the answer should disappear, my issue is that only the first card allows the method to work. Can anyone please explain how can this be fixed so I can repeat this in a OOP way, I understand this code may need to be rewritten, any advice/example with this code would be helpful. Thanks!

 const card = document.querySelector('.card'); const addCardBtn = document.querySelector('.add'); const closeCardBtn = document.querySelector('.close'); const saveCardBtn = document.querySelector('.save'); const questionInput = document.querySelector('#question-input'); const answerInput = document.querySelector('#answer-input'); // add card let addCard = addCardBtn.addEventListener('click', function(e) { card.style.display = 'block' }) // close card let closeCard = closeCardBtn.addEventListener('click', function(e) { card.style.display = 'none' }) // create flash card let saveFlashCard = saveCardBtn.addEventListener('click', function(e) { e.preventDefault() if (questionInput.value === '' || answerInput.value === '') { alert('empty fields, please fill both parts') } else { const flashCard = document.createElement('flash') flashCard.innerHTML = `<div class="flash"> <p class="flash-question">${questionInput.value}</p> <a class="show">Show / Hide Answer</a> <div class ="flash-answer"> <p>${answerInput.value}</p> </div> <button class="btn edit">Edit</button> <button class="btn delete">Delete</button> </div>` document.querySelector('.cards').appendChild(flashCard); questionInput.value = '' answerInput.value = '' document.querySelector('.show').addEventListener('click', function(e) { document.querySelector('.flash-answer').classList.toggle('hide') }) } }) function Play() { this.addCard = addCard this.closeCard = closeCard this.saveFlashCard = saveFlashCard } const game = new Play();
 * { box-sizing: border-box; margin: 0; padding: 0; } * { box-sizing: border-box; } body { font-family: 'Open Sans'; } .head { margin-top: 20px; margin-left: 100px; } .card { display: none; margin-left: 100px; width: 760px; border-style: solid; border-color: coral; } textarea ,h3{ margin-top: 10px; margin-left: 20px; } .btn { padding: 10px 10px; margin-top: .5rem!important; margin-bottom: .5rem!important; text-transform: capitalize!important; background: transparent; border-radius: 5px; border-color: rgb(154, 45, 0); color: rgb(255, 134, 83); background-image: initial; background-color: transparent; cursor: pointer; } .close { margin: 0px 0px 0px 700px; } .save { margin: 0px 20px; } .add { margin: 0px 20px; } .flash { text-align: center; padding: 10px 10px; width:fit-content ; border-style: solid; border-color: coral; margin: 30px 100px; } .hide { display: none; } /* .flash p { margin: 3px 0px; } */ button.btn.edit{ margin-left: 5px; color: rgb(62, 212, 231); } button.btn.delete{ margin-left: 5px; color: rgb(231, 192, 62); } /**** media queries *****/ /* Media Query for Mobile Devices */ @media (max-width: 480px) { .card{ box-sizing: border-box; width: 480px; margin-left: 20px; } .head { margin-left: 20px; } textarea { width: 420px; } .flash { margin-left: 20px; } .close { margin: 0px 20px; } } /* Media Query for low resolution Tablets, Ipads */ @media (min-width: 481px) and (max-width: 767px) { } /* Media Query for Tablets Ipads portrait mode */ @media (min-width: 768px) and (max-width: 1024px){ } /* Media Query for Laptops and Desktops */ @media (min-width: 1025px) and (max-width: 1280px){ } /* Media Query for Large screens */ @media (min-width: 1281px) { }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <!-- CSS --> <link rel="stylesheet" href="./style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="head"> <h2>Flashcards</h2> </div> <button class="btn add">Add Question</button> </div> <div class="card"> <div class="main"> <button class="btn close"><i class="fa fa-window-close"></i></button> <h3>Question</h3> <textarea name="" id="question-input" cols="100" rows="10"></textarea> <h3>Answer</h3> <textarea name="" id="answer-input" cols="100" rows="10"></textarea> <button class="btn save">Save</button> </div> </div> <div class="cards"> </div> <!-- JS --> <script src="./app.js"></script> </body> </html>

You need to bind the click events, after attaching <flash/> to DOM.

This can be done after this line:

document.querySelector('.cards').appendChild(flashCard);  

Likely the events need to be unbound before binding them, in order to avoid multiple bindings (unless binding single items by their id attribute). Also, better use let instead const (in order to assign something else later).

Aight my solution to this is like following js:

// top level add a counter to keep track of id's
let id_counter = 0;

//update where you add the flashcard
//... your code before
const flashCard = document.createElement("flash");
flashCard.innerHTML = `<div id="flash-${_id_counter}" class="flash">
        <p class="flash-question">${questionInput.value}</p>
        <a id="show${_id_counter}" data-id="${_id_counter}" class="show">Show / Hide Answer</a>
        <div id="answer${_id_counter}" class="flash-answer">
        <p>${answerInput.value}</p>
        </div>
        <button class="btn edit">Edit</button>
        <button class="btn delete">Delete</button>
        </div>`;
document.querySelector(".cards").appendChild(flashCard);
questionInput.value = "";
answerInput.value = "";
let show = document.querySelector(`#show${_id_counter}`);
show.addEventListener("click", function (e) {
    document.querySelector(`#answer${e.target.dataset.id}`).classList.toggle("hide");
});
_id_counter++;
//... your code after

After this block, it should work individually. I didn't change too much on code but there are lot's of stuff you can do :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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