css transition not working as expected with JavaScript add class - javascript

I am trying to create a transition effect using css and the JavaScript classList.add function. My expected behaviour is that when the button is clicked, a grey background appears and on top of that another element slides in from the right. At the moment everything appears as expected, but for some reason the slide transition doesn't happen. Any ideas? I have created a basic version of my code below:
html:
<button id="product-form__book-product">Add</button>
<div class="product-form-slider" id="product-form-slider">
<div class="product-form-slider__inner" id="product-form-slider__inner">
<span class="close" id="product-form-slider__close-button">×</span>
<p>TEST</p>
</div>
</div>
scss:
.product-form-slider {
position: fixed;
display: none;
top: 0;
z-index: 11;
right: -65%;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
align-items: center;
justify-content: center;
right: 0;
&.active {
display: flex;
}
}
.product-form-slider__inner {
right: -65%;
height: 100%;
width: 65%;
background-color: #fefefe;
padding: 20px;
box-shadow: 5px 5px 10px #545151;
position: absolute;
&.slide-in {
right: 0;
transition: right 1s linear;
}
}
JavaScript:
var productFormBookButton = document.getElementById('product-form__book-product');
var productFormSlider = document.getElementById('product-form-slider');
var productFormSliderInner = document.getElementById('product-form-slider__inner');
var productFormSliderCloseButton = document.getElementById('product-form-slider__close-button');
productFormBookButton && productFormBookButton.addEventListener('click', showFormSlider);
function showFormSlider() {
productFormSlider.classList.add('active');
productFormSliderInner.classList.add('slide-in');
}
// Close slider on click of close button
productFormSliderCloseButton && (productFormSliderCloseButton.onclick = function() {
productFormSliderInner.classList.remove('slide-in');
productFormSlider.classList.remove('active');
})

Move transition property to main classes.
.product-form-slider {
position: fixed;
display: none;
top: 0;
z-index: 11;
right: -65%;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.4);
align-items: center;
justify-content: center;
right: 0;
&.active {
display: flex;
}
}
.product-form-slider__inner {
right: -65%;
height: 100%;
width: 65%;
background-color: #fefefe;
padding: 20px;
box-shadow: 5px 5px 10px #545151;
position: absolute;
transition: right 1s linear;
&.slide-in {
right: 0;
}
}
Also if you want animate properties like display not working very well. If you want to show and hide elements with the transition, you should use opacity

I managed to solve this by setting a 2 millisecond timeout function on my transition. This way I forced the transition to happen after the show of the background.
function showFormSlider() {
productFormSlider.classList.add('active');
setTimeout(function(){ productFormSliderInner.classList.add('slide-in') }, 2);
}

Related

Removing loading screen after site loads

So I made a loading screen in HTML and CSS, but I am very new to JavaScript and I would like to make the loading screen vanish when the page is loaded. How do I do it in JS? Here is my code:
.loader {
position: fixed;
display: flex;
align-items: center;
align-self: center;
justify-content: center;
background-color: #02171C;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.dissaper {
animation: fadeOut 1s forwards;
}
.ring {
position: absolute;
width: 250px;
height: 250px;
border-radius: 50%;
animation: ring 1.5s linear infinite;
}
.ring:before {
position: absolute;
content: '';
top: 0;
left: 0;
height: 100%;
width: 100%;
box-shadow: 0 0 10px #6497373b;
border-radius: 50%;
}
span {
color: #649737;
font-size: 20px;
letter-spacing: 1px;
line-height: 200px;
}
<div class="loader">
<div class="ring"></div>
<span class="isLoaded">LOADING...</span>
</div>
Using your CSS and HTML here is an example of how to hide the .loader div once the window has fully loaded using JS.
In my example i've changed .loader div class to #loader div ID for easier javascript.
I've also used transition CSS instead of animation CSS on the #loader div, which runs when .disappear class is added.
Here is jsfiddle version to... https://jsfiddle.net/joshmoto/z2dqe8jp/3/
See comments in JS and snippet console logs so you know JS timings with transition CSS, and when the #loader is removed.
// our loader div by id (not class)
let loader = document.getElementById('loader');
// on window loaded
window.onload = (event) => {
console.log('window loaded, and wait 3 secs for example #loader div to fade out');
// for demo example 3 second delay for page load
setTimeout(function() {
// add .disappear class to #loader div
loader.classList.add("disappear");
console.log('.disappear class added to #loader element');
// after 1 second css transition opacity .disappear has completed
// plus an extra 250 milliseconds so not to remove #loader before transition is complete
setTimeout(function() {
// remove #loader element from DOM entirely
loader.remove();
console.log('#loader div element removed from DOM');
// 1 second + 250 milliseconds delay
}, 1250);
// 3 seconds delay
}, 3000);
};
#loader {
position: fixed;
display: flex;
align-items: center;
align-self: center;
justify-content: center;
background-color: #02171C;
top: 0;
left: 0;
height: 100%;
width: 100%;
/* 1 second opacity ease transition */
transition: opacity 1s ease;
}
.disappear {
opacity: 0;
pointer-events: none;
}
.ring {
position: absolute;
width: 250px;
height: 250px;
border-radius: 50%;
animation: ring 1.5s linear infinite;
}
.ring:before {
position: absolute;
content: '';
top: 0;
left: 0;
height: 100%;
width: 100%;
box-shadow: 0 0 10px #6497373b;
border-radius: 50%;
}
span {
color: #649737;
font-size: 20px;
letter-spacing: 1px;
line-height: 200px;
}
<div id="loader">
<div class="ring"></div>
<span class="isLoaded">LOADING...</span>
</div>
you can check if the document loading is complete then:
1- remove the element. or
2- hide the element.
I added 1 second but you can remove it if you want.
comment remove then uncomment hide to see how it works then decide which one is suitable for you.
// remove
if (document.readyState = "complete") {
setTimeout(() => {
document.getElementById("loader").remove();
}, 1000);
}
// OR
// hide
if (document.readyState = "complete") {
setTimeout(() => {
// document.getElementById("loader").style.display = "none";
}, 1000);
}
.loader {
position: fixed;
display: flex;
align-items: center;
align-self: center;
justify-content: center;
background-color: #02171C;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
.dissaper {
animation: fadeOut 1s forwards;
}
.ring {
position: absolute;
width: 250px;
height: 250px;
border-radius: 50%;
animation: ring 1.5s linear infinite;
}
.ring:before {
position: absolute;
content: '';
top: 0;
left: 0;
height: 100%;
width: 100%;
box-shadow: 0 0 10px #6497373b;
border-radius: 50%;
}
span {
color: #649737;
font-size: 20px;
letter-spacing: 1px;
line-height: 200px;
}
<div class="loader" id="loader">
<div class="ring"></div>
<span class="isLoaded">LOADING...</span>
</div>

Slideshow with indicator CSS

Hi I am trying to figure out how to display images when clicked on a section on my bar. So far I have a working animation to switch between sections but I would like to display images under it. It's my first time doing this so I absolutely don't know how to do this and would very much appreciate the help.
var indicator = document.querySelector('.stefan-indicator');
var items = document.querySelectorAll('.stefan-item');
function handleIndicator(el) {
items.forEach(function (item) {
item.classList.remove('is-active');
item.removeAttribute('style');
});
indicator.style.width = "".concat(el.offsetWidth, "px");
indicator.style.left = "".concat(el.offsetLeft, "px");
indicator.style.backgroundColor = el.getAttribute('active-color');
el.classList.add('is-active');
el.style.color = el.getAttribute('active-color');
}
items.forEach(function (item, index) {
item.addEventListener('click', function (e) {
handleIndicator(e.target);
});
item.classList.contains('is-active') && handleIndicator(item);
});
.stefan {
margin-top:4%;
display: inline-flex;
position: relative;
overflow: hidden;
max-width: 100%;
background-color: inherit;
padding: 0 20px;
border-radius: 40px;
/* box-shadow: 0 10px 40px rgba(159, 162, 177, .8); */
display: flex;
justify-content: center;
}
.stefan-item {
color: #252525;
padding: 20px;
text-decoration: none;
transition: 0.3s;
margin: 0 6px;
z-index: 1;
font-family: 'Open sans', sans-serif;
position: relative;
cursor: pointer;
font-weight: 500;
}
.stefan-item:before {
content: "";
position: absolute;
bottom: -6px;
left: 0;
width: 100%;
height: 5px;
background-color: #ffb833;
border-radius: 8px 8px 0 0;
opacity: 0;
transition: 0.3s;
}
.stefan-item:not(.is-active):hover:before {
opacity: 1;
bottom: 0;
}
.stefan-item:not(.is-active):hover {
color: #ffb833;
cursor: pointer;
}
.stefan-indicator {
position: absolute;
left: 0;
bottom: 0;
height: 4px;
transition: 0.4s;
height: 5px;
z-index: 1;
border-radius: 8px 8px 0 0;
}
<div class="stefan">
<a class="stefan-item is-active" active-color="#ffb833">Section1</a>
<a class="stefan-item" active-color="#ffb833">Section2</a>
<a class="stefan-item" active-color="#ffb833">Section3</a>
<a class="stefan-item" active-color="#ffb833">Section4</a>
<a class="stefan-item" active-color="#ffb833">Section5</a>
<span class="stefan-indicator"></span>
</div>
If what you are trying to do is build tabs component you need to create elements for every tab that are hidden by default and only are displayed when your code tells it to.
So when stefan-item with section1 content is clicked, your javascript should tell stefan-content-1 to change it's style to display:block (by directly changing style or adding class).
You can have a look here: https://web.dev/building-a-tabs-component/ or use a ready made component. Bootstrap, Material UI and other systems have tabs for the taking.

All the elements disappear when I click on one of them, but only need the elements that I haven't clicked on to disappear

I want all the other elements(that I haven't clicked on) to disappear when I click on one of them, but instead all of them disappear. Here's the Javascript Code:
$(".content-toggler").click(function() {
let elTriggered = $(this);
elTriggered.parent().toggleClass("expand");
$(".content-toggler").each(function(index, element) {
if ($(element) === elTriggered) {
console.log("Passing on the clicked element...");
} else {
$(element).parent().toggleClass("hide");
}
console.log($(element))
console.log(elTriggered)
});
});
.circular-anim {
display: grid;
align-items: center;
justify-content: center;
margin: 1em auto;
/*With 'auto', you center the element according to the margin*/
margin-top: 0;
padding: 0;
width: 100%;
height: 100%;
border-radius: 2em;
position: absolute;
background: rgba(0, 0, 0, 0.25);
transition: 1s ease;
}
.content-toggler {
margin: 0;
padding: 0;
border-style: none;
background: #8D9CF4;
width: 175px;
height: 175px;
border-radius: 50%;
position: absolute;
top: 32.5px;
left: 188.5px;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page-content">
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
</div>
By the way, I injected some of the content from the js file and they already work well. Don't be surprised if you see some of the classes missing in the css code.
Why do all my elements disappear even though I want the one that I click on to stay?
Each time you call $() it creates a new jQuery object, and it will not compare equal to another object even if they refer to the same DOM element.
You can just use the .not() function to remove an element from the collection, instead of looping with .each() and comparing.
$(".content-toggler").click(function() {
let elTriggered = $(this);
elTriggered.parent().toggleClass("expand");
$(".content-toggler").not(this).toggleClass("hide");
});
.circular-anim {
display: grid;
align-items: center;
justify-content: center;
margin: 1em auto;
/*With 'auto', you center the element according to the margin*/
margin-top: 0;
padding: 0;
width: 100%;
height: 100%;
border-radius: 2em;
position: absolute;
background: rgba(0, 0, 0, 0.25);
transition: 1s ease;
}
.content-toggler {
margin: 0;
padding: 0;
border-style: none;
background: #8D9CF4;
width: 175px;
height: 175px;
border-radius: 50%;
position: absolute;
top: 32.5px;
left: 188.5px;
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page-content">
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
<div class="circular-anim"><button class="content-toggler"></button></div>
</div>

Loading Animation and grayed-out background not working

I just want to have a loading animation with grayed-out background upon clicking TestLoading button. But I can't get it right. The loading gif is slightly in the left side but I want it in the center. Also grayed-out background is not working.
Here's my css:
.divLoader {
margin: 0px;
padding: 0px;
position: fixed;
right: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: rgb(67, 71, 75);
z-index: 30001;
opacity: 0.8;
}
.divLoaderContent {
position: absolute;
color: White;
top: 50%;
left: 40%;
}
In my view, I have this:
<!--LOADER -->
<div id="divProcessing" class="divLoader">
<p class="divLoaderContent"><img src="~/Content/image/blocks.gif"></p>
</div>
and
$('#btnRoster1').click(function(e) {
$("#divProcessing").show();
});
Here is revised version of css:
.divLoader{
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(67, 71, 75, 0.8);
z-index: 30001;
}
.divLoaderContent{
position: absolute;
color: White;
top: 50%;
left: 0;
right: 0;
margin: auto;
transform: translateY(-50%);
}
And don't use p tag for img container. Use div instead
To animate .show() use
$('#btnRoster1').click(function(e) {
$("#divProcessing").show(800);
});
where 800 is 0.8 sec.
To align the gif you can use flex and get rid of absolute positioning:
.divLoaderContent {
color: White;
display: flex;
justify-content: center;
}
Moving elements (especially img tags) with top/left based on percentages can get messy because it depends on the img size. I recommend using flex with this approach. The justify-content will center the children horizontally and align-items will center vertically when display is flex
.divLoader {
margin: 0px;
padding: 0px;
position: fixed;
right: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: rgb(67, 71, 75);
z-index: 30001;
opacity: 0.8;
display: none;
justify-content: center;
align-items: center;
}
Then have your js just modify display in css to flex when you want it to show, then display: none when you want it to hide;
$('#btnRoster1').click(function(e) {
$("#divProcessing").css('display', 'flex');
});
Fiddle below (has a timeout after 3 seconds to simulate something loading) I took out the unnecessary <p> tag as well.
https://jsfiddle.net/Garrito/vh2ttmu9/35/

Css transform animation from right to left

I am working with a navigation bar that has slides a menu from right to left.
With my code, when the user picture is being clicked, it will show the menu.
So when it is loaded, menu is hidden and when it is clicked will be showed. I used to add class hidden and show to toggle to menu.
$(document).ready(function(){
$(".img-profile").click(function(){
$(".menu-wrapper").addClass("show");
});
$(".menu-bg").click(function(){
$(".menu-wrapper").removeClass("show");
});
});
CSS
.show{
display: inline-block !important;
}
.hidden{
display: none;
}
The problem is it's not animating even if I added the transition: all 0.2s linear 0s and the transform from 250px to 0
.menu-wrapper > .login-menu{
background-color: #fff;
height: 100%;
overflow-y: auto;
position: fixed;
right: 0;
width: 250px;
z-index: 5;
padding: 30px 20px;
text-align: center;
transition: all 0.2s linear 0s;
transform: translateX(0px);
}
.menu-wrapper .show > .login-menu{
transform: translateX(250px);
}
Also, I want to animate it on menu-close from right to left.
My full code is at JSFIDDLE
Changing the display CSS attribute does not trigger animations. Use the visibility attribute instead. This one triggers animations.
If you have good reason to use display (which is completely possible), you'll need to set the display attribute first to show the element, but keep the visibility on hidden. Set the visibility: visible attribute right after and the animation will be triggered.
Edit: I had a look at your fiddle. Don't use the .hidden class, because bootstrap sets display:none on .hidden elements. Just use the .show class alone, putting visibility:visible in the show class, and setting visibility:hidden on the .menu-wrapper element. Remove all the display:none lines in your CSS and you'll be fine.
Try to do it with this trick.
<header class="header">
<div class="container">
<a class="logo" href="/"></a>
<div class="login">
<div class="img-profile" style="background-image: url('http://graph.facebook.com/4/picture?width=100&height=100')"></div>
<div class="login-menu">
<div class="img-profile" style="background-image: url('http://graph.facebook.com/4/picture?width=100&height=100')"></div>
<p>Mark Zuckerberg</p>
<button type="button" class="btn btn-danger btn-block">Logout</button>
</div>
<div class="menu-bg"></div>
</div>
</div>
.header{
width: 100%;
height: 50px;
background: #fff;
border-bottom: 2px solid #ececec;
}
.header > .container{
height: 100%;
position: relative;
}
.logo {
background: url("http://d12xrwn9fycdsl.cloudfront.net/static/images/sv_logo.png") no-repeat scroll center center / contain ;
display: inline-block;
width: 23rem;
height: 100%;
}
.select-lang {
display: inline-block;
position: absolute;
top: 15px;
}
.login{
position: absolute;
right: 0;
top: 0;
}
.img-profile{
background: no-repeat scroll center center / contain;
position: relative;
top: 3px;
border-radius: 40px;
width: 40px;
height: 40px;
display: block;
margin: auto;
}
.login > .menu-wrapper{
display: none;
position: fixed;
left: 0;
top: 0;
bottom: 0;
z-index: 5;
height: 100%;
width: 100%;
}
.login-menu{
background-color: #fff;
height: 100%;
overflow-y: auto;
position: fixed;
top: 40px;
right: -250px;
width: 250px;
z-index: 5;
padding: 30px 20px;
text-align: center;
transition: all 0.2s linear 0s;
}
.show{
right: 0;
}
.hidden{
right: -250px;
}
.login-menu > .img-profile {
border-radius: 70px;
height: 70px;
width: 70px;
}
.login-menu > p {
font-weight: bold;
margin: 10px 0 20px;
}
.menu-wrapper > .menu-bg{
background-color: rgba(0, 0, 0, 0.6);
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
$(document).ready(function(){
$(".img-profile").click(function(){
$(".login-menu").addClass("show");
});
$(".img-profile").click(function(){
$("body").removeClass("show");
});
});
Take a look here https://jsfiddle.net/SkiWether/KFmLv/
this is working for me
$(".myButton").click(function () {
// Set the effect type
var effect = 'slide';
// Set the options for the effect type chosen
var options = { direction: $('.mySelect').val() };
// Set the duration (default: 400 milliseconds)
var duration = 500;
$('#myDiv').toggle(effect, options, duration);
});

Categories

Resources