How to replicate jquery animation sequence in vanilla js/css - javascript

As the title says, I would like to replicate the animation bellow. the jquery API https://api.jquery.com/toggle/ decibels this default behavior as so:
easing (default: swing)
Type: String
A string indicating which easing function to use for the transition.
but I don't understand how the transition works. I have tried changing the opacity, translating the element, ect, but obviously no luck. If it is impossible to do this in a simple way without jquery, an answer for the transition effect without the toggle function is also acceptable (but not hide() and show() as I have already tried those and couldn't get it to work properly). And yes, I would prefer a swing transition if possible. any help is appreciated.
document.addEventListener('click', ()=>{
$('#elem').toggle('.hide');
});
.hide{
display:none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='elem' class= 'hide'>
easing text transion
</div>

I don´t know if I understood your question correctly but you want
document.addEventListener('click', ()=>{
$('#elem').toggle('.hide');
});
in normal JS?
You have two options: set an data attribute to #elem or you check if #elem has the class
.hide. But its easier to just add the css to the element
With data attribute:
<div id='elem' data-status='inv' class='hide'>
easing text transion
</div>
let toggleFunction = function() {
let elem = document.querySelector('#elem');
if (elem.dataset.status == "inv") {
elem.className = "";
elem.dataset.status = "vis";
} else if (elem.dataset.status == "vis") {
elem.className = "hide";
elem.dataset.status = "inv";
}
}
document.addEventListener('click', toggleFunction);
Or with css:
<div id='elem' style='display: none;'>
easing text transion
</div>
let toggleFunction = function() {
let elem = document.querySelector('#elem');
if (elem.style.display == 'none') {
elem.style.display = 'inherit';
} else {
elem.style.display = 'none';
}
}
document.addEventListener('click', toggleFunction);
If you still want the animation:
<div id='elem' style='height: 0px;'>
easing text transion
</div>
#elem {
transition: 1s ease-in-out all;
overflow-y: hidden;
}
let toggleFunction = function() {
let elem = document.querySelector('#elem');
if (elem.style.height == '0px') {
elem.style.height = '18px';
} else {
elem.style.height = '0px';
}
}
document.addEventListener('click', toggleFunction);
I hope I could help

You can toggle a class and use a css transition to do it
document.addEventListener('click', () => {
document.getElementById('elem').classList.toggle('no-height')
})
#elem {
max-height: 2em;
transition: max-height 0.5s ease-in-out;
overflow-y: hidden;
}
#elem.no-height {
max-height: 0;
}
<div id='elem'>
easing text transion
</div>

Related

Set display none after transition has finished with pure JS

How would I set display to none (and vice versa) only after the CSS transition has finished?
This is my current code but it doesn't work nicely – the transition isn't visible because I'm adding/removing display:none; straightaway.
<script type="text/javascript">
var mobile_menu = document.querySelector('#mobile-menu');
var mobile_menu_open = document.querySelector('#open-mobile-menu');
var mobile_menu_close = document.querySelector('#close-mobile-menu');
mobile_menu_open.addEventListener('click', function (event) {
mobile_menu.classList.remove('duration-100', 'ease-in', 'opacity-0', 'scale-95');
mobile_menu.classList.add('duration-200', 'ease-out', 'opacity-100', 'scale-100');
mobile_menu.removeAttribute('style');
});
mobile_menu_close.addEventListener('click', function (event) {
mobile_menu.classList.remove('duration-200', 'ease-out', 'opacity-100', 'scale-100');
mobile_menu.classList.add('duration-100', 'ease-in', 'opacity-0', 'scale-95');
mobile_menu.style.display = "none";
});
</script>
I can only think of setTimeout(); but in most cases it's not considered a proper solution but rather a dirty hack. Do I have any other options here?
You can use the transitionend event listener.
mobileMenu.addEventListener('transitionend', setDisplayNone);
After the animation is finished, it will execute setDisplayNone(). If you only want to run this once, you can add this at the end of the setDisplayNone function:
mobileMenu.removeEventListener('transitionend', setDisplayNone);
Example:
var div = document.querySelector('div')
function setDisplayNone() {
div.style.display = 'none'
}
document.querySelector('button').onclick = function() {
div.addEventListener('transitionend', setDisplayNone);
div.classList.add('transition')
}
.transition {
transition-duration: 3s;
opacity: 0;
}
<button>Click me!</button>
<br>
<div id='someDiv'>
Click the button!
</div>
This text will shift upwards once the div has display:none

JS/CSS to fade out and disable a block, then enable and fade in another, is fading out but popping in

I've set up the scenario in jsFiddle. My solution almost works, but it only fades out the old block, popping in the new one instead of fading in.
I've avoided the usual pitfall of trying to animate display: none; by transitioning the opacity first, detecting its completion, and only then setting display: none;. It works a charm for the fading out...
HTML:
<body>
<p>
Mouse over to translate:
</p>
<blockquote class="untranslated">
<p>Mae govannen</p>
</blockquote>
<blockquote class="translated disabled fade">
<p>Well met</p>
</blockquote>
</body>
CSS:
.disabled {
display: none;
}
.fade {
opacity: 0 !important;
}
.untranslated,
.translated {
opacity: 1;
transition: opacity 0.25s;
}
JS:
$(function($) {
function whichTransitionEvent() {
var t;
var el = document.createElement('fakeelement');
var transitions = {
'transition': 'transitionend',
'OTransition': 'oTransitionEnd',
'MozTransition': 'transitionend',
'WebkitTransition': 'webkitTransitionEnd'
}
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}
var transitionEnd = whichTransitionEvent();
var untranslated = $('.untranslated');
var translated = $('.translated');
untranslated.bind(transitionEnd, untranslatedFaded);
translated.bind(transitionEnd, translatedFaded);
untranslated.mouseenter(
function() {
$(this).addClass('fade')
}
)
translated.mouseleave(
function() {
$(this).addClass('fade')
}
)
function untranslatedFaded() {
untranslated.addClass('disabled'),
translated.removeClass('disabled'),
translated.removeClass('fade')
}
function translatedFaded() {
translated.addClass('disabled'),
untranslated.removeClass('disabled'),
untranslated.removeClass('fade')
}
});
Any ideas for getting it to fade in properly? Preferably without greatly changing the approach.

How to add transition into Javascript document.getElementById("myDIV").style.display = "none";

How can I add transition to document.getElementById("myDIV").style.display = "none"; I am currently working on a registration form in which if one input is of a certain value the other div is hidden but it looks so rough, Is there a way to add transitions into the following JS ?
<script type="text/javascript">
function myFunction() {
document.getElementById("myDIV").style.display = "none";
}
function hideshow(which){
if (!document.getElementById)
return
if (which.style.display=="block")
which.style.display="block"
else
which.style.display="block"
}
function myFunction1() {
document.getElementById("myDIV2").style.display = "none";
}
</script>
Create functions with parameters like
function hideDiv(div_id) {
document.getElementById(div_id).style.display = "none";
}
function showDiv(div_id) {
document.getElementById(div_id).style.display = "block";
}
The way to make a nice transition is to set style.display= "none" after you perform some kind of animation that removes the element from view.
You could:
Fade it out (set opacity to 0 - fade it with transition in CSS)
Slide it up/down/left/right (animation library or fancy CSS)
Do some other fancier animation (like bounce, shrink etc.)
Then, set style.display = "none"
The easiest way to do this (in my opinion) is with an animation library. I personally recommend VelocityJS because you don't need jQuery to run it.
I don't think there is anyway to do that with simple js, however I did it easily using JQuery
<script type="text/javascript">
$(document).ready(function(){
$("#myDIV").show();
$(document).on('click', '.married' , function() {
if (this.value == "never_married"){
$("#myDIV").hide('slow');
} else {
$("#myDIV").show('slow');
}
})
});
The reason is display isn't animated, setting it from block to none won't give you the result you're looking for.
A nice way to do this is to use CSS alongside JavaScript for the transition.
Add Transition to your myDIV style such as:
#myDIV {
opacity: 1;
transition: 1s ease;
}
#myDIV.hidden {
opacity: 0;
transition: 1s ease;
}
Then with JavaScript apply the hidden class to #myDiv and you'll get your animation.
Once the animation has finished then set el.style.display = 'none'; to make it disappear completely from view.

Javascript get element class or data attributes

At the moment I have a javascript function which looks for an id and changes some CSS. However I want this function to run on multiple divs. Therefore I need my function to look for a class or a data attribute. Please can you help me!
<script>
var div = document.getElementById('hover')
div.onclick = function () {
this.style.width = '800px'
this.style.transition = 'all 1s'
this.style.backgroundColor = 'red'
}
</script>
You could wrap all your elements inside a common parent, then you apply your click event handler to that parent, checking the target that originated the event.
Doing so you need to attach the event just to a single element (and not to every single element).
Also, your style should be declared in the CSS as a class, so you only need to switch that specific class (and it's always better to keep off css from javascript, for the mantainability)
here is a simple example http://codepen.io/anon/pen/jPwXVr
CSS
.open {
width: 800px;
-webkit-transition : all 1s;
-moz-transition : all 1s;
transition : all 1s;
background: red;
}
JS
document.getElementById('wrap').addEventListener('click', function(ev) {
var target = ev.target
if (target.nodeName === 'DIV') {
target.className = 'open';
}
}, false);
if the structure of your markup makes impossibile to use a common wrapper you could attach the event on the body element, like so
http://codepen.io/anon/pen/aOwPWY?editors=011
CSS
.element {
width: 800px;
-webkit-transition : all 1s;
-moz-transition : all 1s;
transition : all 1s;
}
.element.open {
background: red;
}
JS
document.body.addEventListener('click', function(ev) {
var t = ev.target;
/* I used classList for the sake of brevity, check caniuse.com
for its support across browser */
if (t.classList.contains('element')) {
t.classList.toggle('open');
}
}, false);
You need to use a class, which is better. And loop it through!
<script>
var divs = document.getElementsByClassName('hover');
for (var i = 0; i < divs.length; i++)
divs[i].onclick = function () {
this.style.width = '800px'
this.style.transition = 'all 1s'
this.style.backgroundColor = 'red'
}
</script>
Example using addEventListener:
<script>
var divs = document.getElementsByClassName('hover');
for (var i = 0; i < divs.length; i++)
divs[i].addEventListener("click", function () {
this.style.width = '800px'
this.style.transition = 'all 1s'
this.style.backgroundColor = 'red'
}, false);
</script>

Change button background image, text and shape on hover at the same time

I am wondering if it is possible to make a button background image or text change to another text or image along with the button shape on mouse hover?
Say I had a button having a certain text or background image shoving the symbol ✓ (checkmark) and I wish it to change shape (from a circle to a rectangle) and text (from checkmark to the word submit) on mouse hover.
Is it possible using CSS, JS or both?
Without Changing Animations
JSFiddle
If you just want to change the background image and shape, you can use pure CSS
.button {
height:30px;
width:60px;
-webkit-border-radius:15px;
-moz-border-radius:15px;
border-radius:15px;
background-image:url(...)
}
.button:hover {
-webkit-border-radius:0px;
-moz-border-radius:0px;
border-radius:0px;
background-image:url(...)
}
If you want to change the text, you need JavaScript.
<style>
#button {
height:30px;
width:60px;
border-radius:15px;
background-image:url(img1.png);
}
</style>
<script>
function mouseOver() {
document.getElementById("button").style.backgroundImage = "url(img2.png)";
document.getElementById("button").style.borderRadius = "0px";
document.getElementById("button").innerHTML = "Submit";
}
function mouseOut() {
document.getElementById("button").style.backgroundImage = "url(img1.png)";
document.getElementById("button").style.borderRadius = "15px";
document.getElementById("button").innerHTML = "✓";
}
</script>
<div id="button" onmouseover="mouseOver()" onmouseout="mouseOut()">✓</div>
With Changing Animations
JSFiddle
To animate the button, use the
-webkit-transition:all 0.2s;
transition:all 0.2s;
functions. Every property that is changed in the :hover css, is automatically animated with a duration of 0.2 seconds.
If you also want the text to change (in my example fading in and out) it gets a little more complicated. (Disclaimer: My solution is probably not the most elegant one, but it works.)
Add two more classes to your CSS, .fade-out and .fade-in.
.fade-out {
opacity: 1;
animation: fadeOut 0.2s;
}
.fade-in {
opacity: 0;
animation: fadeIn 0.2s;
}
In this case I wanted the text animation to be a little longer than the border animation (I think it looks better), but if they should be the same length, you have to set each of the animations to 0.1s
Then add two #keyframes animations, fadeOut and fadeIn like this:
#keyframes fadeOut {
from {opacity: 1;}
to {opacity: 0;}
}
#keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
Now the tricky part, the JavaScript:
function mouseIsOver() {
btn = document.getElementById("button_java");
btn.childNodes[0].className += ' fade-out';
setTimeout(function(){
btn.childNodes[0].innerHTML = "Submit";
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-out', '');
btn.childNodes[0].className += ' fade-in';
setTimeout(function(){
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-in', '');
}, 200);
}, 200);
}
function mouseIsOut() {
btn = document.getElementById("button_java");
btn.childNodes[0].className += ' fade-out';
setTimeout(function(){
btn.childNodes[0].innerHTML = "✓";
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-out', '');
btn.childNodes[0].className += ' fade-in';
setTimeout(function(){
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-in', '');
}, 200);
}, 200);
}
childNodes[0] gets all inner children (tags), and chooses the first one
className += ' fade-out' adds the class 'fade-out' to the elements class list. There needs to be a space in front of the added class name, just so if there are classes already defined, they won't combine into one non-existent class
setTimeout(function,waitduration) runs the code in function after it waitet waitduration milliseconds. Match this length to the duration of your animation in the .fade-out{...} class in your CSS-file
className.replace(' fade-out','') replaces the fade-out class in the elements list of classes with an empty string to remove it. Don't forget to remove the space, too.
Your Personalized Button
JSFiddle or PasteBin
I've copied the code from your page, added a <p> wrap around the text in the button, and added
.button p {
line-height:1em;
margin:0;
}
to the CSS.
Then you need to import jQuery by adding
<script src="http://code.jquery.com/jquery-2.1.3.js"></script>
into the head. Then add another code snippet,
<script type="text/javascript">
$( document ).ready(function() {
$("#subscribe_button").hover(
function() {
txt = $("#subscribe_button").children("p");
txt.fadeOut(100, function() {
txt.html("Sottoscrivi");
txt.fadeIn();
});
}, function() {
txt = $("#subscribe_button").children("p");
txt.stop(true,false).fadeOut(100, function() {
txt.html("✓");
txt.fadeIn();
});
}
);
});
</script>
That should be it!

Categories

Resources