execute javascript after css class change - javascript

I am using this code to hide a div whenever I click a button. I am trying to activate this function not on 'onclick' but whenever the button gets the class 'active'.
Is that possible?
<button onclick="myFunction()">Try it</button>
<div id="myDIV">
This is my DIV element.
</div>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
</script>

Though, not sure how the element's class is changing, you can try calling the function if element has the class using classList.contains().
The following example demonstrate that along with MutationObserver and setInterval():
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "block" || x.style.display === '') {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
var elem = document.getElementById("tryBtn");
let observer = new MutationObserver(mutationRecords => {
if(elem.classList.contains('active')){
myFunction();
}
});
// observe attributes
observer.observe(elem, {
attributes: true
});
// test
setInterval(function(){
if(elem.classList.contains('active')){
elem.classList.remove('active');
}
else{
elem.classList.add('active')
}
}, 1000);
<button id="tryBtn">Try it</button>
<div id="myDIV">
This is my DIV element.
</div>

What you probably want to do is to use the MutationObserver API
<div id="myDIV">
This is my DIV element.
</div>
<button id="myButton" onclick="changeClass()">Change class</button>
<script>
function changeClass() {
document.getElementById("myDIV").classList.add("active");
console.log("Changed class to active")
}
function myFunction() {
var x = document.getElementById("myDIV");
console.log(x.style.display);
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
const config = {attributes: true};
const callback = function(mutationsList, observer) {
// Use traditional 'for loops' for IE 11
for(let mutation of mutationsList) {
if (mutation.attributeName === 'class') {
if(mutation.target.className.includes("active")){
myFunction(); // Or you can put function code here.
}
}
}
}
//Set the target node you want to observe
const targetNode = document.getElementById('myDIV');
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
</script>
I used the changeClass function so you can see how this works. Since I suppose you already have some way of setting the class to "active"

Related

Using an anchor to show/hide divs in an asp mvc app

In my Asp MVC program I can toggle a div with a button.
cshtml:
<button onclick="ShowPubs()"> Click to show or hide</button>
JScipt:
function ShowPubs() {
var x = document.getElementById("myPubs");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
and this works fine,
however, when trying to use links as in this code:
cshtnl:
<div id="AboutShow" style="display:block">
Show the hidden piece Show ▼
</div>
<div id="AboutHide" style="display:none">
Hide these details Hide ▲
A lot more stuff
</div>
using this JavaScript:
function ShowAbout() {
var x = document.getElementById("AboutShow");
var y = document.getElementsById("AbourHide");
if (x.style.display === "none") {
x.style.display = "block";
y.style.display = "none";
} else {
x.style.display = "none";
y.style.display = "b;pck";
}
return false;
}
The page url adds the # to the url and nothing else happens, what am I doing wrong here, please?
In else you use y.style.display="b;pck" which is not correct way. it must be block;
You need something like this.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#myDIV {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top: 20px;
}
</style>
</head>
<body>
Try it
<div id="myDIV">
This is my DIV element.
</div>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
</body>
</html>
Let me know if this works for you
change getElementsById to getElementById
change AbourHide to AboutHide
change b;pck to block
Code:
function ShowAbout() {
var x = document.getElementById("AboutShow");
var y = document.getElementById("AboutHide");
if (x.style.display === "none") {
x.style.display = "block";
y.style.display = "none";
} else {
x.style.display = "none";
y.style.display = "block";
}
return false;
}
result:

How to add a third javascript else if statement to a button?

EDIT
I meant to say, how could I add a third else if statement that would fire on the third click.
basically it opens and hide a different element on the first, second and third click.
so I want to add one more function to make a total of 3 functions to this onclick event that changes depending on how many times you click on the button. I am just not sure how to add a third function.
<div class="base" id="base">
<img src="img/base.svg">
</div>
<div class="base one" id="one">
<img src="img/one.svg">
</div>
<div class="base two" id="two">
<img src="img/two.svg">
</div>
<div class="base three" id="three">
<img src="img/three.svg">
</div>
<button class="test" id="test">btn</button>
var action = 1;
test.onclick = function viewSomething() {
if (action == 1) {
base.style.display = "none";
one.style.display = "block";
action = 2;
console.log(tets)
} else {
one.style.display = "none";
two.style.display = "block";
action = 1;
}
}
You already have the basic setup, you just need to extend it:
var action = 1;
test.onclick = function viewSomething() {
if (action == 1) {
base.style.display = "none";
one.style.display = "block";
action = 2;
console.log(tets)
} else if (action === 2) {
// ...
action = 3;
} else if (action === 3) {
one.style.display = "none";
two.style.display = "block";
action = 1;
}
Having said that, if you always go sequentially from one "action" to the other, you could consider moving each "action" into a separate function, storing all those functions into an array and have the click handler simply advance the index:
const actions = [
function(event) {
base.style.display = "none";
one.style.display = "block";
},
function(event) {
one.style.display = "none";
two.style.display = "block";
},
function(event) {
// ...
},
];
let actionIndex = 0;
test.onclick = function viewSomething(event) {
actions[actionIndex](event);
actionIndex = (actionIndex + 1) % actions.length;
};
The advantage of the solution is that you are decoupling the action "control" from the actions themselves and that you can more easily add and rearrange additional actions.
I'm not sure what you mean by a third function since I can only see viewSomething, but you can add an if else block to your if statement:
if (action == 1) {
base.style.display = "none";
one.style.display = "block";
action = 2;
console.log(tets)
} else if (this == that) {
// your logic here
} else {
one.style.display = "none";
two.style.display = "block";
action = 1;
}
If you really want three different functions (you currently have one function and two if statements), you need to use addEventListener:
function clickOne() {
console.log("first!");
}
function clickTwo() {
console.log("second!");
}
function clickThree() {
console.log("third!");
}
var test = document.querySelector("#test");
test.addEventListener("click", clickOne);
setTimeout(() => {
test.addEventListener("click", clickTwo);
}, 2000);
setTimeout(() => {
test.addEventListener("click", clickThree);
}, 5000);
<button class="test" id="test">Click</button>

ForEach Javascript take's only 1st element

Hey i've got 4icons and elements for each of them.
I want to add event listener for icons so when i hover them i will see p element and hide icon.
I can make it like this:
document.getElementById('burger').addEventListener('mouseenter', function(){
document.getElementById('burgerP').style.display = 'block';
document.getElementById('burger').style.display = 'none';
})
document.getElementById('burgerP').addEventListener('mouseleave', function(){
document.getElementById('burgerP').style.display = 'none';
document.getElementById('burger').style.display = 'block';
})
document.getElementById('food').addEventListener('mouseenter', function(){
document.getElementById('foodP').style.display = 'block';
document.getElementById('food').style.display = 'none';
})
document.getElementById('foodP').addEventListener('mouseleave', function(){
document.getElementById('foodP').style.display = 'none';
document.getElementById('food').style.display = 'block';
})
document.getElementById('location').addEventListener('mouseenter', function(){
document.getElementById('locationP').style.display = 'block';
document.getElementById('location').style.display = 'none';
})
document.getElementById('locationP').addEventListener('mouseleave', function(){
document.getElementById('locationP').style.display = 'none';
document.getElementById('location').style.display = 'block';
})
document.getElementById('delivery').addEventListener('mouseenter', function(){
document.getElementById('deliveryP').style.display = 'block';
document.getElementById('delivery').style.display = 'none';
})
document.getElementById('deliveryP').addEventListener('mouseleave', function(){
document.getElementById('deliveryP').style.display = 'none';
document.getElementById('delivery').style.display = 'block';
})
But i want to make it simple and make it in forEach loop. But when i make it i get effect only on 1st element. Should i create a node list?
And if so then how? (don't make me code just tell me how to do it please, i want to learn it not copy/paste)
I tried to make it like this:
document.querySelectorAll('.ikonka').forEach((icon) => {
icon.addEventListener('mouseenter', () => {
document.querySelector('.ikonka').style.display = "none";
document.querySelector('.opis').style.display = "block";
});
icon.addEventListener('mouseleave', () =>{
document.querySelector(".opis").style.display = "none";
document.querySelector(".ikonka").style.display = "block";
})
}
)
Here's and HTML code:
<section id="category">
<div class="burgers">
<i class="fas fa-hamburger ikonka" id="burger"></i>
<p id="burgerP" class="opis">Our burger's!</p>
</div>
<div class="mainFood">
<i class="fas fa-utensils ikonka" id="food"></i>
<p id="foodP" class="opis">Best dishes</p>
</div>
<div class="location">
<i class="fas fa-map-marked-alt ikonka" id="location"></i>
<p id="locationP" class="opis">We are here!</p>
</div>
<div class="delivery">
<i class="fas fa-car ikonka" id="delivery"></i>
<p id="deliveryP" class="opis">Free Delivery!</p>
</div>
<script src="app.js"></script>
</section>
You can also use icon inside the callback ... to get the related .opis use the undex to get it from the arraylike:
const opis = document.querySelectorAll(".opis");
const ikonka = document.querySelectorAll('.ikonka');
ikonka.forEach((icon, index) => {
const op = opis[index];
icon.addEventListener('mouseenter', () => {
icon.style.display = "none";
op.style.display = "block";
});
icon.addEventListener('mouseleave', () =>{
icon.style.display = "none";
op.style.display = "block";
});
});
You could set up a global array containing the IDs (location, delivery,...) of your elements.
Afterwards iterate over this array using a for loop and add the styles to each element you referenced inside.
You can also use icon inside the callback ... to get the related
.opis use the undex to get it from the arraylike:
const opis = document.querySelectorAll(".opis");
const ikonka = document.querySelectorAll('.ikonka');
ikonka.forEach((icon, index) => {
const op = opis[index];
icon.addEventListener('mouseenter', () => {
icon.style.display = "none";
op.style.display = "block";
});
icon.addEventListener('mouseleave', () =>{
icon.style.display = "none";
op.style.display = "block";
});
});
Yes this one work but had to change mouseleave eventlistener for this:
const opis = document.querySelectorAll(".opis");
const ikonka = document.querySelectorAll('.ikonka');
ikonka.forEach((icon, index) => {
const op = opis[index];
icon.addEventListener('mouseenter', () => {
icon.style.display = "none";
op.style.display = "block";
});
op.addEventListener('mouseleave', () =>{
icon.style.display = "block";
op.style.display = "none";
});
});
Because when i enter icon with mouse the P element stay. Now it's okay! thank you :)

Javascript mini Navbar insert

I have an interesting but probably simple problem. I am creating a nav bar insert that has 4 JS buttons that toggle hide a division each, I would like each button to hide the other three divisions while showing the one its own division. Currently each button is only attached to it's own division, I am asking for help that would toggle the other three divs.
Upon further thought I also would like to have the spades, hearts and clubs divs toggled off while the hearts on when a viewer first enters the page.
If you think that there is a better method, I am open to that too, my framework is django jfyi.
Cheers!
JS:
// Card Navigation Bar
function dhide() {
var x = document.getElementById("diamonds");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function chide() {
var x = document.getElementById("clubs");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function hhide() {
var x = document.getElementById("hearts");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function shide() {
var x = document.getElementById("spades");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
html
<button onclick="dhide()">Diamonds</button>
<button onclick="chide()">Clubs</button>
<button onclick="hhide()">Hearts</button>
<button onclick="shide()">Spades</button>
<div id=diamonds>...</div>
<div id=clubs>...</div>
<div id=hearts>...</div>
<div id=spades>...</div>
what about a function that hides them all, then shows the one you want?
js:
function toggleDivs(idToShow){
document.getElementById("diamonds").style.display = 'none';
document.getElementById("hearts").style.display = 'none';
document.getElementById("clubs").style.display = 'none';
document.getElementById("spades").style.display = 'none';
document.getElementById(idToShow).style.display = 'block';
}
toggleDivs('hearts');
html:
<button onclick="toggleDivs('diamonds')">Diamonds</button>
<button onclick="toggleDivs('clubs')">Clubs</button>
<button onclick="toggleDivs('hearts')">Hearts</button>
<button onclick="toggleDivs('spades')">Spades</button>
https://jsfiddle.net/rhoteL4t/
You could give all of the elements to show/hide the same class. Then you could do
document.getElementsByClassName
to get all of the dom elements you want. You can then loop through each one and turn it off unless it was the selected id.

On click show 'Div 1' & hide 'Div 2' & On click of same button show 'Div 2' and hide 'Div 1'?

I am able do this functionality with different button. but i am not able achieve this on click of same button.
Any help/suggestions
Thanks
Toggle the current element using ternary-operator
Use Element.style.display to set the display css
property
var btn = document.getElementById('btn');
var curr = 'div2';
btn.onclick = function() {
document.getElementById(curr).style.display = 'none';
curr = curr === 'div2' ? 'div1' : 'div2';
document.getElementById(curr).style.display = 'block';
};
div {
display: none;
}
<div id="div1">#div1</div>
<div id="div2">#div2</div>
<button id='btn'>Change</button>
Anything like this?
function divchange(){
div1 = document.getElementById("div1");
div2 = document.getElementById("div2");
if(div1.style.display == "none"){
div1.style.display = "block";
div2.style.display = "none";
}else{
div1.style.display = "none";
div2.style.display = "block";
}
}
<button id="divchangebutton" onclick="divchange();">test</button>
<div id="div1">asdf</div>
<div id="div2" style="display:none;">qwert</div>
Problem - If "display:none" sets in css, we cannot get value. "elem.style.display" return empty string.
We can solve it, using Computed Style.
var btn = document.getElementById("btn-toggle");
btn.addEventListener("click", function(){
var one = document.querySelector(".one");
var tow = document.querySelector(".tow");
one.style.display = (getRealDisplay(one) == 'none') ? 'block' : 'none';
tow.style.display = (getRealDisplay(tow) == 'none') ? 'block' : 'none';
});
// get real value of 'display' property
function getRealDisplay(elem) {
if (elem.currentStyle) {
return elem.currentStyle.display;
} else if (window.getComputedStyle) {
var computedStyle = window.getComputedStyle(elem, null);
return computedStyle.getPropertyValue('display');
}
}
.one, .tow{
width:200px;
min-height: 200px;
background-color:burlywood;
}
.tow{
display: none;
background-color:cadetblue;
}
<div class="one">1</div>
<div class="tow">2</div>
<button id="btn-toggle">show hide</button>

Categories