Append Child Element on reset - JavaScript - javascript

I want to reset the game by appending child element back to '1'. By default in html it is labelled as 1 and on finishing game it gets to empty but when this bonus life is used i want at the end of the game to be reset to '1'.
<h2>PLAYER HEALTH<span id="bonus-life">1</span></h2>
I have used this function in JavaScript but seem to be not working:
function resetBonus() {
bonusLifeEl.parentNode.appendChild(bonusLifeEl);
}
This function is called in a file which is like this:
if (currentMonsterHealth <= 0 || currentPlayerHealth <= 0) {
reset();
resetBonus();
}
Reset function just remove bonus life
function reset() {
currentMonsterHealth = chosenMaxLife;
currentPlayerHealth = chosenMaxLife;
resetGame(chosenMaxLife);
}

Nothing will be changed when you try to add a child to the parent where it is already exists.
You can change the value instead of add/remove child by innerText or innerHTML values.

function resetBonus() {
bonusLifeEl.innerHTML = bonusLifeEl;
}

Related

How to reset button style in Javascript

function showQuestion(questionAndAnswers) {
const shuffledAnswers = _.shuffle(questionAndAnswers.answers);
questionTag.innerText = questionAndAnswers.question;
shuffledAnswers.forEach(({ text, correct }, i) => {
answerTag[i].innerText = text;
answerTag[i].dataset.correct = correct;
});
}
document.querySelectorAll(".answer").forEach((answer) => {
answer.addEventListener("click", (event) => {
if (event.target.dataset ) {
answer.style.border = "1.5px solid"
}
});
});
function nextQuestion() {
const nextIndex = currentQuestionIndex + 1;
if (nextIndex <= myQuestions.length - 1) {
showQuestion(myQuestions[nextIndex]);
currentQuestionIndex = nextIndex;
} else {
end.style.visibility = "visible";
nxt_question_btn.style.visibility = "hidden";
}
}
Basically, In this quiz app, I have 4 buttons for answers and once you click on one answer it makes the border black. The problem I am facing is that once I press the next question, it loads up another question with 4 different answers but one of the buttons will still have the border black. How do I get it to reset once I load up another question? and Extra question if it's okay, how can I only select one button at a time per question?
There is no 'reset' as there is no default, you will just have to manually undo what you did earlier, i.e to remove the border completely:
answer.style.border = "none";
To select each button individually, you will ave to give them each an ID, based of something like an iteration, instead of trying to select them by the shared class
that's a tough one, there is no easy answer without knowing what the previous style was, so it's good to store the previous value of the style in memory and reset the styles to the previous value after the next question has been loaded
// a variable declared somewhere in common scope
let prevBorder
// "backup" the old value when you want to mark the answer as "selected"
prevBorder = element.styles.border
// restore to the initial value when you want to reset the styles
element.styles.border = prevBorder
Maybe you are looking for css:initial property?
The initial CSS keyword applies the initial (or default) value of a property to an element. It can be applied to any CSS property. This includes the CSS shorthand all, with which initial can be used to restore all CSS properties to their initial state.
Or you could add class and use classList.toggle() to switch between them.
I don't have your html code and full code so can't help you fully, but this is an example that may help you implement to your code:
document.querySelectorAll('button').forEach(item => {
item.addEventListener('click', function() {
item.style.border = '10px solid black'
document.querySelectorAll('button').forEach(i => {
if (i != item)
i.style.border = "initial"
})
})
})
<button>Click</button>
<button>Click</button>
<button>Click</button>
<button>Click</button>

JavaScript function to replace HTML contents for a few seconds, then revert back.

I'm making a hangman game using JavaScript and need to hide some HTML for a few seconds to display an error message, and then revert back to the original HTML. I've tried using setTimeout(); and setInterval(); but those seem to just wait a few seconds before displaying the error message.
Here's the code for reference:
<div class="row text-center">
<div id="alredGuess" class="col">
<div>
<span id="guessedLetters"></span> <br>
</div>
<div>Guesses left:<span id="guessesLeft">10</span></div>
<div>Wins:<span id="wins">0</span></div>
<div>Losses:<span id="losses">0</span></div>
</div>
</div>
JS:
if (gameRunning === true && guessedLetterBank.indexOf(letter) === -1) {
// run game logic
guessedLetterBank.push(letter);
// Check if letter is in picked word
for (var i = 0; i < pickedWord.length; i++) {
//convert to lower case
if (pickedWord[i].toLowerCase() === letter.toLowerCase()) {
//if match, swap placeholder
pickedWordPlaceholderArr[i] = pickedWord[i];
}
}
$placeholders.textContent = pickedWordPlaceholderArr.join("");
checkIncorrect(letter);
} else if (gameRunning === false) {
$placeholders.textContent = "Press \"A\" To Begin!"
} else {
//alert("You've already guessed this letter.")
function newAlert() {
var hideDiv = document.getElementById("alredGuess");
if (hideDiv.style.display = "block") {
hideDiv.style.display = "none";
}
}
hideDiv.textContent("You've already guessed this letter!");
function showDiv() {
var showDiv = document.getElementById("alredGuess");
if (hideDiv.style.display = "none") {
hideDiv.style.display = "block";
}
}
}
}
setInterval(newAlert, 3000);
}
Tip 1
Well, first of all i don't recommend using display: block|none to show or hide DOM elements. Instead try using visibility: visible|hidden or better, toggle a css class name such as : .hidden. That's because when you set a DOM element's display to none, its width and height are gonna be set to zero, often causing an unwanted loss of space because the DOM node visually collapses. With the visibility property, for example, the element just disappears without loss of space.
Tip 2
Error/status messages should always live within their own containers. Do not display messages in substitution of some content you need to revert back after.
It is always better to prepare an empty <div>, hide it by default with a generic .hiddenCSS class and then remove this one as soon as you need to display the container.
Suggested solution
Now, in your case, i think you're using setIntervalin the wrong way. You have to immediately show the alert message, then make it disappear after a few seconds.
As suggested above, this should be done by toggling CSS classes, using different containers and using setTimeout in order to remove/add the CSS classes as soon as the interval is over. Basically, the setTimeout restores everything to its original state.
So, given this HTML code:
<div id="alredGuess">This is the original text</div>
<div id="alertbox" class="hidden"></div>
and this CSS code:
.hidden { visibility: hidden; }
try this:
var alertTimeout = 1000; // Timeout in milliseconds.
function showAlertMessage() {
// This is your original text container.
var alredGuess = document.getElementById("alredGuess");
// This is the new error message container named #alertbox
var alertBox = document.getElementById("alertbox");
// Now let's fill it with the specific error text (better using HTML here).
alertBox.innerHTML = "You've already guessed this letter!";
// Hide the original container by adding an .hidden css class.
alredGuess.classList.add('hidden');
// Show the error message container by removing its default .hidden css class.
alertBox.classList.remove('hidden');
// Then set up an interval: as it ends, revert everything to its original state.
setTimeout(function() {
alertBox.classList.add('hidden');
alredGuess.classList.remove('hidden');
}, alertTimeout);
}
// Call the function.
showAlertMessage();
Fiddle: https://jsfiddle.net/qyk4jspd/
Hope this helps.

If value is greater than, less than and becomes greater than again

I'm having a problem with my following logic.
Jsfiddle
The logic
var budgetCalc = function (financeBudget, totalCost, remainingBudget, changeOn) {
var reloadCalc = function () {
var formula = parseFloat($(financeBudget).val()) - parseFloat($(totalCost).val());
$(remainingBudget).val(Math.abs(formula.toFixed(0)));
if ( formula >= 0 ) {
$('.toolbar-budget').addClass('is-positive').append('<p>Remaining</p>');
} else {
$('.toolbar-budget').addClass('is-negative').append('<p>Over Budget</p>');
}
};
$(document).ready(function () {
// Price Input
$(changeOn).change(function () {
reloadCalc();
});
$(changeOn).trigger('change');
});
};
What works fine
The interface has multiple selects, inputs and a jQuery sliders that change the value of formula. The logic works fine when the page loads and the formula value is >= 0. If the value is < 0 than the formula works fine as well.
The Issue
If the value of the formula is < 0 and then becomes > 0 again because the user changes the values contributing to formula, the logic does not change the class back to .is-positive unless the page refreshes.
My goal
I want the class of .is-positive to be applied without the page refreshing if the value goes from < 0 to >= 0.
Seems like the simplest solution would be to remove both classes before adding the appropriate one but adding $('.toolbar-budget').removeClass('is-positive is-negative'); before your check:
$('.toolbar-budget').removeClass('is-positive is-negative');
if (formula >= 0) {
$('.toolbar-budget').addClass('is-positive').append('<p>Remaining</p>');
} else {
$('.toolbar-budget').addClass('is-negative').append('<p>Over Budget</p>');
}
jsFiddle example
You use addClass() and do not clear existing classes, so you end up with both classes set. You should remove previously set classes via removeClass() or toggleClass().
Also, I'd recommend to do the same with .append('<p>Remaining</p>'); part, so you don't just append paragraphs but swich them.

How to bypass function for element with specify class and two conditions with jQuery

It's hard to say in couple wors in title... So i have this code:
var class_main_content = $('.main_content ul').attr('class');
var xml_element_name = $(xml).find(class_main_content)[0].nodeName.toLowerCase();
var no_option = $('.no_option').attr('class');
if ((class_main_content) == xml_element_name){
...
}
else if ($(class_main_content) == (no_option)){
...
}
and i have first condition with some actions - every things fine, next i have second condition which first condition is also performs, but i need to do something for element with class .no_option. The problem grows when this element have two class from first condition and second. How to pass by first condition and do something for second? :)
Rather than getting the class attribute and comparing it against things, why not use the hasClass JQuery function:
var main_content=$('.main_content ul');
if(main_content.hasClass('something')) {
do_something();
}
if(main_content.hasClass('no_option')) {
do_something_else();
}
You can of course do the reverse test:
if(!main_content.hasClass('no_option')) ...

Expand only one row in javascript code

hey guys having trouble figuring out how to make it so that i can make it only open one table at once, once you open another the other should close any help here?
function showRow(cctab){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = '';
}
}
function hideRow(row1){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = 'none';
}
}
function toggleRow(cctab){
if (document.getElementById(cctab)) {
if (document.getElementById(cctab).style.display == 'none') {
showRow(cctab)
} else {
hideRow(cctab)
}
}
}
Now I want to make it so that only one table "cctab" opens after I suggest the onClick="javascript:toggleRow(cctab);" anyhelp?
Well you could save a reference to the previously shown item and hide it when another is shown:
var currentTab;
function showRow(cctab){
if (document.getElementById(cctab))
document.getElementById(cctab).style.display = '';
if (currentTab && currentTab != cctab)
hideRow(currentTab);
currentTab = cctab;
}
Note that doing inline event handler attributes is so 1999, but assuming you're sticking with it for whatever reason you don't need the javascript: in onClick="javascript:toggleRow(cctab);". (Just say onClick="toggleRow(cctab);")
First you need to store the old row somewhere.
What you've got is a system where you're using <element onclick="..."> to pass the id of the current element into the controller that shows or hides the row.
But if you look at that, what you're missing is a way of telling what the last open row was.
So what your code will need is a central object, or variables which store the old element and the new element.
How you do this is up to you, but if you did something like this:
var table_rows = { current : null /* or set a default */, previous : null };
function rowController (cctab) {
var newRow = document.getElementById(cctab);
if (newRow === table_rows.current) { toggleRow(newRow); }
else {
table_rows.previous = table_rows.current;
table_rows.current = newRow;
showRow(table_rows.current);
hideRow(table_rows.previous);
}
}
Note:
This deals with elements directly, so you don't have to do getById in your functions;
that's handled one time, and then that element is passed around and saved and checked against.
It assumes that the click is happening on the row itself, and not on anything inside of the row;
that's a separate issue that your code has.
Unless it's obvious and easy to click on the row, and not the cells inside of the row, it's difficult to tell how you want users to be able to open and close rows.
What I mean is if only the table-row has an onclick, and somebody clicks on a table-column, then then onclick isn't going to fire.

Categories