pure javascript - creating my own fadeout function [duplicate] - javascript

This question already has answers here:
How to add my own methods to HTMLElement object?
(5 answers)
Closed 4 years ago.
I'm trying to create a similar function to the jquery .fadeOut() effect in pure javascript, but I'm having trouble with my code. The error code:
span[0].fadeOutEffect is not a function
My code:
var span = document.querySelectorAll("span");
function fadeOutEffect() {
var node = this
var fadeEffect = setInterval(function() {
if (!node.style.opacity) {
node.style.opacity = 1;
}
if (node.style.opacity > 0) {
node.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 50);
}
span[0].fadeOutEffect();
<span>one </span><span>two </span><span>three </span>

When I read your code, I see you likely want to add a function to the HTMLElement prototype - it is not recommended but it will look like this:
HTMLElement.prototype.fadeOutEffect = function() {
var node = this
var fadeEffect = setInterval(function() {
if (!node.style.opacity) {
node.style.opacity = 1;
}
if (node.style.opacity > 0) {
node.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 50);
}
var span = document.querySelectorAll("span");
span[0].fadeOutEffect();
<span>one </span><span>two </span><span>three </span>
A cleaner way is passing the span:
var fadeOutEffect = function(node) {
var fadeEffect = setInterval(function() {
if (!node.style.opacity) {
node.style.opacity = 1;
}
if (node.style.opacity > 0) {
node.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 50);
}
var span = document.querySelectorAll("span");
fadeOutEffect(span[0]);
<span>one </span><span>two </span><span>three </span>

You are trying to add a function as a property to the array of span elements. You should instead pass it as a parameter to the function you created. Also, document.querySelectorAll("span"); returns an array of spans, as there can be multiple in your HTML document, so you can loop through each and apply you code to them.
See working example:
function fadeOutEffect(nodes) {
nodes.forEach(function(node) { // Loop through each node (each span) in the array of spans
var fadeEffect = setInterval(function() { // Run your code
if (!node.style.opacity) {
node.style.opacity = 1;
}
if (node.style.opacity > 0) {
node.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 50);
});
}
var nodes = document.querySelectorAll("span"); // Nodes is an array of spans
fadeOutEffect(nodes); // Pass the array of spans to your function
<span>Hello world!</span>

Your code is attempting to call a function, on a DOM element, which doesn't exist. Try passing the element as a parameter to your function instead.
var span = document.querySelectorAll("span");
function fadeOutEffect(node) {
var fadeEffect = setInterval(function() {
if (!node.style.opacity) {
node.style.opacity = 1;
}
if (node.style.opacity > 0) {
node.style.opacity -= 0.1;
} else {
clearInterval(fadeEffect);
}
}, 50);
}
fadeOutEffect(span[0]);
<span>one </span><span>two </span><span>three </span>

Related

Javascript animation for fadein value does not change

I was trying to make a fade in animation in pure javascript, and I encounter a problem. The opacity does not moove when I make the += 0.1, and I don't know why.
function fadeInEffect() {
var fadeTarget = document.getElementById("target");
var fadeEffect = setInterval(function() {
if (!fadeTarget.style.opacity) {
fadeTarget.style.opacity = 0;
}
if (fadeTarget.style.opacity < 1) {
fadeTarget.style.opacity += 0.1;
} else {
clearInterval(fadeEffect);
}
}, 100);
}
Explicity cast the opacity before you attempt your addition or else it will by default handle the variable type as a string and do a replace instead. Sometimes interpretive languages act a bit inconsistent with auto-type casting so you have to take manual control.
function fadeInEffect() {
var fadeTarget = document.getElementById("target");
var fadeEffect = setInterval(function() {
if (!fadeTarget.style.opacity) {
fadeTarget.style.opacity = 0;
}
if (fadeTarget.style.opacity < 1) {
fadeTarget.style.opacity = parseFloat(fadeTarget.style.opacity) + 0.1;
} else {
clearInterval(fadeEffect);
}
}, 100);
}

Adding a image to an element

I'm making a element that is randomly appearing on the screen using javascript. What would I do in order to add an image using javascript to the randomly generated element?
function addEnemy() {
var interval = 0.1;
if (iterations > 1500) {
interval = 5;
} else if (iterations > 1000) {
interval = 3;
} else if (iterations > 500) {
interval = 1;
}
if (getRandom(50) == 0) {
var elementName = "enemy" + getRandom(10000000);
var enemy = createSprite(elementName, getRandom(450), -40, 45, 45);
var enemiesDiv = document.getElementById("enemiesDiv");
var element = document.createElement("div");
element.id = enemy.element;
element.className = "enemy";
enemiesDiv.appendChild(element);
enemies[enemies.length] = enemy;
element.enemy.innerHTML
}
}
You can create a new img element, give it the source to your image, then append that img element to your element you created. (I would suggest using a more descriptive variable name than just "element")
The relevant code could look like this:
var myImage = document.createElement('img');
myImage.src = 'my_image.jpg';
element.appendChild(myImage);
A little bit too broad, but I think you could consider using the background property of your created div. Something like this:
function addEnemy() {
var interval = 0.1;
if (iterations > 1500) {
interval = 5;
} else if (iterations > 1000) {
interval = 3;
} else if (iterations > 500) {
interval = 1;
}
if (getRandom(50) == 0) {
var elementName = "enemy" + getRandom(10000000);
var enemy = createSprite(elementName, getRandom(450), -40, 45, 45);
var enemiesDiv = document.getElementById("enemiesDiv");
var element = document.createElement("div");
element.id = enemy.element;
element.className = "enemy";
// Here
element.style.backgroundImage = "url('img_enemy.png')";
enemiesDiv.appendChild(element);
enemies[enemies.length] = enemy;
element.enemy.innerHTML
}
}

How to use setTimeout with a "do while" loop in Javascript?

I'm trying to make a 30 second countdown on a span element (#thirty) that will be started on click of another element (#start). It doesn't seem to work. I would appreciate your help.
var countdown = function() {
setTimeout(function() {
var i = 30;
do {
$("#thirty").text(i);
i--;
} while (i > 0);
}, 1000);
}
$("#start-timer").click(countdown());
use this :
var i = 30;
var countdown = function() {
var timeout_ = setInterval(function() {
$("#thirty").text(i);
i--;
if(i==0){
i = 30;
clearInterval(timeout_);
}
}, 1000);
}
$("#start-timer").click(countdown);

scope in angular and applied css class only on first div

I'm calling js function every 2 seconds where on certain condition I want to update div on the view.
<div id="ball_{{ballIndex}}">{{ball}}</div>
on ng controller
var myCounter = 0;
var interval = $interval(function () {
if (myCounter <= 35) {
myCounter ++;
DoSomething();
} else {
//
}
}, 1500);
function setCurrentBallEffect() {
$('#ball_' + myCounter).addClass('magictime puffIn');
}
function DoSomething() {
if (myCounter == 0) {
$scope.ballIndex = 1;
} else {
$scope.ballIndex = myCounter;
}
}
using this code only first div in iteration is applied with class magictime puffIn. When I hardcode div id's on the view side like <div id="ball_1">1</div> <div id="ball_2">2</div> .. applied css class work on each div. What I'm doing wrong?
Update:
Tried with
<div ng-attr-id="{{ 'ball_' + ballIndex }}"> </div>
but problem is still present.
At first you must define
var myCounter =0;
I don't understand ball
you must defined it like this :
$scope.ball=0;
I Change view like this
<div id="ball_{{ballIndex}}">{{ballIndex}}</div>
and your javascript changed like this:
var poolCounter = 0;
var myCounter = 0;
var interval = $interval(function () {
if (myCounter <= 35) {
myCounter++;
DoSomething();
} else {
//
}
}, 1500);
function setCurrentBallEffect() {
$('#ball_' + myCounter).addClass('magictime puffIn');
}
function DoSomething() {
if (myCounter == 0) {
$scope.ballIndex = 1;
} else {
$scope.ballIndex = myCounter;
}
}

Pure JavaScript fade in function

Hi friends i want to fade in a div when i click on another div and for that i am using following code. Code1 works fine but i require to use the Code2.
I know there is jQuery but i require to do this in JavaScript
Can you guide me that what kind of mistake i am doing or what i need change...
Code1 --- Works Fine
function starter() { fin(); }
function fin()
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout("seto(" + i + ")", i * 1000);
}
}
function seto(opa)
{
var ele = document.getElementById("div1");
ele.style.opacity = opa;
}
Code2 --- Does not work
function starter()
{
var ele = document.getElementById("div1");
fin(ele);
}
function fin(ele)
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout("seto(" + ele + "," + i + ")", i * 1000);
}
}
function seto(ele,opa)
{
ele.style.opacity = opa;
}
Based on this site
EDIT-1
Added the functionality so that user can specify the animation duration(#Marzian comment)
You can try this:
function fadeIn(el, time) {
el.style.opacity = 0;
var last = +new Date();
var tick = function() {
el.style.opacity = +el.style.opacity + (new Date() - last) / time;
last = +new Date();
if (+el.style.opacity < 1) {
(window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
}
};
tick();
}
var el = document.getElementById("div1");
fadeIn(el, 3000); //first argument is the element and second the animation duration in ms
DEMO
Update:
It seems that people enjoy my minimalistic and elegant approach, Updated for 2022:
No need for complex mechanisms. Just use CSS, which has it out of the box and has better performance overall.
Basically you achieve it with CSS by setting a transition for the opacity. In JavaScript that would be:
const div = document.querySelector('#my-div');
div.style.transition='opacity 1s';
and as a trigger you just set opacity to 0:
div.style.opacity=0;
This will create a 1 second fade out effect and you can use the trigger anywhere. The inverse can also be done to achieve a fade in effect.
Here's a working example:
const div = document.querySelector('#my-div');
div.style.transition='opacity 1s';
// set opacity to 0 -> fade out
setInterval(() => div.style.opacity=0, 1000);
// set opacity to 1 -> fade in
setInterval(() => div.style.opacity=1, 2000);
#my-div { background-color:#FF0000; width:100%; height:100%; padding: 10px; color: #FFF; }
<div id="my-div">Hello!</div>
Seems like your attempting to convert your element, to a string. Try this instead
function starter()
{
var ele = document.getElementById("div1");
fin(ele);
}
function fin(ele)
{
for (i = 0; i <= 1; i += 0.01)
{
i=Math.round(i*100)/100;
setTimeout(function() { setto(ele,i); }, i * 1000);
}
}
function seto(ele,opa)
{
ele.style.opacity = opa;
}
What happens here is, that i call a anonnymous function when the timer hits, and from that function, execute my functioncall to setto.
Hope it helps.
Jonas
The problem here is you are using the pass-a-string method of using setTimeout. Which is basically just a hidden eval.
It's worth noting that this is a bad practice, slow performer, and security risk.
(see questions such as this: setTimeout() with string or (anonymous) function reference? speedwise)
The reason this is causing your problem is because "seto(" + ele + "," + i + ")" is going to evaluate to "seto('[object HTMLDivElement]', 1)". You really want to pass reference to the ele object -- but the value's being cast to a string when you tried concatenating an object onto a string. You can get around this by using the pass-a-function method of using setTImeout.
setTimeout(function() { seto(ele, i); }, i * 1000);
I believe making this change will make your Code2 behavior equivalent to Code1.
Below are the complete answers to my question
ANS1 --- DEMO
function fin() {
var i = 0;
var el = document.getElementById("div1");
fadeIn(el,i);
}
function fadeIn(el,i) {
i = i + 0.01;
seto(el,i);
if (i<1){setTimeout(function(){fadeIn(el,i);}, 10);}
}
function seto(el,i) {
el.style.opacity = i;
}
ANS2 --- DEMO
function fin(){
var i = 0;
var el = document.getElementById("div1");
fadeIn(el,i);
}
function fadeIn(el,i) {
var go = function(i) {
setTimeout( function(){ seto(el,i); } , i * 1000);
};
for ( i = 0 ; i<=1 ; i = i + 0.01) go(i);
}
function seto(el,i)
{
el.style.opacity = i;
}
My version
function fadeIn($element){
$element.style.display="block";
$element.style.opacity=0;
recurseWithDelayUp($element,0,1);
}
function fadeOut($element){
$element.style.display="block";
$element.style.opacity=1;
recurseWithDelayDown($element,1,0);
}
function recurseWithDelayDown($element,startFrom,stopAt){
window.setTimeout(function(){
if(startFrom > stopAt ){
startFrom=startFrom - 0.1;
recurseWithDelayDown($element,startFrom,stopAt)
$element.style.opacity=startFrom;
}else{
$element.style.display="none"
}
},30);
}
function recurseWithDelayUp($element,startFrom,stopAt){
window.setTimeout(function(){
if(startFrom < stopAt ){
startFrom=startFrom + 0.1;
recurseWithDelayUp($element,startFrom,stopAt)
$element.style.opacity=startFrom;
}else{
$element.style.display="block"
}
},30);
}
function hide(fn){
var hideEle = document.getElementById('myElement');
hideEle.style.opacity = 1;
var fadeEffect = setInterval(function() {
if (hideEle.style.opacity < 0.1)
{
hideEle.style.display='none';
fn();
clearInterval(fadeEffect);
}
else
{
hideEle.style.opacity -= 0.1;
}
}, 20);
}
function show(){
var showEle = document.getElementById('myElement');
showEle.style.opacity = 0;
showEle.style.display='block';
var i = 0;
fadeIn(showEle,i);
function fadeIn(showEle,i) {
i = i + 0.05;
seto(showEle,i);
if (i<1){setTimeout(function(){fadeIn(showEle,i);}, 25);}
}
function seto(el,i)
{
el.style.opacity = i;
}
}
hide(show);
I just improved on laaposto's answer to include a callback.
I also added a fade_out function.
It could be made more efficient, but it works great for what i'm doing.
Look at laaposto's answer for implementation instructions.
You can replace the JS in his fiddle with mine and see the example.
Thanks laaposto!
This really helped out for my project that requires zero dependencies.
let el = document.getElementById( "div1" );
function fade_in( element, duration, callback = '' ) {
element.style.opacity = 0;
let last = +new Date();
let tick = function() {
element.style.opacity = +element.style.opacity + ( new Date() - last ) / duration;
last = +new Date();
if ( +element.style.opacity < 1 )
( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
else if ( callback !== '' )
callback();
};
tick();
}
function fade_out( element, duration, callback = '' ) {
element.style.opacity = 1;
let last = +new Date();
let tick = function() {
element.style.opacity = +element.style.opacity - ( new Date() - last ) / duration;
last = +new Date();
if ( +element.style.opacity > 0 )
( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
else if ( callback !== '' )
callback();
};
tick();
}
fade_out( el, 3000, function(){ fade_in( el, 3000 ) } );
Cheers!

Categories

Resources