Element disappears after removing class - javascript

I've come across some strange behavior in Chrome 60.0 when removing a class from an element with a very specific configuration.
I removed the fade class from an <h1> element and it makes it completely disappear. The problem can be reproduced by removing the class in the dev-tools element inspector as well. Can anyone tell me what's going on here?
The element should just go back to full opacity after clicking the button.
var button = document.querySelector('button');
var h1 = document.querySelector('h1');
button.addEventListener('click', function(){
h1.classList.remove('fade');
});
.center {
overflow: hidden;
}
h1 {
float: left;
overflow: hidden;
}
.fade {
opacity: .2;
}
<div class="center">
<div>
<h1 class="fade">Watch me disappear</h1>
</div>
</div>
<button>Click</button>

Removing the overflow: hidden property defined for h1, will solve your problem.
var button = document.querySelector('button');
var h1 = document.querySelector('h1');
button.addEventListener('click', function() {
h1.classList.remove('fade');
});
.center {
overflow: hidden;
}
h1 {
float: left;
}
.fade {
opacity: .2;
}
<div class="center">
<div>
<h1 class="fade">Watch me disappear</h1>
</div>
</div>
<button>Click</button>

Related

Adding class when screen is clicked

I have no knowledge of js, but I am trying to add a class to a div when any point of the screen is clicked. I have this html
<div class="container">
<div class="box"></div>
</div>
And I need to add the class to the container when any point of the screen is clicked.
I tried this js
<script>
let button = document.querySelector('.container');
button.addEventListener('click', function() {
button.classList.add('.hide');
});
</script>
but it is not working, the class is not being applied. What am I doing wrong?
There is a small syntax error: the class should be mentioned without the dot prefix:
button.classList.add('hide');
Demo
let button = document.querySelector('.container');
button.addEventListener('click', function() {
button.classList.add('hide');
});
.container {
background-color: #ddd;
cursor: pointer;
}
.box {
background-color: #ccf;
margin: 1rem;
}
.hide {
opacity: 0;
transition: opacity .5s ease-in-out;
}
<div class="container">
<br>
<div class="box">Click anywhere in the grey container to hide it</div>
<br>
</div>

How to make inner elements of a container not able to be clickable and selected

I want to implement a loading state where when we click on the button, we make the container opacity to .32 and we shouldn't be able to click or select the elements inside the container. In the example below, the inner a tag is still clickable and selectable after the loading is shown.
const container = document.getElementById('container');
const btn = document.getElementById('load');
btn.addEventListener('click', () => {
container.classList.add('loading');
})
#container {
width: 300px;
height: 300px;
background: tomato;
}
.loading {
opacity: .32;
user-select: none;
}
<div id="container">
Test
Test
Test
Test
</div>
<button id="load">
Load
</button>
Have you looked into using pointer-events: none; from CSS? See running snippet below.
const container = document.getElementById('container');
const btn = document.getElementById('load');
btn.addEventListener('click', () => {
container.classList.add('loading');
})
#container {
width: 300px;
height: 300px;
background: tomato;
}
.loading {
opacity: .32;
user-select: none;
pointer-events: none;
}
<div id="container">
Test
Test
Test
Test
</div>
<button id="load">
Load
</button>
I believe what you are trying to do is, disabling the anchor tag. For this, you can simply use the following property in the CSS: pointer-events: none;.
With this even if the anchor tag is clicked, nothing will happen.

Transitioning Visibility/Opacity w/in JS

I have an alert box that I want to use sessionStorage so that it only appears once. When the user clicks to close the alert, I want the box to disappear (display:none) but fade-out.
I read that you have to use two different functions - one that is activated when clicked and starts the transition and another the adds the 'display' style once transitioned. However, I can't get that to work:
<style>
.ddAlert {
padding: 20px;
box-sizing: border-box;
background-color: #f0ad4e;
color: #fff;
opacity: 1;
transition: opacity 1s;
}
.hide {
opacity: 0;
display: none;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let dismissed = sessionStorage.getItem("dismissed");
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
if (!dismissed) {
alertDiv.classList.remove("hide");
}
alertDiv.addEventListener("click", function() {
this.style.display = "block";
}.bind(alertDiv));
alertDiv.addEventListener("transitionend", function() {
if (this.className == "hide") {
this.style.display = "none";
}
sessionStorage.setItem("dismissed", true);
}.bind(alertDiv));
});
</script>
<div class="ddAlert hide" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
You are on the right track. Instead of listening on click on the alert, use the button as I assume it is there for that reason. When clicking the button the .hide class should be added to the alert. This will start the transition from opacity: 1; to opacity: 0;.
I suggest that instead of using inline-styles, that you stick to classes. Inline styles are hard to overwrite and prevents you from utilizing the full power of CSS. So I've added some classes in there to help you out.
Try out the example below.
<div class="ddAlert hidden" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
.ddAlert {
display: block;
transition: opacity 1s;
}
.hide {
opacity: 0;
}
.hidden {
display: none;
}
document.addEventListener("DOMContentLoaded", function() {
let dismissed = sessionStorage.getItem("dismissed");
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
if (!dismissed) {
alertDiv.classList.remove("hidden");
}
dismissButton.addEventListener("click", function() {
alertDiv.classList.add("hide");
});
alertDiv.addEventListener("transitionend", function({ target }) {
if (target.classList.contains("hide")) {
target.classList.add("hidden");
}
sessionStorage.setItem("dismissed", true);
});
});
This answer greatly lends from this SO question titled CSS3 Transition - Fade out effect which notes
When showing the element (by switching to the visible class), we want
the visibility:visible to kick in instantly, so it’s ok to transition
only the opacity property. And when hiding the element (by switching
to the hidden class), we want to delay the visibility:hidden
declaration, so that we can see the fade-out transition first. We’re
doing this by declaring a transition on the visibility property, with
a 0s duration and a delay.
I chose not to mark this question as a duplicate because it also involves the transitionend event. Additionally, I've focused only on the essence of the transition, with a minimal illustration.
The crucial element is the .dismissed-saved class.
let alertDiv = document.getElementById("alert");
let dismissButton = document.getElementById("dismiss");
dismissButton.addEventListener("click", function() {
// kick in the transition
alertDiv.classList.add("dismissed-saved");
// *this is where state should be committed
});
alertDiv.addEventListener("transitionend", function({
target
}) {
if (target === alertDiv) {
// clean up and show a nifty text message illustrating the event handler.
target.classList.add("hidden");
target.classList.remove("dismissed-saved");
document.getElementById("dismissed").classList.remove('hidden');
}
});
.ddAlert {
padding: 20px;
box-sizing: border-box;
background-color: #f0ad4e;
color: #fff;
opacity: 1;
}
.hidden {
display: none;
}
.dismissed-saved {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
<div class="ddAlert" id="alert">
SOME ANNOYING ALERT HERE!
<button type="button" id="dismiss">X</button>
</div>
<div id="dismissed" class="hidden">
Dismissed!
</div>
Good luck!

How to prevent links from being tab stops when they're not hidden with display block?

I'm trying to implement a simple dropdown with a slideDown effect. To build this effect I used a CSS transition applied to the height property.
Problem is that if I press the Tab ↹ key, any targetable element (tab stops) inside the dropdown will be targeted, even when it is hidden as I am not using display: none.
Here's the code:
const button = document.getElementById('button');
const dropdown = document.getElementById('dropdown');
dropdown.style.setProperty('height', 'auto', 'important');
dropdown.style.setProperty('height', dropdown.clientHeight + 'px');
button.addEventListener('click', function(e) {
e.target.classList.toggle('active');
e.target.nextElementSibling.classList.toggle('active');
});
#dropdown {
overflow: hidden;
transition: height 330ms linear;
background-color: lightgrey;
height: 200px;
}
#dropdown:not(.active) {
height: 0 !important;
}
#dropdown.active {
visibility: visible;
}
<button id="button">Click me!</button>
<div id="dropdown">
I should not be accessible with tab when dropdown is hidden
</div>
<div id="info">This link will be focused after three tabs, instead of two: Tab me!</div>
I have tried to modify the code a little bit using the transitionend event to add and remove display: none when the transition ends thus making any targetable elements inside the dropdown untargetable, but this messes up with the starting animation of the transition.
See:
const button = document.getElementById('button');
const dropdown = document.getElementById('dropdown');
dropdown.style.setProperty('height', 'auto', 'important');
dropdown.style.setProperty('height', dropdown.clientHeight + 'px');
dropdown.classList.add('hidden');
button.addEventListener('click', function(e) {
if (!e.target.classList.contains('active'))
dropdown.classList.remove('hidden');
e.target.classList.toggle('active');
e.target.nextElementSibling.classList.toggle('active');
});
dropdown.addEventListener('transitionend', function(e) {
dropdown.classList.add('hidden');
});
#dropdown {
overflow: hidden;
transition: height 330ms linear;
background-color: lightgrey;
height: 200px;
}
#dropdown:not(.active) {
height: 0 !important;
}
#dropdown.active {
visibility: visible;
}
a {
display: block; /* so it doesn't move when dropdown is hidden */
}
.hidden {
display: none;
}
<button id="button">Click me!</button>
<div id="dropdown">
I should not be accessible with tab when dropdown is hidden
</div>
<div id="info">This link will now be focused after <strong>two</strong> tabs, as expected: Tab me!</div>
Try setting attribute "tabindex" to -1, this should prevent link from selecting with tab. You can also simply remove this attribute with JS when dropdown is active
You can modify the element’s tabIndex (-1 to make it untargetable, very high number to make it targeted last). How to ignore HTML element from tabindex?

How to make Accordion(CSS+javascript) work?

I have this code so far:
var acc;
acc = document.getElementByClassName('button');
acc.onclick = function()
{
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: 0.6s ease-in-out;
opacity: 0;
}
div.panel.show {
opacity: 1;
max-height: 500px;
}
.button{
display:block;
height:431px;
width:100%;
font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
color:black;
font-size:80px;
margin:0 auto;
background-color:transparent;
border-style:none;
}
.button:hover, .button.active{
background: url('pcluj.jpg') ;
background-size: cover;
}
<center><button class="button" id="button">CLUJ</button></center>
<div class="panel">
<p>Lorem ipsum...</p>
</div>
Right now it doesn't work and I don't know why!! The div doesn't show up when I press the first button. What is the solution? Please help!
It looked like my post was only code so I had to write this in order to be able to post ...........
One way to achieve it if you are only supporting Chrome and Safari or Mobile Devices is to use the HTML5 details element and style it with CSS. You won't even need JavaScript.
Read on: http://dipaksblogonline.blogspot.in/2014/09/html5-details-element.html
Basic Demo: http://jsfiddle.net/8mthoj5g/1/
<details open>
<summary>Click me to toggle more information</summary>
<div>The details element is used as a widget to show/hide additional information.</div>
</details>
Another way is to use the onclick as attribute on the button - it will work -
<button class="button" id="button1" onclick="someFunc()">CLUJ</button>
Demo: https://jsfiddle.net/Lp05m27p/
Jquery
$("#button").click(function(){
var divPnl = $('.panel');
$(this).toggleClass("active");
divPnl.toggleClass("show");
});
fiddle link
javascript:
window.onload = function(){
var acc;
acc = document.getElementById('button');
acc.onclick = function()
{
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
html:
<button class="button" id="button">CLUJ</button>
<div class="panel">
<p>Lorem ipsum...</p>
</div>
You have several errors in your Javascript code. You are trying to assign a click event handler to an element before it actually exists in the DOM. You are also referring to the div that you are trying to show incorrectly. See below a working JavaScript code with comments and your mistakes fixed.
// You need to make sure that the button element exists before trying to attach a click handler to it.
// You can do that by running the function when the onload event is triggered.
window.onload = function () {
var acc;
acc = document.getElementsByClassName('button')[0];
// You have errors in the above line, "s" is missing in getElement/s/ByClassName, also that method returns an array, not an element, so you need to add [0] at the end.
acc.onclick = function()
{
this.classList.toggle("active");
// this.nextElementSibling.classList.toggle("show");
// This does not work because <button> is in <center> and the panel div is therefore not its sibling.
// there are many ways to reference the panel div, eg:
var panel= document.getElementsByClassName("panel")[0];
panel.classList.toggle("show");
}
}
Ideally you would use an established method or existing library for an accordion such as an Unordered List but what you've got already can be made to work with a few minor changes:
Firstly, use querySelectorAll to select the .button element. This returns a NodeList.
Iterate through the NodeList using a basic for-loop and add an event listener to each item which calls a method to toggle the .button's active class.
Rather than find the children of the active .button we simply use CSS2's Adjacent Sibling Selector to select the .buttons next sibling .panel
E.G:
// Get the .buttons
var buttons = document.querySelectorAll('.button');
// For each button
for (i = 0; i < buttons.length; ++i) {
//add an event listener
buttons[i].addEventListener("click", onButtonClick, false);
}
// On button click...
function onButtonClick(){
this.classList.toggle("active");
}
div.panel {
padding: 0 18px;
background-color: white;
max-height: 0;
overflow: hidden;
transition: 0.6s ease-in-out;
opacity: 0;
}
/*
div.panel.show {
opacity: 1;
max-height: 500px;
}
*/
.button{
display:block;
height:50px;
width:100%;
font-family: Futura, 'Trebuchet MS', Arial, sans-serif;
color:black;
font-size:20px;
margin:0 auto;
background-color:transparent;
border-style:none;
outline:none;
}
.button:hover, .button.active{
background:#eee url('http://lorempixel.com/100/20/') ;
background-size: cover;
}
#button1:hover, #button1.active{
background-image:url('http://lorempixel.com/100/20/');
}
#button2:hover, #button2.active{
background-image:url('http://lorempixel.com/200/20/');
}
/* adjacent sibling selector to select a .panel next to an button.active: */
.button.active + .panel {
opacity: 1;
max-height: 500px;
}
<button class="button" id="button1">ONE</button>
<div class="panel">
<p>Lorem ipsum one...</p>
</div>
<button class="button" id="button2">TWO</button>
<div class="panel">
<p>Lorem ipsum two...</p>
</div>

Categories

Resources