How to change the opacity on an element dynamically using javascript - javascript

i made a function that change the opacity of an element, but you know it is not working, Following is my code:
function _opacity(ele, opacity,addOpac , delay ){
ele = document.getElementById(ele);
var CurrentOpacity = ele.style.opacity,
ChangeInOpacity = setInterval(function(){
if (CurrentOpacity > opacity ) { decrease();};
if (CurrentOpacity < opacity) { increase();};
if (CurrentOpacity == opacity) { stopInc();};
}, delay),
increase = function(){
ele.style.opacity = CurrentOpacity;
CurrentOpacity = CurrentOpacity+addOpac;
},
decrease =function(){
ele.style.opacity = CurrentOpacity;
CurrentOpacity = CurrentOpacity-addOpac;
},
stopInc = function(){
clearInterval(ChangeInOpacity);
};
}
one of the foremost feature of this function is that is doesn't uses any loop.
this ideology of using setInterval works perfectly in changing the width and height of element. But here this function is not functioning.
What i know is that it is not adding any style attribute to the element which is passed to the above function
what is the mistake here because of which this is not working?
thanks in advance.

There are a few problems there:
To get the current opacity of the element, you need to use the getComputedStyle function (or currentStyle property on oldIE), not .style.opacity. The latter only has a value if it's been assigned explicitly, rather than implicitly through style sheets.
The value will be a string, so you need to convert it to a number.
It's unlikely that you'll exactly match the target opaccity, so you need to just stop when you cross the target.
You don't put ; at the end of if statements, so remove those.
You assign the opacity, but then increment it, and then later the incremented value is what you check to see if you're done, so even if it weren't for #3, you'd stop early.
In JavaScript, the overwhelming convention is to start local variable names with a lower-case letter. I changed the name of your timer handle to timer.
Your best bet is to figure out what direction you're going, then stop when you pass the target:
// Polyfill getComputedStyle for old IE
if (!window.getComputedStyle) {
window.getComputedStyle = function(element) {
return element.currentStyle;
}
}
// Your _opacity function
function _opacity(ele, opacity, addOpac, delay) {
var direction;
ele = document.getElementById(ele);
// Determine direction
direction = +getComputedStyle(ele).opacity < opacity ? 1 : -1;
var timer = setInterval(function() {
// Get the *computed* opacity
var current = +getComputedStyle(ele).opacity;
if (direction > 0) {
if (current < opacity) {
increase(current);
} else {
stopInc();
}
}
else {
if (current > opacity) {
decrease(current);
} else {
stopInc();
}
}
}, delay),
increase = function(current) {
// Increase, but don't go past target
ele.style.opacity = Math.min(current + addOpac, opacity);
},
decrease = function(current) {
// Decrease, but don't go past target
ele.style.opacity = Math.max(current - addOpac, opacity);
},
stopInc = function() {
clearInterval(timer);
};
};
// Run
_opacity("target", 0.3, 0.05, 50);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<div id="target">this is the element</div>

you can do this:
ele.style.opacity = "0.2";// some desired value but string if for all browsers.
for more info see this post:Setting opacity of html elements in different browsers

Related

If/Else jQuery is breaking my script

I am trying to set-up an if/else statement that if a class exists then the var num will equal 100, if the class does not exist then var num will equal 55. num is then used to understand how many pixels the screen will be offset. Any help will be appreciated as Javascript is one of my weak points.
// Add scrollspy to <body>
$('body').scrollspy({target: ".navbar", offset: 55});
// Checks to see if navbar is affixed or not
if (($(".affix-top")[0]){) {
num = 100;
} else {
num = 55;
}
// Add smooth scrolling on all links inside the navbar
$(".navbar-lower a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (300) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top - num
}, 300, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
This is difficult to read.
if (($(".affix-top")[0]){) {
num = 100;
} else {
num = 55;
}
It can be simplified to just this, because anything matched is true.
var num = $(".affix-top").length ? 100 : 55;
That will not work if the script runs before the rest of the HTML page has loaded.
<script type="application/javascript"> $(".affix-top").length > 0; // false </script>
<div class="affix-top"></div>
<script type="application/javascript"> $(".affix-top").length > 0; // true </script>
So wrap everything in a jQuery ready block.
jQuery(document).ready(function(){
var num = $(".affix-top").length ? 100 : 55;
//....... insert more code here
});
You dont need the extra brackets. Also, just check .length to see if an element exists. It's subjective but IMO it makes it easier to read.
if ( $(".affix-top").length ) {
num = 100;
} else {
num = 55;
}
You have a { where it doesn't belong
if (($(".affix-top")[0]){) {
should be
if (($(".affix-top")[0])) {

javascript, div blinking instead of fading

I'm making a site that has an area that it's content disappear and re-appears. So when the user clicks certain button, the <div>'s content fades out and fades in the content relative to the clicked icon.
First time the function getabout is clicked it works OK, but whenever I click on clear() and then again on getabout it starts blinking. I've discovered that it does the clean to the div but it happens that the content re-appears again from nothing and becomes intermittent.
Here is my JavaScript code, it's commented so you could give me a hand here:
var check = null; //this will be checking the instance of div's content
const wait_time = 50; //the time it will take to fade
function getabout(id) {
/* prevent second call to the same function to bug */
if (check == id) return;
var titleOpacity = 0,
textOpacity = 0;
/* this changes the title first */
document.getElementById("title").style.opacity = 0;
document.getElementById("title").innerHTML = "this is the title";
// recursive call to the opacity changer, it
// increases opacity by 0.1 each time until it's 1
setInterval(function () {
titleOpacity = fadeIn(titleOpacity, 'title');
}, wait_time);
/* changes the content next to the title */
window.setTimeout(function () {
document.getElementById("dialog").style.opacity = 0;
document.getElementById("dialog").innerHTML = "this is the content";
setInterval(function () {
textOpacity = fadeIn(textOpacity, 'dialog');
}, wait_time);
}, 500);
check = id; // defines the instance "about" at the moment
}
function fadeIn(opacity, id) {
opacity += 0.1;
document.getElementById(id).style.opacity = opacity;
document.getElementById(id).style.MozOpacity = opacity;
if (opacity >= 1.0) clearInterval(listener);
return opacity;
}
function clear() {
var opacity = document.getElementById("title").style.opacity;
// supposed to decrease the opacity by 0.1 but it's not doing that
setInterval(function () {
opacity = fadeout(opacity);
}, wait_time);
//cleans the title and dialog to fill with the next button user clicked
document.getElementById("title").innerHTML = "";
document.getElementById("dialog").innerHTML = "";
}
function fadeout(opacity) {
opacity -= 0.1;
document.getElementById("title").style.opacity = opacity;
document.getElementById("dialog").style.MozOpacity = opacity;
if (opacity <= 0.0) clearInterval(listener);
return opacity;
}
function getregister(id) {
if (check == id) return;
clear(); // proceed to fade out the content and clean it
check = id;
}
I don't understand what is the error of the code. with the clear() function it should smoothly fade out the content and then clean it. But it just cleans the div. And next time I use getabout() function, instead of smoothly fade in again as it does the first time, it starts to blink.
I'm relatively new to web programming and I refuse JQuery for now. I want to understand deeply javascript before go to JQuery and this is why I would just like to know pure JavaScript solutions and considerations about this.
Ive managed to cock up my comment so trying again!
I think your problem is that you're not clearing the setInterval correctly - ensure you use listener = setInterval(...)
As it stands your clearInterval(listener); is doing nothing as 'listener' is not defined. So your fade out function continues to run.

Animating long sequences in jQuery

I have to make a long animation with jQuery, full of fadeOuts,fadeIns,slideIns,...
The problem I am having is that my code looks ugly and it is full of callback. Also, if I want to stop animation for some time like: slideOut->wait 5 seconds->slideIn I have to use delay and I am not sure if that is the best practice.
Example:
/* Slides */
var slide1 = $('div#slide1'),
slide2 = $('div#slide2'),
slide3 = $('div#slide3');
$(document).ready(function(){
slide1.fadeIn(function(){
slide2.fadeIn(function(){
slide3.fadeIn().delay(3000).fadeOut(function(){
slide2.fadeOut(function(){
slide1.fadeOut();
});
});
});
});
});
JSFIddle: http://jsfiddle.net/ZPvrD/6/
Question: Is there any other way of building animations in jQuery, possibly even some great plugin to help me solve this problem?
Thanks!
Here's the plugin you were looking for :) Does the exact same thing, but is much more flexible than your existing code http://jsfiddle.net/ZPvrD/11/
(function($){
$.fn.fadeInOut = function(middleDelay) {
middleDelay = middleDelay || 0;
var index = 0,
direction = 1, // 1: fading in; -1: fading out
me = this,
size = me.size();
function nextAnimation() {
// Before the first element, we're done
if (index === -1 ) { return; }
var currentEl = $(me.get(index)),
goingForward = direction === 1,
isLastElement = index === (size - 1);
// Change direction for the next animation, don't update index
// since next frame will fade the same element out
if (isLastElement && goingForward) {
direction = -1;
} else {
index += direction;
}
// At the last element, before starting to fade out, add a delay
if ( isLastElement && !goingForward) {
currentEl.delay(middleDelay);
}
if (goingForward) {
currentEl.fadeIn(nextAnimation);
} else {
currentEl.fadeOut(nextAnimation);
}
}
nextAnimation();
return this;
}
})(jQuery);
And you call it like
$('div.slideWrapper>div.slide').fadeInOut(3000);
This process of traversing up and down a list of jQuery elements waiting for each animation to finish could be abstracted so that it could be used for other things besides fadeIn and fadeOut. I'll leave that for you to try out if you feel adventurous.
Try this:
/* Slides */
var slide = $('div[id*="slide"]');
$( function(){
slide.each( function( k ){
$( this ).delay( 500 * k ).fadeIn();
});
});
JQuery animations take two parameters (maximum), duration and complete, duration is the time in milliseconds for how long you want your animation to complete, or you can use "slow" or "fast", and the second params complete which is the callback function.
If don't want to use delay, you may make the previous animation slow.
e.g.
slide1.fadeIn(5000, function(){
slide2.fadeIn();
};

Difficulty with setInterval loop using class of Divs

$(document).ready(function fadeIt() {
$("#cool_content > div").hide();
var sizeLoop = $("#cool_content > div").length;
var startLoop = 0;
$("#cool_content > div").first().eq(startLoop).fadeIn(500);
setInterval(function () {
$("#cool_content > div").eq(startLoop).fadeOut(1000);
if (startLoop == sizeLoop) {
startLoop = 0
} else {
startLoop++;
}
$("#cool_content > div").eq(startLoop).fadeIn(1500);
}, 2000);
});
Here I want a class of divs to animate, infinitely!
However, because the interval is set to two seconds there is period where no div is showing!
What would be an appropriate way to loop the animation of these divs?
I thought about using a for loop but couldn't figure out how to pass a class of divs as arguments. All your help is appreciated.
Thanks!
Ok, generally, you should know that Javascript is a single threaded environment. Along with this, the timer events are generally not on time accurately. I'm not sure how jQuery is doing fadeIn and fadeOut, but if it's not using CSS3 transitions, it's going to be using timeOut and Intervals. So basically, there's a lot of timer's going on.
If you go with the for loop on this one, you'd be blocking the single thread, so that's not the way to go forward. You'd have to do the fade in/out by yourself in the setInterval.
Setting the opacity on each interval call. Like div.css('opacity', (opacity -= 10) + '%')
If you're trying to fade in and out sequentially, I think maybe this code would help
var opacity = 100,
isFadingIn = false;
window.setInterval(function() {
if (isFadingIn) {
opacity += 10;
if (opacity === 100) isFadingIn = false;
} else {
opacity -= 10;
if (opacity === 0) isFadingIn = true;
}
$('#coolContent > div').css('opacity', opacity + '%');
}, 2000);
Consider the following JavaScript / jQuery:
$(function(){
var divs = $('#cool_content > div').hide();
var curDiv;
var counter = 0;
var doUpdate = function(){
// Hide any old div
if (curDiv)
curDiv.fadeOut(1000);
// Show the new div
curDiv = divs.eq(counter);
curDiv.fadeIn(1000);
// Increment the counter
counter = ++counter % divs.length;
};
doUpdate();
setInterval(doUpdate, 2000);
});
This loops infinitely through the divs. It's also more efficient than your code because it only queries the DOM for the list of divs once.
Update: Forked fiddle
instead of
if (startLoop == sizeLoop)
{
startLoop = 0
}
else
{
startLoop++;
}
use
startLoop =(startLoop+1)%sizeLoop;
Check the demo http://jsfiddle.net/JvdU9/ - 1st div is being animated just immediately after 4th disappears.
UPD:
Not sure I've undestood your question, but I'll try to answer :)
It doesn't matter how many divs you are being looped - 4, 5 or 10, since number of frames are being calculated automatically
x=(x+1)%n means that x will never be greater than n-1: x>=0 and x<n.
x=(x+1)%n is just shorten equivalent for
if(x<n-1)
x++;
else
x=0;
as for me first variant is much readable:)
And sorry, I gave you last time wrong demo. Correct one - http://jsfiddle.net/JvdU9/2/

Javascript: IE Error, Firebug not erring. Where is it?

Again, I am working with code from my predecessor and am at a loss for this one. It appears to be a sampled navigation script. It is receiving an error in IE stating Object doesn't support this property or method. Here is what I have narrowed the error down to.
The function:
/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
*
* #param f onMouseOver function || An object with configuration options
* #param g onMouseOut function || Nothing (use configuration options object)
* #author Brian Cherne <brian#cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};
cfg=$.extend(cfg,g?{over:f,out:g}:f);
var cX,cY,pX,pY;
var track=function(ev){cX=ev.pageX;
cY=ev.pageY;
};
var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);
ob.hoverIntent_s=1;
return cfg.over.apply(ob,[ev]);
}else{pX=cX;
pY=cY;
ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);
},cfg.interval);
}};
var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s=0;
return cfg.out.apply(ob,[ev]);
};
var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;
while(p&&p!=this){try{p=p.parentNode;
}catch(e){p=this;
}}if(p==this){return false;
}var ev=jQuery.extend({},e);
var ob=this;
if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
}if(e.type=="mouseover"){pX=ev.pageX;
pY=ev.pageY;
$(ob).bind("mousemove",track);
if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);
},cfg.interval);
}}else{$(ob).unbind("mousemove",track);
if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);
},cfg.timeout);
}}};
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
The document.ready line triggering the error:
var config = {
sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)
interval: 50, // number = milliseconds for onMouseOver polling interval
over: megaHoverOver, // function = onMouseOver callback (REQUIRED)
timeout: 200, // number = milliseconds delay before onMouseOut
out: megaHoverOut // function = onMouseOut callback (REQUIRED)
};
$("ul#topnav li .sub").css({'opacity':'0'});
$("ul#topnav li").hoverIntent(config);
I am at a loss as to how to resolve this and finally get this section fixed.
The two functions that are defined within document.ready.
function megaHoverOver(){
$(this).find(".sub").stop().fadeTo('fast', 1).show();
//Calculate width of all ul's
(function($) {
jQuery.fn.calcSubWidth = function() {
rowWidth = 0;
//Calculate row
$(this).find("ul").each(function() {
rowWidth += $(this).width();
});
};
})(jQuery);
if ( $(this).find(".row").length > 0 ) { //If row exists...
var biggestRow = 0;
//Calculate each row
$(this).find(".row").each(function() {
$(this).calcSubWidth();
//Find biggest row
if(rowWidth > biggestRow) {
biggestRow = rowWidth;
}
});
//Set width
$(this).find(".sub").css({'width' :biggestRow});
$(this).find(".row:last").css({'margin':'0'});
} else { //If row does not exist...
$(this).calcSubWidth();
//Set Width
$(this).find(".sub").css({'width' : rowWidth});
}
}
function megaHoverOut(){
$(this).find(".sub").stop().fadeTo('fast', 0, function() {
$(this).hide();
});
}
I'm able to run that code without errors (see http://jsfiddle.net/veHEY/). It looks like the issue might be in the megaHoverOver and megaHoverOut functions that you're passing in through the configuration object. Do you have the code for those functions?
Previously:
The problem is almost certainly
opacity, which is not supported in
IE. Check out this nice quirksmode
article on cross-browser opacity
issues.
Correction: As #patrick rightly points out, and backs up with a source code reference to boot, jQuery is smart enough to automatically deal with IE's own special brands of opacity handling. Whatever the OP's problem is, this is not the answer.

Categories