I have this code below where I press a button to show/hide a div.
I want the objects inside the div to slide from left to right to appear with an animation in JavaScript. How do I implement that into my code?
<script>
function myFunction() {
var x = document.getElementById("test");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
you could use an CSS animation. Here's an example of a projekt I did:
#keyframes spin {
0% {
transform:rotate(0deg);
}
100% {
transform:rotate(720deg);
}
}
to activate the animation in js copy this:
document.getElementById("your_did_id").style.animation = "spin 1.5s alternate 1";
Due to that display is not an attribute that is CSS animatable there's no way to actually solve this with the way shown in the question.
A way to solve this problem is to declare for the object a max-height or max-width and setting then these values to 0 or null. In CSS than is a transition property to be included.
Another way is to lower the opacity value and then applying display. For this method the transition property is needed as well.
Related
How can I run a method inside and animation? or run two animations and a method between them? I'm trying to add a div then change it opacity from 0 to 1, than run a method and then change the opacity again from 1 to 0, some kind of load screen.
I just tried to divide the animation and method in two and use eventlisteners with "animation end" but doesn't work properly (just works the first run, the second time the changeScreen method is used the classList say is null the error says: "Uncaught TypeError: Cannot read property 'classList' of null
at HTMLDivElement." in document.querySelector("#screen").classList.remove("screenOff");)
here the methods:
const screen = document.createElement('div'); //Const to add the load screen
screen.id = 'screen';
function changeScreen(token){
document.body.prepend(screen);
document.querySelector("#screen").classList.add("screenOff");
document.querySelector("#screen").addEventListener("animationend", function(){
loadScreen(loadFile(token));
document.querySelector("#screen").classList.remove("screenOff");
document.querySelector("#screen").removeEventListener("animationed", null);
retrieveScreen();
},false);
}
function retrieveScreen(){
document.querySelector("#screen").classList.add("screenOn");
document.querySelector("#screen").addEventListener("animationend", function(){
document.querySelector("#screen").classList.remove("screenOn");
document.querySelector("#screen").removeEventListener("animationed", null);
screen.remove();
},false);
}
the method obtain a token (number) then I add a div element called screen to the body and add the class screenOff, this starts the animation of the div to turn black. Then with the event listener I expect that when the screen is balck the method loadScreen do the changes, then I wanted that the class changes to screen on to turn the div from black to opacity 0 and in the end remove the div from screen.
All works except that the remove stops the second animation and without it the div will be there blocking the way, this method should be executed many times doing the same thing.
If there is a way to execute the method loadScreen inside in just one animation example:
0% {opacity: 0;}
50% {opacity: 1;}
----- run loadScreen() then -----
50% {opacity: 1; }
100% {opacity: 0;}
would be nice ...
I found a way to do it, using setinterval we can add and remove animations, I resolve my problem like this:
const screen = document.createElement('div'); //Const to add the load screen
screen.id = 'screen';
//Function that calls the loadScreen and loadFile methods and manages the
secuence of the screen changes.
function changeScreen(token){
let x = 0;
document.querySelector("#screen").classList.add("screenOff");
let intervalID = setInterval(function () {
if (x === 0) {
loadScreen(loadFile(token));
load.play();
document.querySelector("#screen").classList.remove("screenOff");
document.querySelector("#screen").classList.add("screenOn");
x++;
}else{
document.querySelector("#screen").classList.remove("screenOn");
window.clearInterval(intervalID);
}
}, 1400);
}
I'm using the javascript below to display a hidden div on a button click:
<script>
function myFunction() {
var x = document.getElementById("mydiv");
if (x.style.display === "none") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
</script>
How do I make the div fade or "fly" in when I click the button? I thought I could use a webkit transition, but can't seem to make it work.
You can use the .style.setProperty() method to add webkit transitions or any other CSS from javascript, like this:
var myDiv = document.getElementById('mydiv');
// example fade effect compatible with most browsers
myDiv.style.setProperty("transition", "opacity .2s ease-in-out");
myDiv.style.setProperty("-moz-transition", "opacity .2s ease-in-out");
myDiv.style.setProperty("-webkit-transition", "opacity .2s ease-in-out");
more on .style.setProperty(): https://developer.mozilla.org/setProperty.
Edit: #RokoC.Buljan pointed out a possible better solution, simply use the .style['-vendor-prop'] = 'val' syntax like this:
myDiv.style['-moz-transition'] = 'opacity .25s ease-in-out';
The display property is not an animatable css property.
You need to use a property from the following list to animate anything in css:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
I am triggering CSS3 Keyframes with javascript but its working for with first call after that any call to that function doesn't animate my div.
Here the Javascript code
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s"
//shareTools.style.animationPlayState = "running";
}
Sample of the issue (Click red box to preview)
var box = document.getElementById("box");
function animateBox(){
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
JSFIDDLE
I want it to animate everytime i call this function.
You can use well known hack: destroy and create element to reset animation.
var box = document.getElementById("box");
function animateBox(){
//destroy and create hack
document.body.removeChild(box);
document.body.appendChild(box);
box.style.animation = "box 1s ease-in-out 0s";
}
#box{
background:red;
width:100px;
height:100px;
}
#keyframes box {
50%{width:300px;}
}
<div id='box' onclick='animateBox()'><div>
In case someone is still interested by this there is another trick that works:
Changing the dataset value to something it has never been, and then use a css matching on that data.
I used this technique when animating the collapsing/uncollapsing of a menu, which of course can happen multiple times. Here's how I did it:
#menu[data-closed^="1"]{
animation:menu_closing;
}
#menu[data-closed^="0"]{
animation:menu_opening;
}
So the animation is based on the first character of the dataset (1 or 0).
Then in the click event that wants to close/open the menu:
var closed = menu_ele.dataset.closed // closed right now
? parseInt( menu_ele.dataset.closed.substr(0,1) )
: 0; // assuming menu is initialized open
var counter = menu_ele.dataset.closed // nb of times the menu was closed or open
? parseInt( menu_ele.dataset.closed.substr(1) )
: 0;
menu_ele.dataset.closed = ''+(1-closed)+(counter+1);
This way the "closed" dataset variable changes like this at every click:
11 (closing for the first time)
02 (reopening for the first time)
13
04
15
06
...
The first digit indicates whether it is currently closed, while all the rest is a counter to make the value new every time.
Think about your code - after first call it does nothing, becouse it already changed animation property of that element.
According to this CSS-Tricks article:
function animateShare (imgSrc){
var share = document.getElementById("shareTools");
share.style.animation = "testAnimate 1s ease-in-out 0s";
shareTools.style.animationPlayState = "paused";
shareTools.style.animationPlayState = "running";
}
add this code in the body section after the element for which the animation is being played-
<script>
document.getElementById('shareTools').addEventListener("animationend", function () {
this.removeAttribute("style");
})
</script>
or if you dont want to remove style attribute ,because you have other css than animation then create a class and add class dynimacally and remove it as above code.
You can reset the animation by just removing the animation property from the styles of the element after the animation has complete - removing the element is unnecessary. In my example, I set the duration in JS, but you could just as easily add an animationend hook to keep it simpler.
JSFiddle
var duration = 1000;
document.getElementById('box').addEventListener('click', function onClick(ev) {
var el = this;
el.style.animation = 'box ' + (duration / 1000 + 's') + ' ease-in-out';
setTimeout(function() {
el.style.animation = ''
}, duration);
});
#box {
background: red;
width: 100px;
height: 100px;
}
#keyframes box {
50% {
width: 300px;
}
}
<div id='box'><div>
I'm new to html and javascript. Some days back someone provided me with javascript which basically opens a hidden DIV and when other DIV is opened, the first DIV which was opened will close automatically. But now I'm having another problem which does not allow me to have a transition effect. I want a transition within this code. Please help!!!
Here is the JAVASCRIPT:
var divs = ["div1", "div2", "div3", "div4", "div5", "div6", "div7", "div8"];
var visibleDivId = null;
function toggleVisibility(divId) {
if (visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for (i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if (visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
And the HTML goes something like this:
<div id="div1" onClick="toggleVisibility('div1');return false;">
<div id="div2" onClick="toggleVisibility('div2');return false;">
and so on.
I have tried every possible way I could find, but there is no perfect way of achieving the effect. I want the div to be hidden and when the navigation is clicked, the div should open with its contents inside with a transition. Thank you :)
Try using CSS transitions. For example, this will give your divs a transition from collapsed to open over two seconds:
#div1 {
transition: height 2s;
-moz-transition: height 2s; /* Firefox 4 */
-webkit-transition: height 2s; /* Safari and Chrome */
-o-transition: height 2s; /* Opera */
}
I don't know JavaScript, but you will use it to hide the div by default, then on hover or click or whichever action you decide, have it display/hide the divs relative to their respective statuses.
As TylerH noted in the comments, the best way is to use CSS transition:
#mydiv { transition: opacity 2s; }
.hidden { opacity: 0; }
the role of the javascript could be just toggle the class .hidden on the element you want to hide:
document.getElementById("mydiv").classList.toggle("hidden");
See working example on the fiddle
You can't achieve it by setting the display property, since there is no transition between none and block. You can iterate through all the divs like you do in your hideNonVisibleDivs() and put it together with the fiddle code.
you can use Jquery animate
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> <--- this will add Jquery
$("div").onclick(function(){
$(this.attr("id")).fadeIn(1000); <--- this is the animation
});
or if you want you can use the animate function
https://api.jquery.com/animate/
My Jquery isn't working with the way I'm selecting the <p> and <img> elements. How could I get it to work?
function projectanim(x)
{
var Para = x.getElementsByTagName("p");
var Imgs = x.getElementsByTagName("img");
if ($(x).height() != 200)
{
$(x).animate({height:'200px'});
$(Para[0]).animate({display:'inline'});
$(Imgs[0]).animate({display:'inline'});
}
else
{
$(x).animate({height:'25px'});
$(Para[0]).animate({display:'none'});
$(Imgs[0]).animate({display:'none'});
}
}
Without the HTML this is just a shot in the dark but I assume you're trying to get the paragraph and image in a specific div?
Try this:
var Para = x.find("p");
var Imgs = x.find("img");
Although depending on what you're actually passing as x will determine whether it will actually work...
function projectanim (projectId) {
$('p, img', $('div#' + projectId)) // Select p/img tags children of <div id="projectId">
.slideDown(); // show using slideDown, fadeIn() or show('slow')
}
// Example
projectanim ('protflolio_project');
The idea with jQuery is:
Use the right selectors
With the right methods
Examples
Different ways to select all img and p tags under a div which id is my_div:
// The easy way
p_and_img = $('#my_div p, #my_div img');
// Using the context parameter
p_and_img = $('p, img', $('#my_div'));
// Using the context parameter and making sure my_div is a div
p_and_img = $('p, img', $('div#my_div'));
// only the first p and img
p_and_img = $('p:eq(0), img:eq(0)', $('#my_div'));
Your question is really, really vague, but from what I can gather, this is what you're looking at achieving:
function projectanim(x) {
var self = $(x);
if (self.height() === 200) {
self.animate({ height : '25px' })
.find('p,img').fadeOut()
;
} else {
self.animate({ height : '200px' })
.find('p,img').fadeIn()
;
}
}
That being said though, barring browser compatibility and all that shizz, you really should be doing something like this using CSS more than Javascript.
Depending on your parent element (say, a <div>), you can write up CSS like the following:
div {
height : 200px;
transition : height .5s linear;
}
div.active {
height : 25px;
}
div img,
div p {
display : inline;
opacity : 100;
transition : opacity .5s linear;
}
div.active img,
div.active p {
opacity : 0;
}
and just toggle a class on/off with your Javascript:
function projectanim(x) {
$(x).toggleClass('active');
}
and everything should be automatic. Your Javascript becomes waaaaaay simpler, less coupled, more maintainable, and your styles are right where they should be (in CSS files).
"what i'm trying to do is fade the and to inline from none."
Do you just want and to fade in? Or do you want it to go from display:none to inline and fade in?
I'll show you how to do both, and you can take away parts if you just want the fade in feature.
First off set p, and img as display:none; and opacity:0, in the css like so
p, img
{
display:none;
opacity:0;
}
Secondly your js has to alter the display of both , and tags and fade in/out like so.
function projectanim(x)
{
if ($(x).height() != 200)
{
$(x).animate({height:'200px'});
document.getElementsByTagName("p").style.display = 'inline';
document.getElementsByTagName("img").style.display = 'inline';
$("p").animate({"opacity": "1"}, 1000);
$("img").animate({"opacity": "1"}, 1000);
}
else
{
$(x).animate({height:'25px'});
$("p").animate({"opacity": "0"}, 500);
$("img").animate({"opacity": "0"}, 500);
document.getElementsByTagName("p").style.display = 'none';
document.getElementsByTagName("img").style.display = 'none';
}
}