Progress bar with .delay - javascript

Fiddle
I want to make a progress bar fill up 25% per second. My current code makes it go to 100% and stay there on click. I'm not sure if it's best to use jquery or css. Or if there is an easier way to do it.
Also how can I make an action occur multiple times from one .click. Like you click battle and it hits the monster, then waits for the progress bar to fill, then hits the monster again and so on?
$('#battle').click(function() {
$('#dam').html("You have hit the " + $('#monsters').val() + " for 5 damage");
$('#bar').val(25).delay(1000);
$('#bar').val(50).delay(1000);
$('#bar').val(75).delay(1000);
$('#bar').val(100);
});

Here you go!
https://jsfiddle.net/6nrjw0Le/
For your example I am using
setTimeout()
Your example edited.
var progress = function(sec){
var interval = 250;//milliseconds
setTimeout(function(){
sec = sec+25;
$('#bar').val(sec);
if(sec < 100)
progress(sec);//call self with new value
},interval)
}
$('#battle').click(function() {
$('#dam').html("You have hit the " + $('#monsters').val() + " for 5 damage");
/*$('#bar').val(25).delay(1000);
$('#bar').val(50).delay(1000);
$('#bar').val(75).delay(1000);
$('#bar').val(100);*/
progress(0);//initialize progress bar
});
delay() is asynchronous. Putting one delay after another doesn't mean you get the execution after first one is complete.

Related

JS/JQuery: Text changes for a few seconds and then back to original

I have a < div > where I keep my score but I want when its right that my text changes to +1 so I can see I was right and then immediately changes back to my score.
With my code he shows immediately the POINTS, that fades out and fades in again so the +1 never shows up. Can someone help pls?
if (x >= y){
score++;
$("#counter").html("+1");
$("#counter").fadeOut(3000);
$("#counter").fadeIn(3000);
$("#counter").html("POINTS" + score);
}
.fadeOut in complete-callback of the fadeIn which is being invoked once the .fadeIn is complete.
if (x >= y) {
score++;
$("#counter").html("+1");
$("#counter").fadeOut(3000, function() {
$("#counter").fadeIn(3000);
$("#counter").html("POINTS" + score);
});
}
try setTimeout
setTimeout(function(){ $("#counter").html("POINTS" + score);},2000);

Is there a way for me to check that an element is not 'loaded' yet in an if statement?

I have a piece of javascript/jquery that is an event listener, waiting for an element to load:
$("#download-iframe").on("load", function() {
alert("Download iframe loaded. src attribute value: " + $(this).attr("src"));
});
Right now this alert will pop up once the script in the src attribute is done loading/running.
I want to show a progress bar of sorts that increments slowly, but I want it to do thins only as long as the $("#download-iframe") element is not yet loaded.
Is there a way to check in an if statement if the element is loaded yet or not?
function showProgress() {
var oneMinute = 60000; // One minute in milliseconds
var maxTime = 10 * oneMinute; // Maximum time in minutes, 10 minutes
var progress = 5;
var increment = 5;
$("#show-progress").attr("aria-valuenow", increment);
$("#show-progress").css("width", increment + '%');
var scriptProgress = setInterval( function() {
progress += increment;
if (progress <= 100 && /* ALSO CHECK FOR ELEMENT NOT YET LOADED HERE */) {
$("#show-progress").attr("aria-valuenow", progress);
$("#show-progress").css("width", progress + '%');
}
else {
$(".progress").addClass("hidden");
clearInterval(scriptProgress);
}
}, oneMinute / 10);
}
I am using twitter bootstrap's progress bars. the src script being run is a POST ajax URL that is not an upload/download so I can't use an AJAX progress eventListener. I want to give the user the appearance of something happening, a feedback of some kind.
If the iframe src is loaded prior to the progress bar reaching 100% incrementally, I want it to jump to 100% and then show the result of the PHP script.
Any suggestions would be greatly appreciated.
Why not set a flag in load()
var loaded = false;
$("#download-iframe").on("load", function() {
loaded = true;
alert("Download iframe loaded. src attribute value: " + $(this).attr("src"));
});
and then in the if statement
if (progress <= 100 && loaded)

Javascript animation too fast

I am trying to write a javascript app which sorts dynamically created divs on a webpage, everything works and it sorts it all as it should, however I want it to animate the divs as they change position due to being sorted, I have code to do this but it moves way too fast, the only way I can see the divs move is if I put an alert in the animation code which looks like this :
function moveAnimation(to,from){
mover1.style.backgroundColor = "rgba(255,100,175,0.8)";
mover2.style.backgroundColor = "rgba(255,100,175,0.8)";
mover1.style.top = parseInt(mover1.style.top) + 10 + 'px';
mover2.style.top = parseInt(mover2.style.top) - 10 + 'px';
from = parseInt(mover1.style.top);
if(from != to && from < to)
{
//alert("TO : " + to + " From : " + from); //This makes it pause so that I can see the divs move
animate = setTimeout(moveAnimation(to,from),1000)
}
else
{
//alert("RET");
return;
}
}
And i call it simply like this :
mover1 = document.getElementById(moving1.id);
mover2 = document.getElementById(moving2.id);
var from = parseInt(in1.style.top);
var to = parseInt(in2.style.top);
moveAnimation(to,from);
When the alert is in place I can see them move frame by frame and it's doing exactly what I want, however it all happens in the blink of an eye with the divs suddenly being sorted, I would like to see them slowly move, any ideas on why my code isn't doing that?

Image Rotation using pure Javascript

PLEASE DO NOT RECOMMEND JQUERY - I AM DOING THIS EXERCISE FOR LEARNING PURPOSES.
I have implemented a JavaScript, which rotates images (_elementSlideChange) on a timer, using a set interval of 10 seconds. Also I have added a slide functionality to this, which is 7 milliseconds (_slideImage).
The image rotates automatically every 10 seconds on page load, and I have also provided next and previous buttons, which allow the user to change the images manually.
_elementSlideChange: function () {
var myString;
var myText;
for (var i = 0; i < this._imgArray.length; i++) {
var imageArr = "url(" + this._imgArray[i].src + ")";
var imageBg = this._imageHolder.style.background + "";
if (imageArr == imageBg) {
if (i == (this._imgArray.length - 1)) {
myString = "url(" + this._imgArray[0].src + ")";
myText = this._infoArray[0];
} else {
myString = "url(" + this._imgArray[(i + 1)].src + ")";
myText = this._infoArray[i + 1];
}
}
}
this._imageNextSlide.style.background = myString;
this._imageNextSlide.style.background);
this._infoElement.innerHTML = myText;
this._myTimer = setInterval(MyProject.Utils.createDelegate(this._slideImage, this), 7);
},
_slideImage: function () {
if (parseInt(this._imageHolder.style.width) >= 0 && parseInt(this._imageNextSlide.style.width) <= 450) {
this._imageHolder.style.backgroundPosition = "right";
this._imageHolder.style.width = (parseInt(this._imageHolder.style.width) - 1) + 'px';
console.log(this._imageNextSlide.style.background);
this._imageNextSlide.style.width = (parseInt(this._imageNextSlide.style.width) + 1) + 'px';
} else {
console.log("reached 0px");
if (parseInt(this._imageHolder.style.width) == 0) {
this._imageHolder.style.background = this._imageNextSlide.style.background;
this._imageHolder.style.width = 450 + 'px';
this._imageHolder === this._imageNextSlide;
this._imageHolder.className = "orginalImage";
this._imageNextSlide.style.width = 0 + "px";
this._imageNextSlide = this._dummyImageNextSlide;
this._imagesElement.appendChild(this._imageHolder);
this._imagesElement.appendChild(this._imageNextSlide);
clearInterval(this._myTimer);
}
clearInterval(this._myTimer);
clearInterval(this._elementSlideChange);
}
}
So when the user clicks on the Next arrow button, the event listener for "click" is triggered. This creates a div for the current image on display, and creates a new div, which will contain the next image. The image slide and rotation works correctly (whether it's onLoad or onClick). The issue I have is if I click the Next button, while the new div image is sliding into position, it causes it to run into an infinite loop, so the same div with the image to be displayed keeps sliding in, and the more you click the Next button, the faster the image starts to rotate.
I have tried putting a clear interval for the image rotation and slider, but I do understand my code is wrong, which causes the infinite loop of the sliding image. And I know I am close to finishing the functionality.
Can anyone please advise where I could be going wrong? Or should I try to implement the sliding DIV in another way?
Once again please don't recommend jQuery.
And thank you for your help in advance.
Kush
To solve the issue, I did re-write the entire code, where I had a next and previous button event listener.
myProject.Utils.addHandler(this._nextImageElement, "click", myProject.Utils.createDelegate(this._changeImage, this));
Both the buttons will call the same function :
_changeImage: function (e)
In this function I check to see if the function is Transition (changing images),
I declare a boolean var forward = e.target == this._nextImageElement;
Then check to see the current index if forward ? Add 1 else minus 1
this._currentImageIndex += forward ? 1 : -1;
If its at the end of the Array and forward is true, assign the this._currentImageIndex to reset to 0 or Array.length – 1 if it’s in reverse
Then call another function which gives the ‘div’ a sliding effect. In this case call it this._transitionImage(forward);
In this function, set the this._inTranstion to true. (Because the div’s are sliding in this case).
The following code solved the issue i was having.
this._slideImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";
this._slideImageElement.style.backgroundPosition = forward ? "left" : "right";
this._slideImageElement.style.left = forward ? "auto" : "0px";
this._slideImageElement.style.right = forward ? "0px" : "auto";
The above code is very important as the object is to place the “sliding in div” Left or Right of the current Visible “div” to the user, and this is mainly dependent on if the forward variable is true or false.
var i = 0;
Then start the transition by
setInterval( function() {
this._currentImageElement.style.backgroundPosition = (forward ? -1 : 1) * (i + 1) + "px";
this._slideImageElement.style.width = (i + 1) + "px";
Notice the forward will determine if the bgPosition will go to the left if its forward as we multiple by -1 or +1,
So for example
If the user clicks NEXT BUTTON,
Forward = true
So the first thing we do is set the
this._slideImageElement.style.backgroundPosition = "left"
Then
this._slideImageElement.style.left = "auto"
this._slideImageElement.style.right = "0px"
This means when the sliding image moves in its background position is LEFT but the div is placed on the RIGHT to 0px;
then this._currentImageElement.style.backgroundPosition = -1 * (i + 1)
Which moves the position of the currentImageElement to the left by 1px,
Increase the width of the slideImage which in this case is right of the current div,
and as the current div moves to the left the sliding image starts to appear from the right. (By default set the width of slideImageElement to 0px so the div exists but isn’t visible to the user). This gives it the slide effect of moving forward new image coming from the right.
this._slideImageElement.style.width = (i + 1) + "px";
then declare it to stop when it it’s the image width. In this case it will be 500px.
if ((i = i + 2) == 500) {
In this if statement reset the currentImageElement background and the background position “right” or “left” don’t really matter as long it has been reset.
Clear the interval
Set the transition to false again
Then call a setTimeout for the function changeImage, which will continue until the slide is completed.
The following shows the reset code as this is very important to prevent repeating the same image (This solved my entire issue)
// set the current image to the "new" current image and reset it's background position
this._currentImageElement.style.backgroundImage = "url(\"" + this._imgArray[this._currentImageIndex].src + "\")";
this._currentImageElement.style.backgroundPosition = "right";
// reset the slide image width
this._slideImageElement.style.width = "0px";
// clear the transition interval and mark as not in transition
clearInterval(this._transitionInterval);
this._inTransition = false;
// setup the next image timer
this._nextImageTimeout = setTimeout(myProject.Utils.createDelegate(this._changeImage, this), 2500);
}
I have provided a thorough detail because then it easier to understand the logic of the problem, and even if your not having the same issue, this may help you fingure out any problem.
I couldn't provide a JSfiddle, as i have created my CSS using Javascript, there are different ways of doing this, but i wanted to understand the logic behind the forward and reverse, and having a timer which continuously goes forward.
It seems like you want to cancel the animation on the slide (perhaps have it fade out while the next slide animates in, cancel its animation abruptly or let it finish and ignore the button click)
What I usually do, personally, is check for the animated state (yes, I use jquery, but you should be able to test the CSS or positioning values you are using to animate in the same way) you could even add an "active" class or data type during animation to make testing easier. Global flags work, too. If there is animation, ignore the button. (For my work... Depends on your intention)
Like I said, the problem may be with button behaviour not with the animation routine. It would be useful to see how you are calling this from the button click, and what your intended results are going to be.
How about CSS3 transitions?
transition: all 1s ease 0.5s;
Simple example on JS Fiddle.
This takes care of the animation, so you just need to set the intended destination using JavaScript, i.e.
this.style.left = '100px';
Or
this.style.top = '30px';
And CSS3 transitions will smoothly slide the element.
Cross Browser Note!
The transition property may need a vendor prefix for some browsers, I am using the latest production Firefox and you don't need -moz for that. Same goes for Opera, no '-o' required. Internet Exporer 10 needs no prefix. You may need to use -webkit for Safari / Chrome, but test without first.

Javascript: Controlling an image's moving speed

I'm a beginner and currently I can move an image from left to right and I can turn it back to its initial point when moving finishes. What I want to do is also controlling image's speed. In order to do this I tried the codes below:
<script type="text/javascript">
var userWidth = window.screen.width;
function moveRight(speed) {
var pp = document.getElementById("myimage");
var lft = parseInt(pp.style.left);
var tim = setTimeout("moveRight()", speed);
lft = lft + 50;
pp.style.left = lft + "px"
if (lft > (userWidth) + 80) {
document.getElementById("myimage").style.left = 100 + "px";
clearTimeout(tim);
}
}
</script>
And html:
<form>
<input type="button" value="Speed 1" onclick="moveRight(50)" />
<input type="button" value="Speed 2" onclick="moveRight(25)" />
<input type="button" value="Speed 3" onclick="moveRight(10)" />
</form>
My problem: there is no difference when I click any of three buttons. Image is always moving with the same speed and looks like buttons have no control on the speed.
The mistake you did in your orignal code is that when you call the function again you do not pass it the value of speed which means that the only thing that happens is that the first animation is delayed.
Try replacing the call with this line and then your code should work.
var tim = setTimeout("moveRight("+speed+")", speed);
With this you can still do this without using Jquery
Your above code doesn't have any speed logic. The only thing you're doing is delaying the time before the animation start :
var tim = setTimeout("moveRight()", speed);
Making a recursive call to a function waiting for an attribute (speed), is also a nogo.
I setted up a quick fiddle to demonstrate jquery animation speed :
http://jsfiddle.net/yeQtB/
To achieve speed in animation, two possibilities :
• Cycle logic :
You admit that rather than seconds, you can work with cycles, then just create a for loop, that will iterate until animation is over. edit : this is just here for the sake of the explanation
• Time logic
You have a distance and a timeframe (in sec), divide the distance by the timeframe, it gives you step, divide the distance by the step, it will give you the number of steps, then it is just a matter of creating a settimeout firing every second in a loop. edit : if you achieved this and is eager to go for something a bit smoother, i'd advise to have a look at the requestAnimationFrame HTML5 Api :
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
You have to pass the variable speed to moveRight in the setTimeout :
var userWidth = window.screen.width,
tim,
pp = document.getElementById("myimage"); // You should cache your variables
function moveRight(speed) {
var lft = parseInt(pp.style.left) || 0;
tim = setTimeout("moveRight(" + speed + ")"); // Here you have to pass speed as a parameter
lft = lft + speed; // Here I guess it is speed rather than 50
pp.style.left = lft + "px"
if (lft > (userWidth) + 80) {
pp.style.left = 100 + "px";
clearTimeout(tim);
}
}

Categories

Resources