Prev & Next button with counter for overlay using jQuery - javascript

I build this image gallery using jquerytools, I'm using scrollable div on thumbs and overlay on the main image... Everything works like charm..
EDIT: Before I make this a bounty...I have to explain that I need something clean and simple like this, because the images come from php (encrypted) , and I can't modify this, just the "view" as I need to achieve this with something like classes and ids. This is why I try this but...
The problem is I need to insert a Next and Prev Buttons when you are viewing the overlay... so you can go trough the images, once the overlay has been loaded..
I have made this fiddle for you my teachers full of wisdom can see what I am saying. http://jsfiddle.net/s6TGs/5/
I have really tried. but api.next() it's working for the scrolling on the thumbs , so I don't know how can I tell this script.. hey if next is clicked, yo pls insert next url on thubs, if previous btn is clicked, pls go to prev url on thumbs.. But I can't
Also and no less important a Counter like 1/8 have to be displayed =S... how in the name of JavaScript you do this..
Here is My code
$(function() {
$(".scrollable").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").fadeTo("medium", 0.5);
var wrap2 = $("#mies1");
// 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();
});
// This makes the image Overlay with a div and html
$(document).ready(function() {
$("img[rel]").overlay({
// some mask tweaks suitable for modal dialogs
mask: {
color: '#ebecff',
loadSpeed: 200,
opacity: 0.9
},
closeOnClick: true
});
});
I know here is part of my answer I just can make it work :(
http://jquerytools.org/demos/combine/portfolio/index.html
EDIT: Thanks to the first answer by QuakeDK I almost achieve the goal.. But the counter is not ok, also when you get to the 4 image (number 5 on counter) you cant go to the 5th thumb .. This is the CODE with that answer integrated
http://jsfiddle.net/xHL35/5/
And here is the CODE for PREV & NEXT BUTTON
//NExt BTN
$(".nextImg").click(function(){
// Count all images
var count = $(".items img").length;
var next = $(".items").find(".active").next("img");
if(next.is(":last")){
next = $(".items").find(".active").parent().next("div").find("img:first");
if(next.index() == -1){
// We have reached the end - start over.
next = $(".items img:first");
scrollapi.begin(200);
} else {
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").fadeTo("medium", 0.5);
var wrap2 = $("#mies1");
// 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("Image: "+current+" of "+count);
// activate item
$(".items img").removeClass("active");
next.addClass("active");
});
//PREV BTN
$(".prevImg").click(function(){
// Count all images
var count = $(".items img").length;
var prev = $(".items").find(".active").prev("img");
if(prev.is(":first")){
prev = $(".items").find(".active").parent().prev("div").find("img:first");
if(prev.index() == -1){
// We have reached the end - start over.
prev = $(".items img:first");
scrollapi.begin(200);
} else {
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").fadeTo("medium", 0.5);
var wrap2 = $("#mies1");
// 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("Image: "+current+" of "+count);
// activate item
$(".items img").removeClass("active");
prev.addClass("active");
});
There must be a reward option here, if somebody help me I give you 20box! jajaja I'm desperate. Because now I also need to display title for each image, and I think it's the same process of URL replace, but next & prev is just something I can't manage.. Post the full solution and your email on paypal, I will pay 20!

Okay, never tried jQueryTOOLS, so thought it would be fun to play with.
first of all, here's the JSFiddle I just created: http://jsfiddle.net/xHL35/1/
Now, the API calls need a variable to hold it
$(".scrollable").scrollable();
var scrollapi = $(".scrollable").data("scrollable");
Now scrollapi, can call the functions like this:
scrollapi.next(200);
I've copied your own code for choosing image and just rewritten it to fit the NEXT image.
I haven't created the PREV function, but should not be that hard to reverse the NEXT function.
$(".nextImg").click(function(){
// Count all images
var count = $(".items img").length;
// Finding the next image
var next = $(".items").find(".active").next("img");
// Is the next image, the last image in the wrapper?
if(next.is(":last")){
// If it is, go to next DIV and get the first image
next = $(".items").find(".active").parent().next("div").find("img:first");
// If this dosn't exists, we've reached the end
if(next.index() == -1){
// We have reached the end - start over.
next = $(".items img:first");
scrollapi.begin(200);
} else {
// Not at the end, show next div in thumbs
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").fadeTo("medium", 0.5);
var wrap2 = $("#mies1");
// 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;
// Show the counter
$("#imageCounter").html("Image: "+current+" of "+count);
// activate item
$(".items img").removeClass("active");
next.addClass("active");
});
Hoping you can use this to develop the rest of the gallery.

Related

Image source not changing with JavaScript

Please answer this question, as I am struggling a lot with it.
I am trying to change image source on mouse over. I am able to do it, but image is not displaying on page.
I am trying to change image source to cross domain URL. I can see that in DOM image source is changing but on page its not.
I have tried all solutions mentioned in LINK, but none of them is working.
Please let me solution to problem.
NOTE:
I can see in network tab image is taking some time to download (about 1 sec).
It is an intermediate issue, sometime image is loading and sometimes its not
CODE:
document.getElementsByTagName('img')[0].addEventListener('mouseover', function()
{
document.getElementsByTagName('img')[0].setAttribute('src', 'url/of/the/image');
});
have you tried loading images before everything else?
function initImages(){
var imC = 0;
var imN = 0;
for ( var i in Images ) imN++;
for(var i in Images){
var t=Images[i];
Images[i]=new Image();
Images[i].src=t;
Images[i].onload = function (){
imC++;
if(imC == imN){
console.log("Load Completed");
preloaded = 1;
}
}
}
}
and
var Images = {
one image: "path/to/1.png",
....
}
then
if( preloaded == 1 ){
start_your_page();
}
Here the code that will remove the img tag and replace it with a new one:
document.getElementsByTagName('img')[0].addEventListener('mouseover', function() {
var parent = document.getElementsByTagName('img')[0].parentElement;
parent.removeChild(document.getElementsByTagName('img')[0]);
var new_img = document.createElement("img");
new_img.src = "https://upload.wikimedia.org/wikipedia/commons/6/69/600x400_kastra.jpg";
parent.appendChild(new_img);
});
<img src="https://www.w3schools.com/w3images/fjords.jpg">
I resolved the issue using code:
function displayImage() {
let image = new image();
image.src="source/of/image/returned/from/service";
image.addEventListener('load', function () {
document.getElementsByTagName('img')[0].src = image.src;
},false);
}
Here in code, I am attaching load event to image, source of image will be changed after image is loaded.

Issue with image load recursive chain on slow network/mobile

So basically I have a page with a few sections. Each sections contains 5-30 image icons that are fairly small in size but large enough that I want to manipulate the load order of them.
I'm using a library called collagePlus which allows me to give it a list of elements which it will collage into a nice image grid. The idea here is to start at the first section of images, load the images, display the grid, then move on to the next section of images all the way to the end. Once we reach the end I pass a callback which initializes a gallery library I am using called fancybox which simply makes all the images interactive when clicked(but does not modify the icons state/styles).
var fancyCollage = new function() { /* A mixed usage of fancybox.js and collagePlus.js */
var collageOpts = {
'targetHeight': 200,
'fadeSpeed': 2000,
'allowPartialLastRow': true
};
// This is just for the case that the browser window is resized
var resizeTimer = null;
$(window).bind('resize', function() {
resetCollage(); // resize all collages
});
// Here we apply the actual CollagePlus plugin
var collage = function(elems) {
if (!elems)
elems = $('.Collage');
elems.removeWhitespace().collagePlus(collageOpts);
};
var resetCollage = function(elems) {
// hide all the images until we resize them
$('.Collage .Image_Wrapper').css("opacity", 0);
// set a timer to re-apply the plugin
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
collage(elems);
}, 200);
};
var setFancyBox = function() {
$(".covers").fancybox({/*options*/});
};
this.init = function(opts) {
if (opts != null) {
if (opts.height) {
collageOpts.targetHeight = opts.height;
}
}
$(document).ready(function() {
// some recursive functional funk
// basically goes through each section then each image in each section and loads the image and recurses onto the next image or section
function loadImage(images, imgIndex, sections, sectIndex, callback) {
if (sectIndex == sections.length) {
return callback();
}
if (imgIndex == images.length) {
var c = sections.eq(sectIndex);
collage(c);
images = sections.eq(sectIndex + 1).find("img.preload");
return loadImage(images, 0, sections, sectIndex + 1, callback);
}
var src = images.eq(imgIndex).data("src");
var img = new Image();
img.onload = img.onerror = function() {
images[imgIndex].src = src; // once the image is loaded set the UI element's source
loadImage(images, imgIndex + 1, sections, sectIndex, callback)
};
img.src = src; // load the image in the background
}
var firstImgList = $(".Collage").eq(0).find("img.preload");
loadImage(firstImgList, 0, $(".Collage"), 0, setFancyBox);
});
}
}
From my galleries I then call the init function.
It seems like my recursive chain being triggered by img.onload or img.onerror is not working properly if the images take a while to load(on slow networks or mobile). I'm not sure what I'm missing here so if anyone can chip in that would be great!
If it isn't clear what is going wrong from the code I posted you can see a live example here: https://www.yuvalboss.com/albums/olympic-traverse-august-2017
It works quite well on my desktop, but on my Nexus 5x it does not work and seems like the finally few collage calls are not happening. I've spent too long on this now so opening this up to see if I can get some help. Thanks everyone!
Whooooo I figured it out!
Was getting this issue which I'm still unsure about what it means
[Violation] Forced reflow while executing JavaScript took 43ms
Moved this into the callback that happens only once all images are loaded
$(window).bind('resize', function() {
resetCollage(); // resize all collages
});
For some reason it was getting called early even if the browser never resized causing collage to get called when no elements existed yet.
If anyone has any informative input as to why I was getting this js violation would be great to know so I can make a better fix but for now this works :):):)

Javascript Slide show

I have a simple fading slide-show which works great for a while, but runs to about 300 images. After a while it starts jumping and missing some, which I assume is down to too many images being loaded. Is there a way of 'unloading' images once viewed, or is it likely to be something else?
Let all images load before you display the slide show, or skip not loaded images.
You could do this like this for example:
var images = ['./path1.jpg', './path2.jpg']; // Array with all images
var imageCount, imagesLoaded, c;
imageCount = images.length; // Get images count
imagesLoaded = 0;
for (c = 0; c < imageCount ; c++){ // Loop thorough all images
var image = document.createElement('img'); // Create img tag
image.setAttribute('src', images[c]); // Set src attribute
document.body.appendChild(image); // Add img tag to body
image.onload = function() {
imagesLoaded++; // Add loaded image to loaded images count
console.log('Loaded: ' + imagesLoaded + '/' + imageCount); // debug
if (imagesLoaded == imageCount){ // when all images loaded
// Start your slideshow
}
}
}

How to add prev and next button in slide show

I just made this program for slide show it is working well but i want to use previous and next buttons in the slide show and i don't have any idea how to do that so i put this here please help for the same
var image1=new Image()
image1.src="slide/23.jpg"
var image2=new Image()
image2.src="slide/7.jpg"
var image3=new Image()
image3.src="slide/4.jpg"
var image4=new Image()
image4.src="slide/5.jpg"
var image5=new Image()
image5.src="slide/6.jpg"
</script>
<img id="myImg"src="slide/2.jpg" name="img" width="1000" height="250"/>
<script>
var step=1
function slideImages(){
if (!document.images)
return
document.images.img.src=eval("image"+step+".src")
if (step<5)
step++
else
step=1
setTimeout("slideImages()",3000)
}
slideImages()
</script>
You probably want to abstract away some code so it can be easily reused in your functions:
// Dealing with the counter:
var step;
var steps = 5;
function increment() {
s = (s + 1) % steps;
}
function decrement() {
s--;
if (s<0) s = steps-1;
}
// Dealing with the slide show:
function show() {
document.images.img.src=eval("image"+step+".src")
}
function next() {
increment();
show();
}
function prev() {
decrement();
show();
}
// Automatic sliding:
window.setInterval(next, 3000);
Also, i would reconsider your approach to storing images:
function createImgBySource(src){
var img = new Image();
img.src = src;
return img;
}
var images = [
createImgBySource('slide/23.jpg'),
createImgBySource('slide/7.jpg'),
createImgBySource('slide/4.jpg'),
createImgBySource('slide/5.jpg'),
createImgBySource('slide/6.jpg')
];
Now you can change the increment and decrement functions to use images.length instead of steps, so you can add more images without having to alter other variables. Also, your show() function should look like this (getting rid of the nasty eval):
function show() {
document.images.img.src = images[step];
}
Try the below code
var ss = new TINY.fader.init("ss", {
id: "slides", // ID of the slideshow list container
position: 0, // index where the slideshow should start
auto: 0, // automatic advance in seconds, set to 0 to disable auto advance
resume: true, // boolean if the slideshow should resume after interruption
navid: "pagination", // ID of the slide nav list
activeClass: "current", // active class for the nav relating to current slide
pauseHover: true, // boolean if the slideshow should pause on slide hover
navEvent: "click", // click or mouseover nav event toggle
duration: .25 // duration of the JavaScript transition in seconds, else the CSS controls the duration, set to 0 to disable fading
});
got from Here also here is a sample Fiddle
I would consider using something like jCarousel.
I think you are best putting all of your images into an array and then looking over it. I am assuming that the image tag with the ID 'myImg' is the one that you want to update, as such you should use document.getElementByID('myImg') and not document.images.img.src=eval("image"+step+".src") -- eval should also be avoided as the performance is poor and it can be dangerous.
Put this as the end of your page:
<script type="text/javascript">
(function(){
var step = 0;
var images = [image1, image2, image3, image4, image5];
var image = document.getElementByID('myImg');
var slideImages = function() {
image.src = images[step].src;
step++;
if (step == images.length){
step == 0;
}
setTimeout("slideImages()", 3000);
};
slideImages()
})();
</script>

Javascript image preloader doesn't show status

I put together an image preloader which works fine, but what doesn't work is updating the status after every image that has been loaded. Instead, all images are loaded and "done" (last line) is the only thing that shows up. It does work when I use an alert instead of the innerHTML command, but that is obviously of no use. What am I doing wrong?
<div id="preloader">
<span id="preloader_status"> </span>
<script language="JavaScript">
imageObj = new Image();
images = new Array();
images[0]="bigimage.gif"
images[1]="anotherbigimage.gif"
/* and so on */
var i = 0;
var o = (images.length);
for (i=0;i<o;i++) {
var status = (Math.round(100*(i/o)));
imageObj.src=images[i];
document.getElementById("preloader_status").innerHTML = status;
}
document.getElementById("preloader_status").innerHTML = "done";
</script>
</div>
To show image load progress, you will need to hook into the onload event for the images so you can track when their loading is actually complete. Images are loaded asychronously so assigning .src only STARTS the loading of the image. It is not completed until later when the onload handler is called. Because of that, your existing code will just immediately show "done" because it isn't tracking when the images are actually done loading.
In addition, you were successively assigning a new .src value to the same image object which is going to abort the previous image loading. You need to create a new image object for each new image you are loading.
You can fix your code like this:
<div id="preloader">
<span id="preloader_status"> </span>
<script language="JavaScript">
var imageSrcs = [
"bigimage.gif",
"anotherbigimage.gif"
/* and so on */
];
function preloadImages(list, statusID) {
var img, cnt = 0;
var progress = document.getElementById(statusID);
var preloads = [];
for (var i = 0; i < list.length; i++) {
img = new Image();
img.onload = function() {
++cnt;
var loadPercent = Math.round(100*(cnt/list.length));
progress.innerHTML = loadPercent;
if (cnt == list.length) {
progress.innerHTML = "done";
}
}
img.src = list[i];
preloads.push(img);
}
}
preloadImages(imageSrcs, "preloader_status");
</script>
</div>
The for loop will happen almost instantly, because images load asynchronously; setting imageObj.src will just start the image request and move on to the next. It will not block the execution of the loop. This will cause the effect you're seeing, i.e the last line of the code is executed straight away.
I think what you're looking for is the JavaScript Image onload event, which will fire when an image has finished loading.
var image = new Image();
image.onload = function() {
// always called
alert('image loaded');
};
image.src = 'image.jpg';
Code was pinched from this article.

Categories

Resources