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;
}
}
Related
I'm trying to have an image gallery on my site, where I have a counter in the background image source, and when a button is clicked, the counter goes up, changing the background image.
But I want the counter to reset, if the image file doesn't exist.
How would I achieve this?
HTML
<div></div>
<button>click</button>
Javascript
var div = document.querySelector("div");
var button = document.querySelector("button");
var counter = 1;
div.style.backgroundImage = "url(image1.jpg)";
button.addEventListener("click", function() {
counter++;
div.style.backgroundImage = "url(image" + counter + ".jpg)";
console.log(counter + " " + div.style.backgroundImage);
if (div.style.backgroundImage === undefined) { counter = 1 } // something like this?
});
There are no JS callbacks for css styles. There is no way to know if a background image loaded successfully or not wait plain JS. It is necessary to load the image twice - once to check.
For that, you can use something like this:
function imageExists(image_url){
var http = new XMLHttpRequest();
http.open('HEAD', image_url, false);
http.send();
return http.status != 404;
}
And refactor your code to pass the image url to the function.
var div = document.querySelector("div");
var button = document.querySelector("button");
var counter = 1;
div.style.backgroundImage = "url(image1.jpg)";
button.addEventListener("click", function() {
counter++;
var imageUrl = "image" + counter;
if (imageExists(imageUrl)){
//Image can be loaded
div.style.backgroundImage = "url(image" + counter + ".jpg)";
console.log(counter + " " + div.style.backgroundImage);
} else {
//Image cannot be loaded
counter = 1;
div.style.backgroundImage = "url(image" + counter + ".jpg)";
}
// something like this?
});
I have a checkbox. I want a div which is on the bottom of my page to float next to the checkbox when the checkbox has been clicked.
How can I do this?
Here is some code that is working for my mouseovers. Its pretty far beyond my level. Is there an easier way, or way I can use this code for checkboxes as well?
function addreflinkpreview(e) {
var c;
var d = "srcElement";
var f = "href";
this[f] ? c = this : c = e[d];
ainfo = c.className.split('|');
var g = document.createElement('div');
g.setAttribute("id", "preview" + c.className);
g.setAttribute('class', 'reflinkpreview');
g.setAttribute('className', 'reflinkpreview');
if (e.pageX) {
g.style.left = '' + (e.pageX + 50) + 'px'
} else {
g.style.left = (e.clientX + 50)
}
var h = document.createTextNode('');
g.appendChild(h);
var i = c.parentNode;
var j = i.insertBefore(g, c);
new Ajax.Request(ku_boardspath + '/read.php?b=' + ainfo[1] + '&t=' + ainfo[2] + '&p=' + ainfo[3] + '&single',{
method: 'get',
onSuccess: function(a) {
var b = a.responseText || _("something went wrong (blank response)");
j.innerHTML = b
},
onFailure: function() {
alert('wut')
}
})
}
One way you may be able to achieve this is with positioning and transitions. Take the screen coordinates of the click event and then absolute position the div next to the coordinate by adding or subtracting from the x-coordinate.
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.
Ok i have finish this code
http://jsfiddle.net/xHL35/9/
I just made some css changes, and rename image_wrap to image_wrap_galeria
here http://queretaro.orsilin.com.mx/index.php?page=item/view/15/Probando
But the counter is really not counting the imgs on .items.
I really tried to debug this one. i cant find the mistake
Here is my JS code.
<script>
$(function() {
$(".scrollable").scrollable();
var scrollapi = $(".scrollable").data('scrollable');
$(".items img").click(function() {
// see if same thumb is being clicked
if ($(this).hasClass("active")) { return; }
// calclulate large image's URL based on the thumbnail URL (flickr specific)
var url = $(this).attr("src").replace("t_", "");
// get handle to element that wraps the image and make it semi-transparent
var wrap = $("#image_wrap_galeria").fadeTo("medium", 0.5);
var wrap2 = $("#mainim");
// the large image from www.flickr.com
var img = new Image();
// call this function after it's loaded
img.onload = function() {
// make wrapper fully visible
wrap.fadeTo("fast", 1);
// change the image
wrap.find("img").attr("src", url);
wrap2.find("img").attr("src", url);
};
// begin loading the image from www.flickr.com
img.src = url;
// activate item
$(".items img").removeClass("active");
$(this).addClass("active");
// when page loads simulate a "click" on the first image
}).filter(":first").click();
$("img[rel]").overlay({
// some mask tweaks suitable for modal dialogs
mask: {
color: '#ebecff',
loadSpeed: 200,
opacity: 0.9
},
closeOnClick: true,
onBeforeLoad: function() {
var items = $('.items'),
count = items.find("img").length,
current = items.find('.active'),
currentIndex = current.index("img");
$("#imageCounter").html( currentIndex+" of "+count);
}
});
//NExt BTN
$(".nextImg").click(function(){
// Count all images
var items = $('.items'),
images = items.find('img'),
count = images.length,
currentImage = items.find('.active'),
currentImageIndex = images.index(currentImage),
next = $(images.get(currentImageIndex + 1)),
nextImageIndex = images.index(next);
if ( currentImageIndex === (count - 1) ){
next = $(images.get(0));
nextImageIndex = images.index(next);
}
if (nextImageIndex === 0) {
scrollapi.begin(200);
} else if ( nextImageIndex % 4 === 0 && nextImageIndex > 0) {
scrollapi.next(200);
}
// Get the current image number
var current = $(next.index("img"));
var nextUrl = next.attr("src").replace("t_", "");
// get handle to element that wraps the image and make it semi-transparent
var wrap = $("#image_wrap_galeria").fadeTo("medium", 0.5);
var wrap2 = $("#mainim");
// the large image from www.flickr.com
var img = new Image();
// call this function after it's loaded
img.onload = function() {
// make wrapper fully visible
wrap.fadeTo("fast", 1);
// change the image
wrap.find("img").attr("src", nextUrl);
wrap2.find("img").attr("src", nextUrl);
};
// begin loading the image from www.flickr.com
img.src = nextUrl;
$("#imageCounter").html((nextImageIndex + 1) +" of "+count);
// activate item
$(".items img").removeClass("active");
next.addClass("active");
});
//PREV BTN
$(".prevImg").click(function(){
// Count all images
var items = $('.items'),
images = items.find('img'),
count = images.length,
currentImage = items.find('.active'),
currentImageIndex = images.index(currentImage),
prev = $(images.get(currentImageIndex - 1)),
prevImageIndex = images.index(prev);
// var prev = $(".items").find(".active").prev("img");
if(currentImageIndex === 0){
prev = $(images.get(count-1));
prevImageIndex = images.index(prev);
}
if(prevImageIndex === (count - 1)) {
// We have reached the end - start over.
scrollapi.end(200);
} else if ( (prevImageIndex + 1) % 4 === 0 ) {
scrollapi.prev(200);
}
// Get the current image number
var current = (prev.index("img"));
var prevUrl = prev.attr("src").replace("t_", "");
// get handle to element that wraps the image and make it semi-transparent
var wrap = $("#image_wrap_galeria").fadeTo("medium", 0.5);
var wrap2 = $("#mainim");
// the large image from www.flickr.com
var img = new Image();
// call this function after it's loaded
img.onload = function() {
// make wrapper fully visible
wrap.fadeTo("fast", 1);
// change the image
wrap.find("img").attr("src", prevUrl);
wrap2.find("img").attr("src", prevUrl);
};
// begin loading the image from www.flickr.com
img.src = prevUrl;
$("#imageCounter").html((prevImageIndex + 1) +" of "+count);
// activate item
$(".items img").removeClass("active");
prev.addClass("active");
});
});
</script>
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