How to make a Div's height change slower - javascript

I want to make a Div appear by scrolling down on a button click slowly from the top of the page. But when I do it with what I have now, it just appears very fast and does not really slide down. What am I doing wrong?
function showstuff(inquiryForm){
document.getElementById(inquiryForm).style.visibility="visible";
for (var i=0;i<300;i++)
{
document.getElementById(inquiryForm).style.height= i + "px";
}
}

You are looping 300 items and you try to find the element with getELementById and then trying to style the selected item
I think that makes the process really slow and laggy.

Here is an example that should help you understand the event loop,
and the use of setTimeout.
<div id="myDiv" style="width:10px;height:50px;background:#f00;"></div>
<button class="btn" onclick="start();">Start</button>
<button class="btn" onclick="stop();">Stop</button>
<button class="btn" onclick="reset();">Reset<button>
var timeout;
function start() {
var div = document.getElementById("myDiv");
var size = 10;
var func = function () {
timeout = setTimeout(func, 0);
div.style.width = size + "px";
if (size++ == 600) stop();
}
func(); // starts the process
}
function stop() {
clearInterval(timeout);
}
function reset() {
var div = document.getElementById("myDiv");
div.style.width = "10px";
}

this sort of thing is often handled using jquery, as it includes various animation functions, including a convenient short form that would be useful here:
once you've included the jquery library, you can use a function like this:
$(inquiryForm).slideDown( 500 );
where the argument is duration of the effect in ms
like so:
function showstuff(inquiryForm){
$(inquiryForm).slideDown( 500 );
}

Related

onmousedown/onmouseup function not working

I have a rectangle I am trying to move using javascript. I can get it to move left and right using functions, but when I hold the mouse down it doesn't continue to move. Here is my html code:
<button onmousedown="moveLeft();" onmouseup="stopMove();">LEFT</button>
<button onmousedown="moveRight();"
onmouseup="stopMove();">RIGHT</button><br><br>
Here is my javascript code (the conditional statements are just so the rectangle doesn't move off of the canvas):
function moveLeft () {
xx-=20;
if (xx<0) {
xx=0;
}
}
function moveRight() {
xx+=20;
if (xx>400) {
xx=400;
}
}
function stopMove () {
xx+=0;
}
When you press a mouse button, the mousedown event will fire just once. It does not continuously fire while you have the button held down. What you'll need to do is use a timer to begin the movement and then, on mouseup, stop the timer.
Also, don't use inline HTML event handlers (onmouseover, onmouseout, etc.). Here's why.
Lastly, since your moveLeft and moveRight functions are essentially the same thing, they can be combined into one function that simply takes in an argument that determines the direction.
Here's a working example:
// Get references to the HTML elements you'll need to interact with:
var btnLeft = document.getElementById("btnLeft");
var btnRight = document.getElementById("btnRight");
var box = document.getElementById("box");
// Set up event handlers for the HTML elements in JavaScript, using modern
// standards, not in the HTML. Both the left and right buttons need to
// call the same function, but with a different argument value. This is
// why the events are being bound to another function that wraps the actual
// call to the move function (so that an argument can be passed).
btnLeft.addEventListener("mousedown", function(){ move(-20); });
btnRight.addEventListener("mousedown", function(){ move(20); });
btnLeft.addEventListener("mouseup", stopMove);
btnRight.addEventListener("mouseup", stopMove);
// The counter needs to be accessible between calls to move
var xx = 0;
// We'll start an automatic timer, but we'll need to stop it later
// so we need a variable set up for that.
var timer = null;
// Only one function is needed to address the move operation
// The argument is what determines the direction
function move(amount) {
// Stop any previous timers so that we don't get a runaway effect
clearTimeout(timer);
xx += amount;
// Check the new position to see if it is off the visible page
if (xx < 0){
xx = window.innerWidth;
} else if(xx > window.innerWidth){
xx = 0;
}
// Just displaying the current value
box.textContent = xx;
// Move the box to the new location
box.style.left = xx + "px";
// Run the timer after a 250 millisecond delay and have
// it call this function again. Assign the variable to
// the timer.
timer = setTimeout(function() { move(amount) }, 250);
}
function stopMove () {
xx += 0;
// Stop the timer
clearTimeout(timer);
}
#box {
background-color:blue;
border:2px solid black;
color:yellow;
text-align:center;
font-weight:bold;
padding-top:.5em;
margin-top:3em;
/* Everything above is just for display and not actually needed.
But in order to move the box and to be able to have a consistent
size for it, the following is required: */
position:absolute;
height:50px;
width:50px;
}
<button id="btnLeft">LEFT</button>
<button id="btnRight">RIGHT</button>
<div id="box"></div>
Since the mouse evet does not fire while it is down, you need to fire the event manually until you detect the other event. So to do this, you need to either use setInterval or setTimeout
var moveTimer,
xx = 200;
function move (dir) {
xx+=20*dir;
if (xx<0) {
xx=0;
} else if (xx>400) {
xx=400
}
stopMove()
moveTimer = window.setTimeout(move.bind(this,dir), 100)
document.getElementById("out").value = xx;
}
function stopMove () {
if(moveTimer) window.clearTimeout(moveTimer);
moveTimer = null
}
window.addEventListener("mouseup", stopMove)
<button onmousedown="move(-1);">LEFT</button>
<button onmousedown="move(1);">RIGHT</button>
<input type="number" id="out"/>

Simple loop for images

I'm trying to build a simple image slider (but using a fade effect). Every two seconds, the image should change to another image. At the end, it should call repeat_sponsor() again, to start over, so it becomes a loop.
I've written this (highly ineffective) code for 5 images. Turns out I'm going to need it for around 50 images. My editor just freezes when I add too much code.
I've tried using while-loops, but I just can't figure it out how to do this the right way.
Anyone who can help me with this?
function repeat_sponsor()
{
$("#sponsor2").hide();
$("#sponsor3").hide();
$("#sponsor4").hide();
$("#sponsor5").fadeOut("slow");
$("#sponsor1").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor2").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor3").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor4").fadeIn("slow", function() {
setTimeout(function(){$("#sponsor5").fadeIn("slow", ...
(function (){
var cnt = 50; //set to the last one...
var max=50;
function show() {
$("#sponsor" + cnt).fadeOut("slow"); //if you want the fadeout to be done before showing next, put the following code in the complete callback
cnt++;
if(cnt>max) {
cnt=1;
}
$("#sponsor" + cnt).fadeIn("slow");
window.setTimeout(show, 2000);
}
show();
})();
But the real issue is the fact you are loading tons of images from the start. You will be better off changing it so you only have a small subset of images and change the source.
You should use some sort of for loop and a class for hiding the images. and add a max value that if checks out resets c & i
var i=0;
var c=1;
function repeat_sponsor()
{
$("#sponsor"+i).fadeOut("slow");
$(".sponsers").hide()
$("#sponsor"+c).fadeIn("slow", function() {
window.setTimeout(repeat_sponsor(), 3000);
}
i++;
c++;
}
Just run a function every two seconds with setInterval and appropriately target your different sponsor divs:
var i = 1;
var max = 50;
setInterval(function() {
// Could target all other sponsor images with a class "sponsor"
$('.sponsor').fadeOut();
// Execute code on the target
$("#sponsor" + i).fadeIn();
if (i === max) {
i = 0;
}
i++;
}, 2000);

How can I stop Scrolling my <div> onmouseover?

Right now I have a div that I am automatically scrolling infinitely:
<script language="javascript">
i = 0
var speed = 1
function scroll() {
i = i + speed
var div = document.getElementById("content")
div.scrollTop = i
if (i > div.scrollHeight - 160) { i = 0 }
t1 = setTimeout("scroll()", 100)
}
</script>
The div that I need to scroll I want to stop scrolling onmouseover, so I have added this code to the div:
<div id="content" value="Pause" onmouseover="clearTimeout(t1)" onmouseout="scroll()">
Here is a link to a jfiddle. The preview there isn't doing what it should, but that's what I have that's working in my project right now.
So far this is working, but the problem is that I want to be able to manually scroll when I hover over this div. Now, the automatic scrolling is stopping, but I can't manually scroll with just the scrollwheel: It reacts the same when it is scrolling as when it is stopped with onmouseover.
Is there a way that I can basically cancel the whole scroll function onmouseover, or write something that just allows using the scrollwheel/scrollbar. as well? It would also be ok to have code to ALWAYS allow using the scrollwheel/scrollbar.
I'm not sure what would be the best way to do it.
Thanks!!
By setting it to scroll the overflow, assuming a fixed height, the scrollbar will pop up and you can scroll manually. Of course you will want to hide the scrollbar again when it resumes autoscrolling so you will need two functions to set the style.
<script language="javascript">
i = 0;
var speed = 1,t1=null;
function startScroll(){
document.getElementById("content").style.overflowY="hidden";
scroll();
}
function stopScroll(){
clearTimeout(t1);
document.getElementById("content").style.overflowY="scroll";
}
function scroll() {
i = i + speed;
var div = document.getElementById("content");
div.scrollTop = i;
if (i > div.scrollHeight - 160) { i = 0; }
t1 = setTimeout("scroll()", 100);
}
</script>
HTML change:
<div id="content" value="Pause" onmouseover="pauseScroll()" onmouseout="startScroll()">

Javascript fade in doesn't visibly animate

So I've created the following function to fade elements in and passed in a div that I want to fade in which in this case is an image gallery popup that I want to show when a user clicks an image thumbnail on my site. I'm also passing in a speed value (iSpeed) which the timeout uses for it's time value. In this case I'm using 25 (25ms).
I've stepped through this function whilst doing so it appears to be functioning as expected. If the current opacity is less than 1, then it is incremented and it will recall itself after the timeout until the opacity reaches 1. When it reaches one it stops fading and returns.
So after stepping through it, I take off my breakpoints and try to see it in action but for some reason my gallery instantly appears without any sense of fading.
var Effects = new function () {
this.Fading = false;
this.FadeIn = function (oElement, iSpeed) {
//set opacity to zero if we haven't started fading yet.
if (this.Fading == false) {
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
this.Fading = false;
return;
}
//otherwise, fade
else {
this.Fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
}
}
}
Here's where I'm setting up the gallery.
this.Show = function (sPage, iImagesToDisplay, oSelectedImage) {
//create and show overlay
var oOverlay = document.createElement('div');
oOverlay.id = 'divOverlay';
document.body.appendChild(oOverlay);
//create and show gallery box
var oGallery = document.createElement('div');
oGallery.id = 'divGallery';
oGallery.style.opacity = 0;
document.body.appendChild(oGallery);
//set position of gallery box
oGallery.style.top = (window.innerHeight / 2) - (oGallery.clientHeight / 2) + 'px';
oGallery.style.left = (window.innerWidth / 2) - (oGallery.clientWidth / 2) + 'px';
//call content function
ImageGallery.CreateContent(oGallery, sPage, iImagesToDisplay, oSelectedImage);
//fade in gallery
Effects.FadeIn(oGallery, 25);
}
Could anyone help me out?
Also, I'm using IE10 and I've also tried Chrome, same result.
Thanks,
Andy
This line:
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
calls Effects.FadeIn with the given arguments, and feeds its return value into setTimeout. This is exactly like foo(bar()), which calls bar immediately, and then feeds its return value into foo.
Since your FadeIn function doesn't return a function, that would be the problem.
Perhaps you meant:
setTimeout(function() {
Effects.FadeIn(oElement, iSpeed);
}, iSpeed);
...although you'd be better off creating that function once and reusing it.
For instance, I think this does what you're looking for, but without recreating functions on each loop:
var Effects = new function () {
this.FadeIn = function (oElement, iSpeed) {
var fading = false;
var timer = setInterval(function() {
//set opacity to zero if we haven't started fading yet.
if (fading == false) { // Consider `if (!this.Fading)`
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
clearInterval(timer);
}
//otherwise, fade
else {
fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
}
}, iSpeed);
};
};
Your code has a lot of problems. The one culpable for the element appearing immediately is that you call setTimeout not with a function but with the result of a function, because Effects.FadeIn will be executed immediately.
setTimeout(function(){Effects.FadeIn(oElement, iSpeed)}, iSpeed);
will probably act as you intend.
But seriously, you probably should not re-invent this wheel. jQuery will allow you to fade elements in and out easily and CSS transitions allow you to achieve element fading with as much as adding or removing a CSS class.
T.J. and MoMolog are both right about the bug: you're invoking the Effects.FadeIn function immediately before passing the result to setTimeout—which means that Effects.FadeIn calls itself synchronously again and again until the condition oElement.style.opacity >= 1 is reached.
As you may or may not know, many UI updates that all take place within one turn of the event loop will be batched together on the next repaint (or something like that) so you won't see any sort of transition.
This jsFiddle includes the suggested JS solution, as well as an alternate approach that I think you may find to be better: simply adding a CSS class with the transition property. This will result in a smoother animation. Note that if you go this route, though, you may need to also include some vendor prefixes.

Showing/hiding <div> using javascript

For example I have a function called showcontainer. When I click on a button activating it, I want a certain div element, in this case <div id="container">, to fade in. And when I click it again, fade out.
How do I achieve this?
Note: I am not accustomed with jQuery.
So you got a bunch of jQuery answers. That's fine, I tend to use jQuery for this kind of stuff too. But doing that in plain JavaScript is not hard, it's just a lot more verbose:
var container = document.getElementById('container');
var btn = document.getElementById('showcontainer');
btn.onclick = function() {
// Fade out
if(container.style.display != 'none') {
var fade = setInterval(function(){
var opacity = parseFloat(container.style.opacity);
opacity = isNaN(opacity) ? 100 : parseInt(opacity * 100, 10);
opacity -= 5;
container.style.opacity = opacity/100;
if(opacity <= 0) {
clearInterval(fade);
container.style.opacity = 0;
container.style.display = 'none';
}
}, 50);
// Fade in
} else {
container.style.display = 'block';
container.style.opacity = 0;
var fade = setInterval(function(){
var opacity = parseFloat(container.style.opacity);
opacity = isNaN(opacity) ? 100 : parseInt(opacity * 100, 10);
opacity += 5;
container.style.opacity = opacity/100;
if(opacity >= 100) {
clearInterval(fade);
container.style.opacity = 1;
}
}, 50);
}
};
Check the working demo.
Provided you're not opposed to using jQuery per se, you can achieve this easily:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#showcontainer').click(function() {
$('#container').fadeToggle();
});
});
</script>
...
<div id="container">
...
</div>
...
<input type="button" id="showcontainer" value="Show/hide"/>
...
Note the missing http: in the beginning of the source of jQuery. With this trick the browser will automatically use http: or https: based on whether the original page is secure.
The piece of code after including jQuery assigns the handler to the button.
Best thing you could do is start now and get accustomed to jQuery.
The page http://api.jquery.com/fadeIn/ has all the example code that could be written here. Basically you want to have the call to fadeIn in your showcontainer function.
function showcontainer() {
$('#container').fadeIn();
}
You can have a look at jQuery UI Toggle.
The documentation turns the use of the library very simple, and they have many code examples.
You'd be as well off learning jQuery as it makes it a lot easier to do things!
From the sounds of it, you could have the container div already in the HTML but with a style of "display:none;", and then simply show it in your click event using (jQuery):
$('#container').fadeIn('slow', function() {
//Any additional logic after it's visible can go here
});

Categories

Resources