Changing the Style of a HTML-Button within a JavaScript Function - javascript

I am trying to change the style class of a button when clicking it but it is not working how it should.
I need the style/icon change inside a JS function because I am doing some more stuff when the buttons gets clicked.
function generate() {
//// Some stuff
document.getElementById('btn1').class = 'play icon fa fa-stop';
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div class='container20'>
<button class='play icon fa fa-play-circle-o' type='button' onclick='generate()' id="btn1">Button</button>
</div>

class not exist, there is className, so replace it by className
In onclick there is function so, you need to add () in it so, replace generate to generate().
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div class='container20'>
<button class = 'play icon fa fa-play-circle-o' type = 'button' onclick = 'generate()' id = "btn1">Button</button>
</div>
<div class='container80'>
<script>
function generate() {
//// Some stuff
document.getElementById('btn1').className = 'play icon fa fa-stop';
}
</script>
</div>

Use className and not class
document.getElementById('btn1').className = 'play icon fa-stop';

Try the following:
Below code will add the 3 classes to any existing classes already applied to the button
document.getElementById('btn1').classList.add('play', 'icon', 'fa-stop');
Below code will replace any existing classes already added to the button with play, icon and fa-stop
document.getElementById('btn1').className = 'play icon fa-stop';

Rather than setting className, and having to preserve the play icon parts of the className text, you can use classList to remove and add the necessary classes
function generate() {
const b = document.getElementById('btn1')
b.classList.remove('fa-play-circle-o`);
b.classList.add('fa-stop');
}
Yes, it's more lines, but it's more flexible too. For example you could write a method that takes the old class and the new class and call it from anywhere.
function changeClass(element, old, new) {
element.classList.remove(old);
element.classList.add(new);
}
Also, since you are running in an event handler, you don't have to getElementById('btn1') because the event.target is the button that was clicked.
This (below) attaches an event handler, rather than using an inline onclick=, and I've added background color just so the effect of clicking the button can be seen.
document.getElementById('btn1')
.addEventListener('click', function(e) {
e.target.classList.remove('fa-play-circle-o');
e.target.classList.add('fa-stop');
});
button {
font-weight: bold;
}
button.fa-play-circle-o {
background-color: lightsalmon;
}
button.fa-stop {
background-color: lightgreen;
}
<div class="container20">
<button id="btn1" type="button"
class="play icon fa-play-circle-o">Button</button>
</div>

Related

How to show hidden div onclick of button and hide when not in focus using JS

I'm trying to create add a way to show a div onclick of a button and hide it when not in focus / when user clicks outside the div.
I've already managed to add a button that can show a hidden div, but I can't figure out how to make it hidden again when focus is lost.
I've read this: Hide a DIV when it loses focus/blur
...and other articles, but I couldn't follow them to make it work..
Please see my code so far:
function openCardsList() {
let window = document.getElementById("anchor-cards-list");
window.style.display = "block";
}
$(document).not("#anchor-cards-list").click(function() {
$('#anchor-cards-list').hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div class="collapse" id="anchor-cards-list">Lorem Ipsum</div>
<button id="anchor-open-cards-list-btn" onclick="openCardsList();">Collapse Maincard</button>
Any help would be appreciated. Thank you in advance!
you can use this code :
function openCardsList() {
let window = document.getElementById("anchor-cards-list");
window.style.display = "block";
}
function hideDiv(){
let window = document.getElementById("anchor-cards-list");
window.style.display = "none";
}
and add onclick event to parent div
div onclick="hideDiv()" style="height: 100vh;">
<div class="collapse" id="anchor-cards-list">Lorem Ipsum</div>
</div>
I'd personally simplify things to separate concerns. Add an event listener to the button (click) to show your div, and an event listener (blur) on the div to hide it again.
document.getElementById('anchor-open-cards-list-btn').addEventListener('click', showDiv);
document.getElementById('anchor-cards-list').addEventListener('blur', hideDiv);
Then showDiv and hideDiv just handle the element visibility.
Use jquery simple way
use toggle() instead of show/hide, because it is more clear and simple.
$(document).ready(function(){
$("#anchor-open-cards-list-btn").click(function(){
$("#anchor-cards-list").toggle();
});
});
OR
function openCardsList() {
$("#anchor-cards-list").toggle();
}
OR
For onblue you can also use this code
function openCardsList() {
$("#anchor-cards-list").css('display','block');
}
function hideD(){
$("#anchor-cards-list").css('display','none');
}
add onclick event in parent div
div onclick="hideD()">
<div id="anchor-cards-list">text</div>
</div>
i prefer to make let window outside the function so you can use it anytime needed. and also if you only make this for handle show/hide div while onclick and onblur you dont need jquery. the default javascript can deliver those event action.
script.js
let card = document.getElementById('anchor-cards-list')
function openCard() {
card.style.display = 'block'
}
function blurCard() {
card.style.display = 'none'
}
index.html
<div id="anchor-cards-list">Hello Text</div>
<button onclick="openCard()" onblur="blurCard()">Clik me</button>

Creating a read more button with html and javascript

I am using html, css and javascript to create a read more button. I have a paragraph and if this button is pressed, more text will de displayed.
This is my html code
<p class="details">Text that is displayed><span class="read-more">More text</span></p>
<button class="read-more-button">Read more</button>
//on the bottom of the page I also added the scripts
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
In my css file I make the paragraph between the span tag not visible
.details .read-more{
display:none;
}
In my javascript
const readMoreBtn = document.querySelector('.read-more-button');
const text = document.querySelector('.details');
readMoreBtn.addEventListener('click',(e)=>{
details.classList.toggle('read-more');
})
The problem is that when I press the Read more button nothing happens, the paragraph between the span tag is not displayed. Am I missing something here?
You need to target .read-more class, not .details.
Also, there is a undefined variable in event listener.
The correct JS code should be:
const readMoreBtn = document.querySelector('.read-more-button');
const text = document.querySelector('.read-more');
readMoreBtn.addEventListener('click',(e)=>{
text.classList.toggle('read-more');
})
You're toggling the class of p.details. You should toggle the class of `.read-more'.
const readMoreBtn = document.querySelector('.read-more-button');
const moreText = document.querySelector('.read-more');
readMoreBtn.addEventListener('click',(e) => {
moreText.classList.toggle('read-more');
// Consider changing the button text to collapse or removing it altogether perhaps?
})
.details .read-more{
display:none;
}
<p class="details">Text that is displayed<span class="read-more">More text</span></p>
<button class="read-more-button">Read more</button>

Displaying a block on mouseover inline

I want to display a <div> block when mouse enters an element
My code so far:
<div class="dropdown">
MEN
<div class="dropdowncontent" id="ddmen" style="margin-left:100px;">
TOPWEAR <br/>
BOTTOMWEAR </br>
FOOTWEAR
</div>
</div>
JavaScript Code:
var ddm=document.getElementById("ddmen")
function ddmenin()
{
ddm.style.display="block";
}
function ddmenout()
{
ddm.style.display="none";
}
But when i hover over <a href="#men"> I cannot click on the links in the <div> with class="dropdowncontent" as the block disappears when i leave the <a href="#men">
I don't understand why this is happening since i have used onmouseover, which is valid even for child elements.
I have tried doing it using css but for some reason the following does not work (Style.css is used in above html)
STYLE.CSS
.dropdowncontent{
display:none;
}
.dropdown:hover .dropdowncontent{display:block;}
Can someone please correct my code to satisfy my needs or has any other simple alternative?
Well, your div link container is not part of a link, so when you move cursor to dropdown menu you leave the link and onmouseout listener does its job.
What you want is to hide the menu when it's not needed anymore. E.g. you clicked on the menu item or you left the menu and didn't return for some time.
To achieve this you can do the following:
Add hiding the menu to click listener on menu items
Add a function that starts some timer as soon as you leave the dropdown button or the menu (so that makes two onmouseout listeners). If you return there, you can reset the timer in onmouseover. When timer is done you can hide the menu.
It can look like this:
const $ = document.querySelector;
let menuTimeoutId;
const menu = $('#ddmen');
function stopMenuTimeoutAndShowMenu() {
if (menuTimeoutId) {
clearTimeout(menuTimeoutId);
menuTimeoutId = null;
}
menu.style.display = 'block';
}
function startMenuTimeout() {
window.menuTimeoutId = setTimeout(() => {
menu.style.display = 'none';
}, 2000); // possible timeout value
}
$('#men, #ddmen').addEventListener('onmouseover', stopMenuTimeoutAndShowMenu);
$('#men, #ddmen').addEventListener('onmouseout', startMenuTimeout);
I think you should use the onmouseover and onmouseout in your <div class="dropdown"> instead. Because, when you go to the div.dropdowncontent you probably invokes the onmouseout event. So the code will be like this:
<div class="dropdown" onmouseover="ddmenin()" onmouseout="ddmenout()">
MEN
<div class="dropdowncontent" id="ddmen" style="margin-left:100px;">
TOPWEAR <br/>
BOTTOMWEAR </br>
FOOTWEAR
</div>
</div>
See if it works ;D
You can try simple CSS changes, that can even help you :
In your Style.css file:
.dropdown .dropdowncontent {
visibility: hidden;
}
.dropdown:hover .dropdowncontent {
visibility: visible;
}

Button styling bug

I want to receive information from my users using buttons, so i created two sections for that. When the user clicks a button i need it to change its style so the user will see a difference in what they clicked even when they click another button in the other section. The problem is that when another button is clicked the other section looses its style (so the user wouldn't know what he previously clicked). I pasted the html code of the part with the problem(below)
<div>
<p><strong>Network</strong></p>
<button class="btn25" onclick = "gfg_Run()">
MTN
</button>
<button class="btn25">
Glo
</button>
<button class="btn25">
9 Mobile
</button>
<button class="btn25">
Airtel
</button>
</div>
<div>
<p><strong>Data</strong></p>
<button class="btn25">
1Gb
</button>
<button class="btn25">
2Gb
</button>
<button class="btn25">
3Gb
</button>
<button class="btn25">
5Gb
</button>
<button class="btn25">
10Gb
</button>
</div>
i need it to change its style so the user will see a difference
Create a class called active and then set the buttons to use that class when the user selects them.
The problem is that when another button is clicked the other section looses its style
The issue is that you need to separate out each group. I added a class on the parent div that distinguishes the two groups: "data" or "speed". The button background will change to blue for each of the groups because it is limited to that class in the query as ".data" does here:
document.querySelectorAll('.data .btn25');
Here is an example snippet showing the basic technique.
const dataChoices = document.querySelectorAll('.data .btn25');
dataChoices.forEach(function(choice) {
choice.addEventListener('click', function() {
removeClass(dataChoices);
this.classList.add('active');
});
});
const speedChoices = document.querySelectorAll('.speed .btn25');
speedChoices.forEach(function(choice) {
choice.addEventListener('click', function() {
removeClass(speedChoices);
this.classList.add('active');
});
});
function removeClass(dataGroup) {
dataGroup.forEach(function(choice) {
choice.classList.remove('active');
});
}
.active {
background-color: lightblue;
}
div {
float: left;
margin-right: 10px;
}
<div class="data">
<p><strong>Data</strong></p>
<button id="1" class="btn25">1Gb</button>
<button id="2" class="btn25">2Gb</button>
<button id="3" class="btn25">3Gb</button>
<button id="4" class="btn25">5Gb</button>
<button id="5" class="btn25">10Gb</button>
</div>
<div class="speed">
<p><strong>Speed</strong></p>
<button id="1" class="btn25">1Mbps</button>
<button id="2" class="btn25">2Mbps</button>
<button id="3" class="btn25">3Mbps</button>
<button id="4" class="btn25">5Mbps</button>
<button id="5" class="btn25">10Mbps</button>
</div>
I have an alternate way to do this, but honestly Christopher Taleck's answer is perfectly fine as well, I just had a different conception of how to solve the problem and figured that would be informative for others facing a similar situation.
Here is a link to a JSFiddle with a working example: JSFiddle
Here is the complete code, an explanation of everything is provided below:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Button Practice</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="network-container">
<h2>Network</h2>
<button type="button" class="btn25">MTN</button>
<button type="button" class="btn25">Glo</button>
<button type="button" class="btn25">9 Mobile</button>
<button type="button" class="btn25">Airtel</button>
</div>
<div class="speed-container">
<h2>Speed</h2>
<button type="button" class="btn25">1Mbps</button>
<button type="button" class="btn25">2Mbps</button>
<button type="button" class="btn25">3Mbps</button>
<button type="button" class="btn25">5Mbps</button>
<button type="button" class="btn25">10Mbps</button>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
script.js
function ButtonContainer(element) {
this.element = element;
this.selectedButton = null;
this.element.addEventListener('click', function(e) {
if (e.target.type !== 'button') return;
if (this.selectedButton) this.selectedButton.classList.remove('active');
e.target.classList.add('active');
this.selectedButton = e.target;
});
}
const networkContainer = new ButtonContainer(document.querySelector('.network-container'));
const speedContainer = new ButtonContainer(document.querySelector('.speed-container'))
style.css
.active {
background-color: #9AD58E;
}
GENERAL CODE EXPLANATION
First, I would suggest removing this call to gfg_Run() from the .html file:
// index.html
<button class="btn25" onclick = "gfg_Run()">
And creating a separate file to hold your JS. Then, you can just link that file like so, right before the closing <body> tag (I created a file called script.js for this purpose):
// index.html
<script type="text/javascript" src="script.js"></script>
Also, I would suggest adding a descriptive class based on the type of buttons that each <div> holds, like so:
// index.html
<div class="network-container">
------ rest of the container ------
<div class="speed-container">
------ rest of the container ------
To handle the change of style on the button click, you can create a class that is added to the clicked button. I will use .active as that is a pretty common convention. This can be in a style.css file that you link from the head of the HTML document:
// style.css
.active {
background-color: #9AD58E;
}
In that script.js file, my approach would be to create a constructor function that represents the container that holds the buttons:
// script.js
function ButtonContainer(element) {
this.element = element;
this.selectedButton = null;
this.element.addEventListener('click', function(e) {
if (e.target.type !== 'button') return;
if (this.selectedButton) this.selectedButton.classList.remove('active');
e.target.classList.add('active');
this.selectedButton = e.target;
});
}
ButtonContainer CONSTRUCTOR FUNCTION EXPLANATION
We set the ButtonContainer up with two properties, element and selectedButton. element represents the DOM element which contains the buttons (in our case, a <div>), and the selectedButton represents the last <button> in this <div> that was clicked.
The eventListener will fire whenever the <div> is clicked anywhere inside it's borders. We only want to handle clicks on a <button> element within this <div>, so we exit the listener if the target of the event was not a button with the line below:
if (e.target.type !== 'button') return;
Next, we want to see of there is already a selectedButton in this <div>, and if so, we need to remove the .active class from it so we don't have two buttons in the same <div> that have colored backgrounds:
if (this.selectedButton) this.selectedButton.classList.remove('active')
Finally, we set the .active class on the <button> that triggered the event, and set the selectedButton property of this ButtonContainer object to that button, so that we can keep track of the currently selected button in this <div>:
e.target.classList.add('active');
this.selectedButton = e.target;
Then simply create two instances of the ButtonContainer that represent the <div> elements containing each group of buttons (each <div> should have a class representing the type of buttons it holds):
const networkContainer = new ButtonContainer(document.querySelector('.network-container'));
const speedContainer = new ButtonContainer(document.querySelector('.speed-container'));
In this way, you don't have to loop through the buttons and add event listeners to each, you simply allow each container to handle it's own button events. I like this approach because we seem to be treating the buttons like two separate groups, and this logically mirrors that.

div into a js button [duplicate]

This question already has answers here:
Add click event on div tag using JavaScript
(6 answers)
Closed 5 years ago.
I have a <div> that I have formatted very carefully to look nice, and I need to make it have the functionality of a button. How would I go about doing this?
You can give that div tag a onclick function as follows.
function myfns() {
console.log("Clicked")
}
<div id="btn" onclick="myfns()">Click</div>
First recommendation is to use a <button> instead. You can style that however you want as well. If that is not an option for some reason, you'll have to do a few different things to create a proper button out of a div element (to ensure that it works with keyboard and screen readers).
Add click handler. Eg btn.addEventListener('click', clickHandler);
Add enter key handler. Eg btn.addEventListener('keyup', keyHandler);
Add button role. role="button"
Add it to tab order: tabindex="0"
var buttons = document.querySelectorAll('.btn');
buttons.forEach(function (btn) {
btn.addEventListener('click', function(e) {
console.log('clicked');
});
btn.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
console.log('keyup');
}
});
});
.btn {
display: inline-block;
background: #eee;
border: 1px solid #aaa;
padding: 6px;
cursor: pointer;
}
<div class="btn" role="button" tabindex="0">My Button</div>
<div class="btn" role="button" tabindex="0">My Button</div>
<div class="btn" role="button" tabindex="0">My Button</div>
document.getElementByID("#divID").addEventListenet('click',()=>{
//write your logic
})
handle all button event similarly
e.g. doubleclick etc
Like if you have div
<div class="demo" >
....
</div>
And If you are using javascript
document.getElementsByClassName('demo')[0]
.addEventListener('click', function (event) {
// do something
});
using jquery u can do like
$(".demo").click(function(){
//do something
});

Categories