Slideshow - make a jQuery Plugin from working code fails - javascript

I've created a little slideshow with images out of a folder with jQuery and with help from stackoverflow and other snippets.
Images are named 1.jpg, 2.jpg ... 1-b.jpg, 2-b.jpg...The special thing is, that every image-change 3 images are loaded. The first time the images in the HTML (3 images too) are replaced.
2 of the 3 new images are blurred, to have a fade from current to - blurred current - into blurred next - next. Works fine and looks really great.
Now I want to make a real jQuery plugin out of that, because I want to change the startup (image Nr.) and imageLast (here go back to startup) on every site. Well I don't know if there are problems with the logic of the original code to make a plugin. My trials failed. Please have a look.
Original working code:
// slideshow ----------------------------------------------------------------------------
(function() {
var pauseTime = 7000;
function slideShow(index) {
var imagePath = "slider-team";
var startup = 1;
var startindex = index+startup-1;
var index1 = startindex+1;
var lastImage = 6;
var fadeTime = 700;
var fadeTime2 = 500;
var fadeTime3 = 1000;
var theImage1 = new Image();
var theImage2 = new Image();
var theImage3 = new Image();
var url = imagePath + "/" + startindex + ".jpg";
var urlb = imagePath + "/" + startindex + "-b.jpg";
var url2b = imagePath + "/" + index1 + "-b.jpg";
$(theImage1, theImage2, theImage3).load(function () {
$(theImage1).prependTo("#slider");
$(theImage2).prependTo("#slider");
$(theImage3).prependTo("#slider");
$("#slider img:last").fadeOut(fadeTime, function() {
$(this).remove();
$("#slider img:last").fadeOut(fadeTime2, function() {
$(this).remove();
$("#slider img:last").fadeOut(fadeTime3, function() {
$(this).remove();
setTimeout(function() {
slideShow((index % (lastImage-startup)) + 1)
}, pauseTime);
});
});
});
});
theImage1.src = url;
theImage2.src = urlb;
if(startup+index === lastImage) {
theImage3.src = "slider/" + startup + "-b.jpg";
} else {
theImage3.src = url2b;
};
}
$(document).ready(function() {
// Img 1 is already showing, so we call 2
setTimeout(function() { slideShow(2); }, pauseTime);
});
})();
Trial to make a plugin:
// slideshow ----------------------------------------------------------------------------
(function($) {
$.blurSlider = function(index, settings){
var config = {
'startup':1;
'lastImage':17;
};
if(settings){$.extend(config, settings);}
var pauseTime = 7000;
//function slideShow(index) {
var imagePath = "slider-opt";
//var startup = 1;
var startindex = index+startup-1;
var index1 = startindex+1;
//var lastImage = 17;
var fadeTime = 700;
var fadeTime2 = 500;
var fadeTime3 = 1000;
var theImage1 = new Image();
var theImage2 = new Image();
var theImage3 = new Image();
var url = imagePath + "/" + startindex + ".jpg";
var urlb = imagePath + "/" + startindex + "-b.jpg";
var url2b = imagePath + "/" + index1 + "-b.jpg";
$(theImage1, theImage2, theImage3).load(function () {
$(theImage1).prependTo("#slider");
$(theImage2).prependTo("#slider");
$(theImage3).prependTo("#slider");
$("#slider img:last").fadeOut(fadeTime, function() {
$(this).remove();
$("#slider img:last").fadeOut(fadeTime2, function() {
$(this).remove();
$("#slider img:last").fadeOut(fadeTime3, function() {
$(this).remove();
setTimeout(function() {
slideShow((index % (config.lastImage-config.startup)) + 1)
}, pauseTime);
});
});
});
});
theImage1.src = url;
theImage2.src = urlb;
if(config.startup+index === config.lastImage) {
theImage3.src = "slider/" + config.startup + "-b.jpg";
} else {
theImage3.src = url2b;
};
// }
};
return this;
$(document).ready(function() {
// Img 1 is already showing, so we call 2
setTimeout(function() { $.blurSlider(2); }, pauseTime);
});
})(jQuery);
I don't know if in plugins you need to set up the selector. Here I don't, because the selector didn't change. The call of document.ready inside the plugin is the other thing that might cause problems.

Related

jQuery Promises with chained setTimeouts

I'm doing a little dice game to learn.
What I do is i scrumble the dice X amount of times, keep slowing the random down until it gets to the final value, and that's the "winning number".
But i would like to execute the scrumble 1 by 1 on the dices. Imagine I got 2. And later I do a little zoom effect.
I was thinking I could achieve this by using promises but is not working for me, I don't know what I'm missing.
Here's the JS code:
var counter = 0.8;
var diceNumber = 0;
var rollDice = function(diceId){
var dfd = new $.Deferred();
$('#' + diceId).removeClass('idle');
counter *= 1.2;
diceNumber = Math.round(Math.random()*5) + 1;
$('#' + diceId).removeClass();
$('#' + diceId).addClass('dice_' + diceNumber);
if(counter < 800) {
timeout = setTimeout(rollDice, counter, diceId);
}else{
$('.winner').text(diceNumber);
$('#' + diceId).removeClass();
$('#' + diceId).addClass('animate');
$('#' + diceId).addClass('dice_' + diceNumber)
.animate({ zoom: '1.3' }, 200)
.animate({ zoom: '1' }, 100);
dfd.resolve();
return dfd.promise();
}
}
var startToDice = function() {
rollDice('dice_1').then(rollDice('dice_2'));
}
startToDice();
And what it ends up doing is running both dices simultaneously.
Any advice? Thanks.
You're on the right track. I couldn't test cause I don't have all the elements in place, but try this out:
var counter = 0.8;
var diceNumber = 0;
var rollDice = function(diceId){
var dfd = new $.Deferred();
var roll = function() {
$('#' + diceId).removeClass('idle');
counter *= 1.2;
diceNumber = Math.round(Math.random()*5) + 1;
$('#' + diceId).removeClass();
$('#' + diceId).addClass('dice_' + diceNumber);
if(counter < 800) {
timeout = setTimeout(roll, counter);
}else{
$('.winner').text(diceNumber);
$('#' + diceId).removeClass();
$('#' + diceId).addClass('animate');
$('#' + diceId).addClass('dice_' + diceNumber)
.animate({ zoom: '1.3' }, 200)
.animate({ zoom: '1' }, 100);
dfd.resolve();
}
}
roll();
return dfd.promise();
}
var startToDice = function() {
rollDice('dice_1').then(function(){
rollDice('dice_2');
});
}
startToDice();
Let me know if you get any errors when you run it so I can make adjustments as necessary.
Like comented by bergi:
var startToDice = function() {
rollDice('dice_1').then(function() { rollDice('dice_2'); });
}

Loading bar while image loads from getElementById

Below I have some code for a comic website I'm maintaining. When you click various buttons or select a page from the drop down menu the image changes to the corresponding image. However the image remains on the previous image until the new one has loaded. Is there any way I can add a loading bar or one of the spinning circle things until it has happened?
FYI, I'm not heaps advanced with JS, and this is my own code creation. Help much appreciated.
// Drop Down Menu, next and previous buttons
// Buttons
$(document).ready(function () {
var dd = $('#HailComic');
var max_len = dd.find('option').length;
$('#nextpage').click(function () {
var x = dd.find('option:selected').index();
if (max_len == x + 1) x = -1;
dd.find('option').eq(x + 1).prop('selected', true);
document.getElementById("hail_image").src="images/comic/hail_" + HailComic.options[HailComic.selectedIndex].value + ".jpg";
});
$('#previouspage').click(function () {
var x = dd.find('option:selected').index();
if (0 == x + 1) x = max_len;
dd.find('option').eq(x - 1).prop('selected', true);
document.getElementById("hail_image").src="images/comic/hail_" + HailComic.options[HailComic.selectedIndex].value + ".jpg";
});
$('#lastpage').click(function () {
var x = max_len;
dd.find('option').eq(x - 1).prop('selected', true);
document.getElementById("hail_image").src="images/comic/hail_" + HailComic.options[HailComic.selectedIndex].value + ".jpg";
});
$('#firstpage').click(function () {
dd.find('option').eq(0).prop('selected', true);
document.getElementById("hail_image").src="images/comic/hail_001.jpg";
});
});
// List Changing
$(document).ready(function(){
// Select
var changeHailImage = function () {
document.getElementById('hail_image').src = "images/comic/hail_" + this.options[this.selectedIndex].value + ".jpg"
}
var HailList = document.getElementById('HailComic');
HailList.addEventListener('change', changeHailImage, false);
});
You an use img.load() function to achieve this. Please check the pen http://codepen.io/anon/pen/VvwWWj
var changeHailImage = function () {
document.getElementById('hail_image').src = 'loading.gif';//get a loading image
var img = new Image();
img.src = "images/comic/hail_" + this.options[this.selectedIndex].value + ".jpg";
img.onload = function () {
document.getElementById('hail_image').src = img.src;
}
}

How do you prevent horizontal interfearing of JS movement?

I'm working on a school project, we have just started learning JavaScript. I have to make a script that makes something move with JS. Well, I made the following script:
var object = document.getElementById("object");
var omhoog = document.getElementById("omhoog");
var omlaag = document.getElementById("omlaag");
var links = document.getElementById("links");
var rechts = document.getElementById("rechts");
object.style.left = '0px';
object.style.top = '0px';
omlaag.onclick = function()
{
var positiehuidigtop = parseInt(object.style.top);
setInterval(function()
{
if (parseInt(object.style.top)<positiehuidigtop+100)
{
object.style.top = (parseInt(object.style.top) + 10) + 'px';
}
}, 10);
}
links.onclick = function()
{
var positiehuidigleft = parseInt(object.style.left);
setInterval(function()
{
if (parseInt(object.style.left)>positiehuidigleft-100)
{
object.style.left = (parseInt(object.style.left) - 10) + 'px';
}
}, 10);
}
rechts.onclick = function()
{
var positiehuidigleft = parseInt(object.style.left);
setInterval(function()
{
if (parseInt(object.style.left)<positiehuidigleft+100)
{
object.style.left = (parseInt(object.style.left) + 10) + 'px';
}
}, 10);
}
Sorry for the Dutch stuff in there, but it's variables, so the name doesn't really matter.
Anyways, at first I just had the part of the script that made the div move right. Worked like a charm. But when I started adding left, it would interfear. Both directions are sort of fighting.
I really don't know what to do and this stuff is getting my a headache :/
You should use clearInterval to stop the already running interval timer before starting the new one.
var currentInterval;
omlaag.onclick = function() {
clearInterval(currentInterval);
currentInterval = setInterval(
...
);
};
rechts.onclick = function() {
clearInterval(currentInterval);
currentInterval = setInterval(
...
);
};

variable in nth-child() jquery / javascript

i have the following code:
$(document).ready(function(){
var max_count = $(".slider").children().length;
function fn_get_natural_dim(slide_image,img){
var width = img.width;
var height = img.height;
var ratiow = width/600;
var ratioh = height/400;
if(ratiow>=ratioh)
{
height = height/ratiow;
$(slide_image).css("width","600px");
$(slide_image).css("height",height);
var margin = (400-height)/2;
$(slide_image).css("margin-top",margin);
}
else
{
width = width/ratioh;
$(slide_image).css("width",width);
$(slide_image).css("height","400px");
var margin = (600-width)/2;
$(slide_image).css("margin-left",margin);
}
}
for(var count=1;count<=max_count;count++)
{
var count_string = count.toString();
var img_name = "img" + count_string;
var slide_image = $('.slider > li:nth-child(" + count + ")');
var img = new Image();
img.onload = (function(slide_image,img){
return function() {fn_get_natural_dim(slide_image,img);};
})(slide_image,img);
img.src = $(slide_image).attr("src");
}
});
i want the variable slide_image to select the nth list, where n should be the same as the variable count.
i added the + signs (although i dont know why i have to) and made the quote symbols different, and yet it still doesnt work
You should do it like this:
$('.slider > li:nth-child(' + count + ')');
The problem is that you're not closing the strings/segments surrounding the variable, so:
'.slider > li:nth-child(" + count + ")'
Is just a long string, a selector which makes no sense; that's why it matches nothing, you have to actually separate the sections by ending the static parts with the same kind of quote...

javascript: Preload ONE image at a time

I currently have a rotating background that preloads the images when the page is loaded. However, I would like to preload the images one at a time, if that is even possible.
My code:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
$(document).ready(function () {
var b = [<? $img = getContents(ROOT."/img/backgrounds/");
foreach($img as $i)
{ echo "\"" . $i . "\"";
if($i != end($img)) echo ",";
}
?>];
preload(b);
var r=Math.floor(Math.random()*b.length)
$('#bg1').css("background-image", "url('/img/backgrounds/"+b[r]+"')");
var alt = false;
var delay = 50000;
var speed = ((delay / 3)*2);
var opacity = 1;
setInterval(function() {
var r=Math.floor(Math.random()*b.length);
//put the individual preload code here
switch(alt)
{ case true:
$('#bg1').css("background-image", "url('/img/backgrounds/"+b[r]+"')");
$('#bg1').fadeTo(speed,opacity);
$('#bg2').fadeOut(speed);
break;
case false:
$('#bg2').css("background-image", "url('/img/backgrounds/"+b[r]+"')");
$('#bg2').fadeTo(speed,opacity);
$('#bg1').fadeOut(speed);
break;
}
alt = !alt;
}, delay);
});
The code above works fine. If there is a better way please let me know! But otherwise how can I just preload one image at a time?
function preload(arrayOfImages, index) {
index = index || 0;
if (arrayOfImages && arrayOfImages.length > index) {
var img = new Image();
img.onload = function() {
console.log(arrayOfImages[index] + " loaded successfully");
preload(arrayOfImages, index + 1);
};
img.src = arrayOfImages[index];
}
}
fiddle

Categories

Resources