Javascript functions with jQuery not fully working - javascript

I am using a hamburger menu which toggles class with jQuery and fades in/out a hidden menu using Javascript all in the same click function. It is working except that the icon has to be clicked twice before the menu fades in initially, not even double clicking gets it to work at the same time as the icon toggles class, after that it is fine and works as expected, just the delay on first opening page, Or is there a way to do it better with jQuery, I did try a couple of ways but couldn't get it. The code is below:
// In javascript
$( document ).ready(function() {
$(".hamburger").click(function() {
$("#primary_nav").toggleClass("is-active");
}
});
// In CSS
#primary_nav {
opacity: 0;
pointer-events: none;
transition: opacity 300ms;
}
#primary_nav.is-active {
opacity: 1;
pointer-events: auto;
}
Its all inside an init() function so Im not sure if I need the document ready. (I am using Sage 9 for Wordpress)
Any tips welcome. Thanks
Update I scrapped the javascript fades to use the jQuery toggle and css as in below answer, so its like that at the moment.
The original Javascript target the js-btn on click. Wordpress generates extra classes menu-main-container etc as in image below. Just need this little bit to finish the nav. Thanks

You asked for another way, so that's what I'm providing. I don't like doing simple transitions like this in JS - I find them easier and more performant in CSS. So here's my suggestion:
// In javascript
$( document ).ready(function() {
$(".hamburger").click(function() {
$("#primary_nav").toggleClass("is-active");
}
});
// In CSS
#primary_nav {
opacity: 0;
pointer-events: none;
transition: opacity 300ms;
}
#primary_nav.is-active {
opacity: 1;
pointer-events: auto;
}
#media (min-width: 920px){
#primary_nav {
opacity: 1;
pointer-events: auto;
}
}

Related

How to control transitions with multiple CSS class assignments from a single Javascript function?

I have one div, with buttons that trigger JS functions to add/remove CSS classes to the div. I understand this is a common way of doing simple animations ("transitions"). Try pressing the first two buttons, one after another. The red div will teleport up and become semi transparent, then fade in and slide back down. It always works.
The third button simply executes the same code as the first two buttons, but from one function. I expected it to have the same visible effect: the div immediately would jump up from the translate and be transparent, then during the course of 1 second it would slide back to its normal spot and fade in to full opacity. But it does not - the button has no visible effect.
Why? How can I make this work?
Here is the JS, see the whole thing at the codepen link.
const div = document.getElementById('red-box')
function translateUp() {
div.classList.remove('no-translate');
div.classList.add('translate-up');
}
function noTranslate() {
div.classList.remove('translate-up');
div.classList.add('no-translate');
}
//why does this function not show any transition animation?
function both() {
translateUp();
noTranslate();
}
https://codepen.io/DMcCreepy/pen/BampPyB
No jQuery please :)
The reason is that the functions are executed immediately one after the another, with no time to see the effect. transition in CSS refers to when the class is applied (could be related to a CSS state like :hover), not to switching classes via JavaScript.
To add the 1 second delay in the JS, you can use window.setTimeout:
function both() {
translateUp();
window.setTimeout(noTranslate, 1000);
}
You are relying on the div getting rerendered and all its properties being recomputed before switching the class again with the second function. I am not sure entirely what order things are done in under the hood, but I am sure you cannot rely on constructions like this working in general. It is true that switching classes is a common way to do animations and maybe it is possible to work out a solution like that, but I have provided a workaround using a CSS animation. You can read more about animations here https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations
const div = document.getElementById('red-box')
div.addEventListener('animationend', reset);
function reset() {
div.classList.remove('dropin');
}
function both() {
div.classList.add('dropin');
}
button {
display: block;
}
.box {
height: 70px;
width: 80px;
font-size: 50px;
background-color: red;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-name: none;
}
.box.dropin {
animation-name: dropin;
}
#keyframes dropin {
from {
transform: translate(0, -40px);
opacity: 0.1;
}
to {
transform: translate(0, 0);
opacity: 1;
}
}
<div id="red-box" class="box">div</div>
<button onclick='both()'>Do Both</button>

Creating HTML element and animating after creation

Update 2019-12-18 with better solution
See other SO question with updated solution
Trigger CSS transition on appended element
Short version: wrap the adding of a CSS animation class in a JS block that forces the browser to re-render the flow and not optimize it into a single call.
# CSS animation class
.visible {
...styles to change transparency from 0 -> 1
...styles to transform(scale) from 0.8 -> 1.0
}
# JS code
requestAnimationFrame(() => {
this.element.classList.add("visible")
})
Previously I had to do something like this:
$element.hide().show()
$element.addClass("visible")
Original question
I'm building an overlay (background for modals or dialog boxes) and I want it to fade in when I create the element. I do the animation by adding/removing a .visible class to the element using CSS3 transitions.
# SASS styles
.overlay {
background-color: rgba(0, 0, 0, 0.6);
cursor: pointer;
height: 100%;
left: 0;
position: fixed;
pointer-events: none;
top: 0;
width: 100%;
will-change: opacity;
#include transparency(0);
#include transition(opacity 0.3s cubic-bezier(0, 0, 0.3, 1));
&.visible {
pointer-events: auto;
#include transparency(1.0);
}
}
When the overlay element already exists on the DOM, everything works just fine:
$(".overlay").addClass("visible") # => does animation as expected...
However, when I CREATE the element and THEN try to animate it, it does not:
# JavasScript using jQuery
tag = $("<div class='overlay'></div>")
$("body").append(tag)
tag.addClass("visible")
I understand this is because the JavaScript is creating and adding the class "instantly", so what I have to do is this:
tag = $("<div class='overlay'></div>")
$("body").append(tag)
tag.hide()
tag.show()
tag.addClass("visible")
By "hiding" and then "showing" the element, it has enough time for the add class to animate the element.
Question
This seems pretty hacky to show/hide an element so I can then animate it via CSS transitions. Is there a cleaner way of implement this?
"Cleaner" is in the eye of the beholder, but one simple way is to wait a tick before you add the visible class:
$("body").append(tag);
setTimeout(function () {
tag.addClass("visible");
}, 0);
That'll wait until the appending is complete before adding the class. You might need to adjust the 0 value higher.

show a website loading image using only CSS (not Javascript or jQuery)

How can i put a logo and a loading image when a user open the website
when the user open the website the logo appear with a loading image than the home page appear after a certain moment like this website
http://www.theprofessionalslb.com/
and it possible to do that without using javascript or jquery only in css?
Yes, you can animate with pure CSS using the animate property.
For example, if you would want #img1 to show first, and #img2 to show after, you can set an animation-delay on your second image and make that equal to the animation-duration of your first:
#img1 {
...
animation-duration: 2s;
...
}
#img2 {
...
animation-delay: 2s;
...
}
Then in your animation you can animate e.g. the opacity property to simulate a fade-in effect.
More on CSS Animations here.
EDIT
I created a fiddle doing what you want.
For support in more browsers, please advice caniuse.com.
Use loader image and apply it to body. Show the image till page load and when page is ready remove the image.
jQuery( window ).load( function(){
//show the image here.
});
jQuery( document ).ready( function(){
//hide the image here.
});
The way they did it, it's handled by jQuery-Animations, something like this:
// Fade-In logo
$('#logo').fadeIn(2000, function() {
// When done, fade-in the slogan
$('#slogan').fadeIn(1400, function() {
// When this is done, wait 1s and then fade both out
$('#logo, #slogan').delay(1000).fadeOut(2000, function() {
// Finally fade-in the content
$('#content').fadeIn(2000);
});
});
});
The first argument of the fadeIn-method is the animation-time, the second argument is the callback-function, that gets executed after the animation is done. For more information see its documentation.
This technique assumes either, that your animated elements are either set to opacitiy: 0 in their CSS, or that you set them hidden in your JS:
$('#logo, #slogan, #content').fadeOut(0);
or:
$('#logo, #slogan, #content').hide();
You could also use plain CSS for this, where you would do something like this:
#logo, #slogan, #content {
opacity: 0;
}
#keyframes fadeInAndOut {
0% { opacity: 0; }
50% { opacity: 1; }
75% { opacity: 1; }
100% { opacity: 0; }
}
#logo {
animation-name: fadeInAndOut;
animation-duration: 6400ms;
}
#slogan {
animation-name: fadeInAndOut;
animation-duration: 4400ms;
animation-delay: 2000ms;
}
#content {
transition: opacity 2000ms ease-out 6400ms;
opacity: 1;
}
Please be aware that both examples are untested and should just give you an idea. You will probably need to also use the -webkit-keyframes prefixed version for the animation and also if you want the animation timings to be visually perfect, you'd need two separate fadeInAndOut-keyframes for both.

How Does CSS Opacity Work When Adding Class?

I'm trying to get something to fade in using Jquery. I am gathering the info via scrollTop(). So, when the scroll top equals the offset().top of the div, it will fadein. Or just appear.
#myDiv {
background: #990000;
height: 500px;
width: 100%;
overflow: hidden;
opacity: 0;
}
.fade-in {
opacity: 1.0;
}
There's my CSS.
var winHeight = $(window).height();
$(window).scroll(function() {
var scrollTop = $(window).scrollTop();
$("#myDiv").each(function() {
var $this = $(this);
var trigger = $(this).offset().top;
if (scrollTop >= trigger) {
$this.addClass("fade-in");
}
});
});
And there is my Jquery. The funny thing is that if I use $this.css it works fine.
I am just wondering how CSS and Jquery interact when it comes to opacity.
The id-selector(#myDiv) class gets more priority than the class-selector(.fade-in) in css. So the opacity property in the #myDiv gets more priority when your div has both the classes added. Just changing the .fade-in class a bit, your code should work fine.
.fade-in {
opacity: 1.0 !important;
}
Hope it helps :)
The jQuery .addClass() method just instantly adds the specified class to the element, and once it's added, the css rules are instantly applied just like they would be if you had added the class in the HTML. There's absolutely nothing special or jQuery-specific about how the rules are applied, so opacity shouldn't be applied any differently than any other CSS rule would be. If you believe you're getting a different result when applying the rule via $(this).addClass("fade-in") rather than using $this.css, I'd suggest setting up a jsFiddle to show the issue so folks can take a look at it for you.

Transitioning sorting what is displayed on webpage

Looking for a way to do something like this.
Where when you click on a section it nicely transitions them.
Would it be a Jquery plug in or done with CSS?
You can do it with both jQuery and CSS, however the CSS support is a little worse than the jQuery-centric solution.
Try something like this for use with jQuery...
$('outerdiv').click(function() {
// `this` being the html element clicked on
$(this).fadeOut(function() { //After fadeOut completes,
$('.page-to-show').fadeIn(); //Fade in target page
});
});
Let me know if you need more advice on how to get this set up.
It looks like you want something along the lines of this plug-in: Quicksand
try this one.
Note:.cont stands for the name of the div or the body that u want to fade or something
.cont{
animation: transitionIn 2s;
}
#keyframes transitionIn{
from{
opacity: 0;
transform: rotateX(-10deg);
}
to{
opacity: 1;
transform: rotateX(0);
}
}

Categories

Resources