How to hide elements (with smooth transition) by class with javascript? - javascript

I have a group of divs that share the same class (optionsclass). The display is set to block. When a user clicks them the following javascript function is executed the display is changed to none.
function hideBlockElementsByClass(className)
{
var elements = document.getElementsByClassName(className);
for(i in elements)
{
elements[i].style.display = "none";
}
}
The transition between display block and none is quite rough and I would like to make a smoother transition. What's the best strategy to accomplish this?

Use CSS3 :
.className {
opacity: 0;
visibility: hidden;
-webkit-transition: visibility 0.2s linear,
opacity 0.2s linear;
-moz-transition: visibility 0.2s linear,
opacity 0.2s linear;
-o-transition: visibility 0.2s linear,
opacity 0.2s linear;
}
.className:hover {
visibility: visible;
opacity: 1;
}

While Sridhar gives a nice CSS3 solution and other mention Jquery.
Here you can find a pure javascript/CSS solution:
https://codereview.stackexchange.com/questions/7315/fade-in-and-fade-out-in-pure-javascript

Try this method
HTML
<div class = "image" onclick = "eff()"></div>
CSS
.transition {
-moz-transition: 2s width;
width: 150px;
height: 100px;
}
Script
function eff() {
var k = document.getElementsByClassName("image");
k[0].className = "transition";
}

try this in plain javascript:(Will work on IE10, chrome, firefox, safari, android, ios)
<script>
function hideBlockElementsByClass(className) {
var elements = document.getElementsByClassName(className);
console.log(elements.length)
for (var i = 0; i < elements.length; i++) {
(function (a) {
elements[a].addEventListener('webkitTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('mozTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('oTransitionEnd', function () {
elements[a].style.display = "none";
}, false);
elements[a].addEventListener('transitionend', function () {
elements[a].style.display = "none";
}, false);
})(i);
elements[i].style.webkitTransitionDuration = "1s";
elements[i].style.mozTransitionDuration = "1s";
elements[i].style.oTransitionDuration = "1s";
elements[i].style.transitionDuration = "1s";
elements[i].style.opacity = "0";
}
}
</script>

Related

Continuously changing the width of an element with setInterval( )

So I want to change the width of a span element inside a h1 element that have the textContent changed every 4s with setInterval().I want to do that to add a transition to the width property to fill the space between the h1 and the next word that span will have smoothly.
I tried to get the width of the span with getBoundingClientRect() but that didn't work and when I set the width it remains the width of the first element and it's not changed dynamically as I would want.
Here is the code:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.style.width = `${elementWidth}px`;
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
transition: width .2s ease;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
consider an animation using max-width:
const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
setInterval(function() {
count++;
if (count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown .8s ease;
}
#keyframes moveDown {
0% {
opacity: 0;
transform: translateY(-50%);
max-width:0;
}
100% {
transform: translateY(0);
max-width:200px; /* a big value here */
}
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>
Your code is very good.
But you need to remove 2 rows like below, then you code works well as you want
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
changingSpan.style.width = ${elementWidth}px;
So the answer was posted by Sean above(Thank you). I will put here the code snippet for this in case somebody will search for something similar and will want to do the same thing:
const changingSpan = document.querySelector('.changing-span');
const changingSpanWrapper = document.querySelector('.changing-span-wrapper');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;
changingSpanWrapper.style.width = `${changingSpan.getBoundingClientRect().width.toString()}px`;
setInterval(function() {
count++;
if(count === array.length) count = 0;
changingSpan.classList.add('animation-span');
changingSpan.textContent = array[count];
changingSpan.addEventListener('animationstart', function() {
let elementWidth = changingSpan.getBoundingClientRect().width.toString();
let elementHeight = changingSpan.getBoundingClientRect().height.toString();
changingSpanWrapper.style.width = `${elementWidth}px`;
changingSpanWrapper.style.height = `${elementHeight}px`;
})
changingSpan.addEventListener('animationend', function() {
changingSpan.classList.remove('animation-span');
})
}, 4000);
.changing-span-wrapper {
display: inline-block;
transition: width .2s ease, height .2s ease;
}
.changing-span {
display: inline-block;
color: #c82929;
}
.animation-span {
animation: moveDown 1s ease;
}
#keyframes moveDown {
0% {opacity: 0;
transform: translateY(-50%);
}
100% {
transform: translateY(0);
}
}
<h1 class="first-heading">The <span class="changing-span-wrapper"><span class="changing-span">best</span></span> burgers in town.</h1>

SetTimeout lags between calls in Firefox

I'm trying to optimize my code so that I can cycle through images on a splash page quickly and effectively. I've got it looking really smooth on chrome and safari but when I view the splash page on mobile and firefox it bugs out big time
A demo can be found at http://theotherchrisrock.com
I would love to hear your input on how to fix this. Here is the relevant code:
var i = 0
var j = 0
var l = $('.se-pre-con > div').length - 2;
var $pre_con = $('.se-pre-con');
var $di_sum = $('.splash-image:last-child');
var $img_array = [];
for (t = 0; t < l; t++) {
$img_array[t] = $('.splash-image-' + t);
}
function flashanimation() {
if (i < l) {
$img_array[i].addClass('flash');
i++;
flashloop();
} else if (j != 1) {
$di_sum.addClass('di-some');
j = 1
flashloop();
} else {
$pre_con.addClass('nun');
}
}
function flashloop() {
setTimeout(function() {
flashanimation();
}, 300)
}
$(".blinker").removeClass("blinker");
flashloop();
Basically, the goal is to make the image appear for 150ms and then disappear for 150ms and then next image appears and so on finally ending with just a black div. Right now I'm adding a class to each div which triggers this keyframe animation ~
.splash-image.flash {
-webkit-animation:flash 0.15s linear;
animation:flash 0.15s linear;
-webkit-animation-delay:0.15s;
animation-delay:0.15s;
display:block;
opacity:0;
}
#-webkit-keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
#keyframes flash {
0% {
opacity:0;
}
1% {
opacity: 1;
}
100% {
opacity:1;
}
}
I would love to hear your input. Thank u for reviewing my question

how to add transition animation to this DIV TOGGLE Hid/Show ?

I have this dive the toggle Hide / Show !! ... It works ok , but I would like to know how to add transition animation to the hide/show ?
this is my JS :
function myFunction() {
var x = document.getElementById("clock1");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none" ;
}
You cannot animate the display property. But you can animate the visibility or opacity property in css easily:
// main.html
<div id="clock1" class="hidden">...</div>
// main.css
#clock1 {
visibility: visible;
opacity: visible;
transition: visibility 0s, opacity 0.5s linear;
}
#clock1.hidden {
visibility: hidden;
opacity: 0;
}
// main.js
function myFunction() {
var x = document.getElementById("clock1")
if (x.classList.contains('hidden')) {
x.classList.remove('hidden')
} else {
x.classList.add('hidden')
}
}
Setting display to none will immediately hide the element, which means there is not opportunity for animation/transition of visibility over time.
Perhaps you could consider using opacity instead, to achieve this?
Add the following CSS:
#clock1 {
transition:opacity 1s;
}
Update your JS:
function myFunction() {
var x = document.getElementById("clock1");
// Update opacity rather than display
if (x.style.opacity === "0") {
x.style.opacity = 1;
} else {
x.style.opacity = 0;
}
}
Working jsFiddle here

How can I use clearInterval() or some other method to make my fade background script in javascript that uses setInterval() stop?

I have a nested closure function that is looping and fading my background color based on assignments in the array. On the button with the onclick "stopFadeColors()" method I started, how can I actually stop the script from running by clicking the second button?
<style>
.black {
-moz-transition: all .2s ease-in;
-o-transition: all .2s ease-in;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
background: #000;
}
.white {
-moz-transition: all .2s ease-in;
-o-transition: all .2s ease-in;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
background: #fff;
}
</style>
<script>
//make the element start blinking at a rate of once per second.
function fadeColors(target) {
var elem = document.body; //assign the object to a shorter named object
var toggleColor = ["black", "white"]; // setup color list, it can be more than two
var counter = 0; //outer counter
var nextColor; //outerClass
function changeBackgroundColor() {
console.log(counter); // output count
counter = (counter + 1) % toggleColor.length; //modulus of counter divided by counter length
nextColor = toggleColor[counter]; //update the class
elem.className = nextColor; //assign the class
}
setInterval(changeBackgroundColor, 1000); //call our function
}
</script>
<button onclick="fadeColors()">Fade Background</button>
<!-- how can i make this next button call a new or existing method and pause the script with clearInterval() or some other way? --//>
<button onclick="stopFadeColors()">Stop Fade Background</button>
You need to assign your setInterval() function to a variable:
function fadeColors(target) {
var elem = document.body; //assign the object to a shorter named object
var toggleColor = ["black", "white"]; // setup color list, it can be more than two
var counter = 0; //outer counter
var nextColor; //outerClass
function changeBackgroundColor() {
console.log(counter); // output count
counter = (counter + 1) % toggleColor.length; //modulus of counter divided by counter length
nextColor = toggleColor[counter]; //update the class
elem.className = nextColor; //assign the class
}
document['intervalTemp'] = setInterval(changeBackgroundColor, 1000); //call our function
}
HTML:
<button onclick="fadeColors();">Fade Background</button>
Other button onclick to stop:
<button onclick="clearInterval(document.intervalTemp);">Stop Fade Background</button>

How to get animate divs based on an array to appear one at a time with maybe CSS3 only?

Assume I have the following array:
var myarray = [1, 2, 3, 4, 5]
What is the cleanest way using Javascript/CSS3 to make it such that onpage load, each element in the array is shown in a box/div with a red background color on the page? Usually I would just do:
for(var i = 0; i < myarray.length; i++) {
bodyelement.append("<div class="box">"+myarray[i]+"</div>");
}
The issue is, it is super fast and they all just show up instantaneously without any real "effect".
Though how do I make them "sequentially" animate in as it is appended? Say, for example, the box would animate say from a overly big box and shrink down to the size of the actual div, or fade in gradually. Can this be done with CSS3 only or is there javascript required? How can I create this effect?
Here is an example of what I described in the comments. JSFIDDLE.
Basically you use css transitions, and add a class to each element after a certain period of time.
(function() {
var elements = document.querySelectorAll("#test div");
for (var i = 0; i < elements.length; i++) {
load(elements[i], i);
}
function load(elem, i) {
setTimeout(function() {
elem.classList.add("load");
},50 * i);
}
}());
CSS
#test div {
-webkit-transition: opacity 2s ease-in;
-moz-transition: opacity 2s ease-in;
-ms-transition: opacity 2s ease-in;
-o-transition: opacity 2s ease-in;
transition: opacity 2s ease-in;
}
#test div.load {
opacity: 1;
}
This FIDDLE may get you started.
JS
var fadeintime = 500;
animatediv();
function animatediv()
{
var number = 0;
var interval = setInterval(function() {
var divid = $("#div" + number);
divid.animate({opacity: "1"}, fadeintime);
number++;
if(number > 4) clearInterval(interval);
}, 1000);
}
Based on THIS.

Categories

Resources