How do I make the text appear and disappear again - javascript

I want the text appears when I click the button then disappear again when I click the same button again by javascript:
const firstclick = document.querySelector('.btn-story');
const hidecontenttwo = document.querySelector('.hide-content-two');
function revealcontentTwo(){
if(firstclick.classList.contains('hidecontenttwo')){
hidecontenttwo.style.display='none';
}
else{
hidecontenttwo.style.display='block';
}
}
firstclick.addEventListener("click",revealcontentTwo);

You can use classList & toggle methods:
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
const btn = document.querySelector('#btn-story');
function toggleShowContent(){
const content = document.querySelector('#content');
content.classList.toggle('hide')
}
btn.addEventListener("click", toggleShowContent);
.hide {
display: none;
}
<button id="btn-story">Toggle</button>
<p id="content" class="hide">Content</p>

Related

I am unable to apply color styles for html elements generated via createElement in javascript

Issue is: after hitting the button on the HTML page, the html <h5> tag text changes on the page but the <h5> tag text color wont change to blue (expected behavior as CSS style doesn't reload after clicking the button).
What could be a possible workaround for solving this issue?
const btn = document.querySelector(".test");
btn.addEventListener("click", () => {
a1 = document.createElement('h5');
a1.className = "first";
a1.textContent = 'Blue updated.';
document.getElementById('position').innerHTML = a1.innerText;
//newtext = document.createTextNode('abc');
});
.test {
color: blue;
}
.first {
color: blue;
}
<h5 id="position">Text Color to be replaced to blue after hitting Blue button(but not happening)</h5>
<button class="test">Change to blue</button>
Above, after the button is clicked and the action listener is triggered, the HTML <h5> tag elements code are created with a1 = document.createElement('h5'); a1.className = "first"
The new text is displayed but the color didn't change (to blue).
You're inserting only the textContent instead of appending the entire new H5 element
const btn = document.querySelector(".test");
const pos = document.querySelector('#position');
btn.addEventListener("click", () => {
const h5 = document.createElement('h5');
h5.className = "first";
h5.textContent = 'Blue updated.';
pos.innerHTML = ""; // Empty
pos.append(h5); // Append!
});
.test, .first { color: blue; }
<h5 id="position">Text Color to be replaced to blue after hitting Blue button(but not happening)</h5>
<button class="test">Change to blue</button>
PS: You can also create some nifty reusable functions to handle the DOM querying and creation of elements, using a friendly syntax:
// DOM utility functions:
const el = (sel, par) => (par || document).querySelector(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Example:
const elPos = el('#position');
el(".test").addEventListener("click", () => {
const elH5 = elNew('H5', {
textContent: "Blue updated",
className: "first",
});
elPos.innerHTML = ""; // Empty
elPos.append(elH5); // Append!
});
.test, .first { color: blue; }
<h5 id="position">Text Color to be replaced to blue after hitting Blue button(but not happening)</h5>
<button class="test">Change to blue</button>

How to reset a button after a few seconds?

I have been trying to create a button that shows the text "copy to clipboard" initially, after clicking the text is copied to the clipboard and the button changes the innerHTMl text to "Copied!" and the button background changes to green.
now, the button should reset to the text "copy to clipboard" and color also.
function copyText() {
navigator.clipboard.writeText("//text to be copied//");
var elem = document.getElementById("button").style.backgroundColor = 'green';
var elem = document.getElementById("button").innerHTML = "Copied!";
}
<div class="adress-right">
<button class="button" onclick="copyText()" id="button"><img src="images/clipboard.svg"> Copy to Clipboard</button>
</div>
You can create a delay async function with setTimeout, add a class instead of set the properties in js side and clean your unnecessary code like this:
const btn = document.getElementById('button');
const delay = (s) =>
new Promise((resolve) => setTimeout(resolve, s * 1000));
btn.addEventListener('click', async() => {
navigator.clipboard.writeText('//text to be copied//');
btn.className = 'copied';
btn.innerText = 'Copied';
await delay(2);
btn.classList.remove('copied');
btn.innerText = 'Copy to Clipboard';
});
.copied {
background-color: green;
color: white;
}
<div class="adress-right">
<button class="button" id="button">Copy to Clipboard</button>
</div>
you can add a timeout inside your function on the bottom like this:
setTimeout(function() {
document.getElementById("button").style.backgroundColor = 'white';
document.getElementById("button").innerHTML = "Copy to Clipboard!";
}, 3000);
In react or other frameworks/libraries will be easier, but for a while you can use an If statement.
function copyText()
{
navigator.clipboard.writeText
("//text to be copied//");
if(document.getElementById("button").text != 'Copied'){
var elem = document.getElementById("button").style.backgroundColor='green';
var elem = document.getElementById("button").innerHTML = "Copied!";
}
}
There is a few things to do.
set a timer
reset background-color
insert again the img and the text aside
You can do it this way:
function copyText() {
navigator.clipboard.writeText("//text to be copied//");
var elem = (document.getElementById("button").style.backgroundColor = "green");
var elem = (document.getElementById("button").innerHTML = "Copied!");
// give it a delay before the content of button is updated
setTimeout(() => {//timer
var button = document.getElementById("button");// fetch the button
button.textContent = "";//erase the text
button.style.backgroundColor = "revert";//reset background-color
button.insertAdjacentHTML(// insert you img and text
"beforeend",
'<img src="images/clipboard.svg"> Copy to Clipboard'
);
}, "1000");//duration in ms secondes before the function is fired 1000 is equal to 1second
}
<div class="adress-right">
<button class="button" onclick="copyText()" id="button"><img src="images/clipboard.svg"> Copy to Clipboard</button>
</div>
ressources
https://developer.mozilla.org/en-US/docs/Web/API/setTimeout
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
https://developer.mozilla.org/en-US/docs/Web/CSS/revert

Display button value in div onclick. Javascript/HTML

I have a set of buttons with different values. When I press a button I want the value of the button to be displayed in the div picked_letters, but nothing is showing. The code is divided in an html file and a javascript file.
html file looks like this:
<body>
<script src="cases.js"></script>
<div id="written_word">
</div>
<div id="list_of_letters">
</div>
<div id="picked_letters">
</div>
</body>
and the onclick in the javascript file looks like this:
for(let i = 0; i < 26; i++) {
let btn = document.createElement("button");
btn.style.background = 'silver';
btn.style.width = '15%';
btn.style.fontWeight = 'bold';
btn.style.fontSize = '135%';
btn.style.display = 'inline-block';
btn.value = case_values[i];
btn.onmouseover = function (){
btn.style.background = 'goldenrod';
}
btn.onmouseleave = function() {
btn.style.background = 'silver';
}
btn.onclick = function() {
btn.style.background = 'darkgrey';
btn.disabled = true;
btn.innerHTML = String(btn.value);
document.getElementById("picked_letters").innerHTML =
String(btn.value);
}
btn.innerHTML = String(i+1);
document.body.appendChild(btn);
}
The button changes color, becomes disabled and displays the value inside the button but it's the last line with getting the button value into a div that I am having problems with. Have looked around but haven't found a solution that solves this problem.
##Edit: The problem seems to have been fixed when I put the script import at the end of the body (and some other minor changes).
Where are you setting the value of the button?
Can you share the button code?
Does your button look like this?
<button>My Button</button>
or do you set your value like this?
<button value="my button value">My button</button>
If you have a value set - you can do this:
btn.onclick = function () {
console.log(btn.innerHTML);
btn.style.background = "darkgrey";
btn.disabled = true;
document.getElementById("picked_letters").innerHTML = btn.value;
};
If you don't have a value set - using btn.value won't return anything.
I would try adding a value to your button if you dont have one. Or if you want to call the innerhtml of the button:
<button>My button</button>
and then
btn.onclick = function () {
console.log(btn.innerHTML);
btn.style.background = "darkgrey";
btn.disabled = true;
document.getElementById("picked_letters").innerHTML = btn.innerHTML;
};
The code above is perfectly fine, the is definately being displayed in the "picked_letters" div, but the value of btn is ""(empty) so the value set to the div is also empty. To solve this issue, add value to the button by doing:-
. and the issue will be gone.
const btn = document.querySelector('#btn')
btn.onclick = function() {
btn.style.background = 'darkgrey';
btn.disabled = true;
console.log(btn.value)
btn.innerHTML = String(btn.value);
document.getElementById("picked_letters").innerHTML =
String(btn.value);
}
<body>
<div id="written_word">
</div>
<div id="list_of_letters">
</div>
<div id="picked_letters">
</div>
<button id='btn' value='5'>Tap me</button>
</body>

How to color one of a 100 boxes with a button in a modal using javascript

Just to make it easier Im explaining what I wish to do in a simplified example.
I have 100 boxes on my site using simple html/css. (styling not shown)
I have written a bit of JS to open a modal that opens when clicking on one of the 100 boxes carrying the same class: class="boxes":
The modal has an Id of "modal":
var modal = document.getElementById("modal");
var boxes = document.getElementsByClassName("box");
var boxesLength = boxes.length;
When any box is clicked the modal appears:
for (var i = 0; i < boxesLength; i++) {
boxes[i].onclick = function () {
modal.style.display = "block";
};
}
Now I wish to color the box that was clicked using a button in the modal that was opened. The code that doesn't work but is my closest guess looks like this:
//get the coloring button in the modal which has Id of "green".
var coloring = document.getElementById("green");
coloring.onclick = function () {
boxes[i].style.backgroundColor = "#90EE90";
//closing the modal after clicking which works
modal.style.display = "none";
};
Writing "boxes[0]" will color the first box, but that is of course not what I wish. I wish to color the box that was clicked.
Thank you for any input. Good day!
on request ive added som simple html
//The modal
<div id="modal">
<button id="green">Completed</button>
</div>
//just some boxes
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
<div class="boxes"></div>
.... 96 more boxes
In accordance to how I understood your issue.You want the background color to show on the box that was clicked for it to show the modal.
Here is my solution.
//to pass it as a global variable between functions
var randomv = {}
var modal = document.getElementById("modal");
var close = document.querySelector('.close')
//get all box
var x = document.getElementById("innerBox").querySelectorAll(".box");
//for each box execute the following
x.forEach(box => {
//on clicking each box, execute a function
box.addEventListener("click", function () {
//this references the parent element which in this case is the box
randomv.parent = this
//display the modal on clicking the box
modal.style.display = "block";
})
});
//hide the modal on clicking the x
close.addEventListener("click", function(){
modal.style.display = "none"
});
function changeColor() {
//first ensure the background color is normal for each box
x.forEach(box => {
box.style.backgroundColor = "white";
});
//reserve the parent element to a variable
var parent_div = randomv.parent
//change the parent's bg color
parent_div.style.backgroundColor = "green";
}
</script>
#modal {
display: none;
}
#innerBox {
width: 100vw;
display: flex;
}
.box{
flex-grow: 1;
}
.close,.box{
cursor: pointer;
}
<div class="container">
<div id="modal">model content
<div class="close"> x </div>
<button onclick="changeColor()">green</button>
</div>
<div id="innerBox">
<div class="box 1">box1</div>
<div class="box 2">box2</div>
<div class="box 3">box3</div>
<div class="box 4">box4</div>
</div>
</div>
I believe your issue is here. You have: for (var i = 0; i < btnsLength; i++) {, but should be referring to boxesLength so for (var i = 0; i < boxesLength; i++.
This would be an ideal application for 'event delegation'. Read more here: https://javascript.info/event-delegation.
Essentially you put the click handler on the parent container for all of your boxes and then use target to point to the clicked box. That gives you 1 event handler instead of 100.
I figured it out using "this":
for (var i = 0; i < boxesLength; i++) {
boxes[i].onclick = function () {
modal.style.display = "block";
var koko = this;
green.onclick = function () {
koko.style.backgroundColor = "#90EE90";
modal.style.display = "none";
};
};

Event target and rest operator with nodelist

I have four buttons, each of these is different than others.
What I want:
When I click on the button I want to add to this button a class named 'togglemath' and exactly in the same time I want to remove class from the three left buttons ( of course if the buttons has a classname 'togglemath')
I know that the code below is bad, but I put this here to understand what I mean.
const sumButton = document.getElementById('add');
const substractButton = document.getElementById('subtract');
const multipleButton = document.getElementById('multiple');
const divideButton = document.getElementById('divide');
const mathButtons = [sumButton, substractButton, multipleButton, divideButton];
const activeClass = () => {
mathButtons.forEach(el => {
el.addEventListener('click', e => {
[e.target, ...rest] = mathButtons;
e.target.classList.add('togglemath');
rest.classList.remove('togglemath');
});
});
};
activeClass();
Lets make for example 3 buttons:
<button class="toggle">1</button>
<button class="toggle">2</button>
<button class="toggle">3</button>
<button class="toggle">4</button>
As far as I understand you need to remove class togglemath from all the buttons except the one that you clicked on. Then we can do something like this:
const TOGGLE_CLASS_NAME = 'togglemath';
const $buttons = document.getElementsByClassName('toggle');
function toggleClass(event) {
for (const $button of $buttons) {
$button.classList.remove(TOGGLE_CLASS_NAME);
}
event.target.classList.add(TOGGLE_CLASS_NAME);
}
for (const $button of $buttons) {
$button.addEventListener('click', toggleClass);
}
First remove the class from all the elements when a button is clicked and then add the class to the clicked button:
const sumButton = document.getElementById('add');
const substractButton = document.getElementById('subtract');
const multipleButton = document.getElementById('multiple');
const divideButton = document.getElementById('divide');
const mathButtons = [sumButton, substractButton, multipleButton, divideButton];
mathButtons.forEach(button => button.addEventListener('click', activeClass))
function activeClass() {
mathButtons.forEach(button => button.classList.remove('togglemath'));
event.target.classList.add('togglemath');
}
.togglemath {
color: red;
}
<button id="add">add</button>
<button id="subtract">subtract</button>
<button id="multiple">multiple</button>
<button id="divide">divide</button>
You are not far from the actual solution. The problem seems to be with the understanding of the following line:
[e.target, ...rest] = mathButtons;
This doesn't search the e.target out of mathButtons and assigns the other elements to rest. But instead assigns e.target to the first element in mathButtons and rest to the second, third end fourth. This produces the follow-up problem that e.target.classList.add('togglemath') will always add the class to the first button.
rest.classList.remove('togglemath') has a somewhat other issue, namely that you try to access classList on an array. Instead you should access it for element in the array.
Without changing your code much you could be looking at something like this:
const sumButton = document.getElementById('add');
const substractButton = document.getElementById('subtract');
const multipleButton = document.getElementById('multiple');
const divideButton = document.getElementById('divide');
const mathButtons = [sumButton, substractButton, multipleButton, divideButton];
const activeClass = () => {
mathButtons.forEach(el => {
el.addEventListener('click', e => {
mathButtons.forEach(mathButton => {
mathButton.classList.remove('togglemath');
});
e.target.classList.add('togglemath');
});
});
};
activeClass();
This solution first removes all togglemath classes from all buttons. Then adds it (back) to the clicked target.
Strafing somewhat from what you've provided, you could opt to save the active button in a variable. This way you only have to remove the class from the current active button, add it to the event target, and replace the active variable with the clicked target.
const sumButton = document.getElementById('add');
const substractButton = document.getElementById('subtract');
const multipleButton = document.getElementById('multiple');
const divideButton = document.getElementById('divide');
const mathButtons = [sumButton, substractButton, multipleButton, divideButton];
const activeClass = () => {
let active;
mathButtons.forEach(button => {
button.addEventListener('click', event => {
if (event.target === active) return;
if (active) active.classList.remove('togglemath');
event.target.classList.add('togglemath');
active = event.target;
});
});
};
activeClass();
button {
border: 1px solid #33497b;
padding: 0.25em 1em;
background-color: white;
color: #33497b;
}
button.togglemath {
background-color: #33497b;
color: white;
}
<button id="add" type="button">+</button>
<button id="subtract" type="button">−</button>
<button id="multiple" type="button">×</button>
<button id="divide" type="button">÷</button>

Categories