how to make hide/show text javascript smoother? - javascript

I am using this script to hide and show text however, I want to make the transition smoother but I am not sure how to. Here's a demo of it: http://jsfiddle.net/LnE5U/.
Please help me change it to make it smoother.
hide/show text
<div id="showOrHideDiv" style="display: none">hidden text</div>
<script language="javascript">
function showOrHide()
{
var div = document.getElementById("showOrHideDiv");
if (div.style.display == "block")
{
div.style.display = "none";
}
else
{
div.style.display = "block";
}
}
</script>

Here is an example using jQuery's fadeToggle (a shortcut for a more complicated animate)
// assuming jQuery
$(function () { // on document ready
var div = $('#showOrHideDiv'); // cache <div>
$('#action').click(function () { // on click on the `<a>`
div.fadeToggle(1000); // toggle div visibility over 1 second
});
});
HTML
<a id="action" href="#">hide/show text</a>
<div id="showOrHideDiv" style="display: none;">hidden text</div>
DEMO
An example of a pure JavaScript fader. It looks complicated because I wrote it to support changing direction and duration mid-fade. I'm sure there are still improvements that could be made to it, though.
function generateFader(elem) {
var t = null, goal, current = 0, inProgress = 0;
if (!elem || elem.nodeType !== 1) throw new TypeError('Expecting input of Element');
function visible(e) {
var s = window.getComputedStyle(e);
return +!(s.display === 'none' || s.opacity === '0');
}
function fader(duration) {
var step, aStep, fn, thisID = ++current, vis = visible(elem);
window.clearTimeout(t);
if (inProgress) goal = 1 - goal; // reverse direction if there is one running
else goal = 1 - vis; // else decide direction
if (goal) { // make sure visibility settings correct if hidden
if (!vis) elem.style.opacity = '0';
elem.style.display = 'block';
}
step = goal - +window.getComputedStyle(elem).opacity;
step = 20 * step / duration; // calculate how much to change by every 20ms
if (step >= 0) { // prevent rounding issues
if (step < 0.0001) step = 0.0001;
} else if (step > -0.0001) step = -0.0001;
aStep = Math.abs(step); // cache
fn = function () {
// console.log(step, goal, thisID, current); // debug here
var o = +window.getComputedStyle(elem).opacity;
if (thisID !== current) return;
if (Math.abs(goal - o) < aStep) { // finished
elem.style.opacity = goal;
if (!goal) elem.style.display = 'none';
inProgress = 0;
return;
}
elem.style.opacity = (o + step).toFixed(5);
t = window.setTimeout(fn, 20);
}
inProgress = 1; // mark started
fn(); // start
}
return fader;
}
And using it
window.addEventListener( // this section matches the code above
'load',
function () {
var fader = generateFader(document.getElementById('showOrHideDiv'));
document.getElementById('action').addEventListener(
'click',
function () {
fader(1000);
}
);
}
);
DEMO of this

This is quite simple. I have just made a demo and i used setInterval
Here's how it works
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
}
}, 50);
};
JSFiddle Demo Link
Steps
Create a function that accepts a DOM element
Set the opacity of the element to 1
Create a function that loops every 50ms
If the opacity is greater than 0 -> continue
Take away 0.01 from the opacity
if it's less than 0 the animation is complete and hide it completely
Note this is a really simple example and will need a bit of work

You can use somthing like this
$('.showOrHideDiv').toggle(function() {
$('showOrHideDiv').fadeIn('slow', function() {
//fadeIn or fadeOut, slow or fast, all the stuffs you want to trigger, "a function to execute every odd time the element is clicked," says the [jquery doc][1]
});
}, function() {
//here comes "additional handlers to cycle through after clicks," says the [jquery doc][1]
});

I used OPACITY to make it show/hide. See this Example, Full code (without jQuery):
Click here
<div id="MyMesage" style="display:none; background-color:pink; margin:0 0 0 100px;width:200px;">
blablabla
</div>
<script>
function ShowDiv(name){
//duration of transition (1000 miliseconds equals 1 second)
var duration = 1000;
// how many times should it should be changed in delay duration
var AmountOfActions=100;
var diiv= document.getElementById(name);
diiv.style.opacity = '0'; diiv.style.display = 'block'; var counte=0;
setInterval(function(){counte ++;
if ( counte<AmountOfActions) { diiv.style.opacity = counte/AmountOfActions;}
},
duration / AmountOfActions);
}
</script>

I followed iConnor solution and works fine but it had a small issue setInterval will not stop after the element be hidden I added stop interval to make it better performance
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
let hidden_process = window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
console.log('1');
clearInterval(hidden_process);
}
}, 50);
};

Related

Run a setInterval function, stop it for 3 seconds and continue running it

I have a setInterval function going trough some div classes, if it finds a div with a particular class it should stop for 3 seconds and then continue running. Notice how I am using:
clearInterval(myInterval);
but I need something else, to start the sequence again or make it to continue running from there.
e.g:
var myInterval = setInterval(function() {
move.removeClass( "girlFromRight" );
runFromRight -= 9;
move = $("#grid"+ runFromRight);
move.addClass("girlFromRight");
if (move.hasClass("man") === true ||
move.hasClass("man-right") === true ||
move.hasClass("man-left") === true )
{
clearInterval(myInterval);
move.addClass('inLove');
move.removeClass('girlFromRight');
setTimeout(function() {
move.removeClass('inLove');
move.addClass('man');
}, 3000);
}
if (c == 9){
clearInterval(myInterval);
}
}, 300);
keyPressed = false;
}, randomTime);
}
Consider using setTimeout and setting the interval (300 or 3000) after each run based on a test. That way you don't have to start and stop setInterval.
A quick example is below, it highlights each div in sequence, pausing longer on any where the text content is evenly divisible by 3 (as an example test).
function doLoop(){
var divs = document.querySelectorAll('div');
var i = 0;
function loop(){
var selected = document.querySelectorAll('.selected');
[].forEach.call(selected,function(el) {
el.className = 'notSelected';
});
divs[i].className = 'selected';
setTimeout(loop, divs[i].textContent % 3? 300 : 3000);
i = ++i % (divs.length - 2);
}
loop();
}
window.onload = doLoop;
.notSelected{}
.selected{
background-color: blue;
}
<div class="notSelected">0</div>
<div class="notSelected">1</div>
<div class="notSelected">2</div>
<div class="notSelected">3</div>
<div class="notSelected">4</div>
<div class="notSelected">5</div>

How to add slide animation for an image with JavaScript

I am trying to make a responsive image gallery in vanilla JS, I have a function and I am passing the image source as its parameter, and every time I am only changing the source on the click of next or previous button. Here is the function:
this.open = function (src) {
if (!src) {
return false;
}
for (count = 0; count <= imgSrc.length; count++) {
if (imgSrc[count] == src)
break;
var tempSrc = imgSrc[count];
}
imgRatio = false; // clear old image ratio for proper resize-values
var img = document.createElement('img');
img.setAttribute('src', src);
// hide overflow by default / if set
if (!this.opt || !isset(this.opt.hideOverflow) || this.opt.hideOverflow) {
body.setAttribute('style', 'overflow: hidden');
}
this.box.setAttribute('style', 'padding-top: 0');
this.wrapper.innerHTML = '';
this.wrapper.appendChild(img);
// console.log(this.wrapper.innerHTML);
addClass(this.box, 'jslghtbx-active');
// already show wrapper due to bug where dimensions are not
// correct in IE8
if (isIE8) {
addClass(that.wrapper, 'jslghtbx-active');
}
imgText.innerHTML = Details.static_data.gallery[count][3];
var checkClassInt = setInterval(function () {
if (hasClass(that.box, 'jslghtbx-active') && img.complete) {
// wait few ms to get correct image-dimensions
setTimeout(function () {
that.resize();
// add active-class for all other browsers
setTimeout(function () {
addClass(that.wrapper, 'jslghtbx-active');
}, 10);
clearInterval(checkClassInt);
}, 40);
}
}, 10); };
Is there any way so that I can attach animate kind of attribute to the image to have a sliding kind of animation. Please suggest your valuable feedback. [ NOTE: I am using this script https://github.com/felixhagspiel/jsOnlyLightbox ]

Jquery - add function to jquery

Hey there i got this fiddle :
http://jsfiddle.net/5H5Xq/42/
containing this jquery:
function anim(selector) {
$(".images img", selector).first().appendTo($('.images', selector)).fadeOut(2000);
$(".images img", selector).first().fadeIn(2000);
}
// Untuk delay gambarnya
var i = 0, max = 3;
myFunction = function(event){
$(".subbox1").each(function() {anim(this)});
i += 1;
if(i >= max) { i = 0; }
}
var interval = setInterval(myFunction, 5000);
$(".slider").hover(function() {
clearInterval(interval);
var img = $('<img>');
img.attr('src', $(this).attr('data-url'));
$('#newImage').html(img);
$('.images').hide();
return false;
i += 1;
$(".subbox1").each(function() {anim(this)});
});
$(".slider").mouseout(
function (){
$('.images').show();
// $('#newImage').hide();
interval = setInterval(myFunction, 5000);
}
);
It just means:
Every 5 seconds => automatic image-change.
When i hover throw a link => image-change + automatic image change disabled.
What i wanted to add to the automatic image-change:
Depending on the current picture, the -item gets a new background-color..is this possible?
greetings
Sure you can. Just change the background-color css attribute of the element depending on your criteria.
if (*your criteria here*) {
element.css("background-color", "#ff0000");
}

Javascript "For" Loop not working?

I have a Javascript file that I am using to try to animate a dropdown menu. I have the "Toggle" function in that file set to run when I click on a certain div. Here's the script I'm using:
var up = true;
function Toggle(x)
{
if (up)
{
for (var i = x.offsetTop; i <= 0; i++)
{
x.style.top = i;
if (i == 0)
{
up = false;
}
}
}
else if (up == false)
{
for (var i = x.offsetTop; i >= -50; i--)
{
x.style.top = i;
if (i == -50)
{
up = true;
}
}
}
}
In the HTML div I want to animate, I have the "onclick" property set to "onclick=Toggle(this)". The first for loop works as it should (it sets the div's top offset to 0). However, the second for loop doesn't set the offsetTop. I know that the for loop is activating because I've tested it and it gives me every integer between 0 and -50. Why isn't it setting the offset position?
1) You must specify a unit to the top ie: x.style.top = i +"px"
2) Your function won't animate instead of you use a setInterval or a setTimeout
Like you asked, an example. I wouldn't do it like this for one of my project, but i kept your function to make you more familiar with the code.
I Used setTimeout instead of setInterval because setInterval must be cleared when not needed and setTimeout is just launched one time :
var Toggle = (function() { // use scope to define up/down
var up = true;
return function(element) {
var top = parseInt(element.style.top, 10); // element.offsetTop ?
if ( !top ) {
top = 0;
}
if (up) {
if (element.offsetTop < 0) { // if we are not at 0 and want to get up
element.style.top = (top+1) + "px";
setTimeout(function() { Toggle(element); }, 10); // recall the function in 10 ms
} else { // we change up value
up = !up;
}
}
else {
if (element.offsetTop > -50) {
element.style.top = (top-1) + "px";
setTimeout(function() { Toggle(element); }, 10); // recall the function in 10 ms
} else {
up=!up;
}
}
}
})();
You'd have to use x.style.top = i + 'px' as top and similar css properties must define the type (px, em, %, etc.) unless they are 0, as this is 0 in any case.
But your script would actually snap the div directly to -50px, as you do not wait between those iteration steps.
I'd recommend to use a library like jQuery to use it's animate() method.
function Toggle(obj) {
$(obj).animate({
top: parseInt($(obj).css('top')) === 0 ? '-50px' : '0px'
})
}

jquery stop image rotation on mouseover, start on mouseout / hover

I have built a jQuery rotator to rotate through 3 divs and loop them. I would like to add the functionality on mouse over to "freeze" the current div and then start again on mouse out.
I've thought about setting a variable to false at the start of the function and setting it true when it's on it's current frame but I've got my self a bit confused.
I've also tried to use the hover function but when using the in and out handlers, I'm confused as to how to stop, restart the animation.
function ImageRotate() {
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).delay(4500).animate({'top' : '330px'}, 3000);
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).delay(4500).animate({'top' : '0px'}, 3000);
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).delay(4500).css('top' , '-330px');
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500)};
Any help would be greatly appreciated!!
Thanks, Matt
If you were to add this code:
var timerId = null;
function startRotation() {
if (timerId) {
return;
}
timerId = setInterval('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; ImageRotate2()', 7500);
}
function stopRotation() {
if (!timerId) {
return;
}
clearInterval(timerId);
timerId = null;
}
and replace the last line of your code block with a simple call to startRotation();, then you could call stopRotation and startRotation when the mouse hovers over/leaves your element:
$('your-element-selector').hover(stopRotation, startRotation);
It's not clear what you are trying to do with the three divs without seeing the HTML and more code, so I think a basic example might help you better (demo).
HTML
<div class="test">image: <span></span></div>
Script
$(document).ready(function(){
var indx = 0, loop, numberOfFeatures = 5;
function imageRotate(){
indx++;
if (indx > numberOfFeatures) { indx = 1; }
$('.test span').text(indx);
loop = setTimeout( imageRotate , 1000 );
}
imageRotate();
$('.test').hover(function(){
clearTimeout(loop);
}, function(){
imageRotate();
});
})
changed things up a little bit, here is how I ended up doing it. `
var animRun = false;
var rotateHover = false;
function startRotation() {
rotateHover = false;
ImageRotate();
}
function stopRotation() {
rotateHover = true;
clearTimeout();
}
function ImageRotate() {
if (rotateHover == false){
animRun = true;
var CurrentFeature = "#container" + featureNumber;
$(CurrentFeature).stop(false, true).animate({'top' : '330px'}, featureDuration, function(){animRun = false;});
var featureNumber2 = featureNumber+1;
if ( featureNumber == numberOfFeatures) {featureNumber2 = 1}
var NewFeature = "#container" + featureNumber2;
$(NewFeature).stop(false, true).animate({'top' : '0px'}, featureDuration); /* rotate slide 2 into main frame */
var featureNumber3 = featureNumber-1;
if ( featureNumber == 1) {featureNumber3 = numberOfFeatures};
var OldFeature = "#container" + featureNumber3;
$(OldFeature).stop(false, true).css('top' , '-330px'); /*bring slide 3 to the top*/
//startRotation();
setTimeout('if (featureNumber == numberOfFeatures){featureNumber = 1} else {featureNumber++}; if (rotateHover == false){ImageRotate2()};', featureDelay);
};
};

Categories

Resources