What I'm trying to do is get 20 or so images from a folder on the server and display them using masonry.desandro and once scrolled to the bottom it will load another set of 20 images. Just like pinterest.
Currently it does load the images 20 at a time, the only problem I'm having is the first 20 display Masonry but when the next 20 load they aren't displaying Masonry
HTML
<div class="grid">
</div>
Json
$(document).ready(function() {
// The max number of images to be loaded at a time.
var limit = 16;
// JSON data will be assigned to this
var images = "";
// to remember where in JSON we are
// initialize to the value of limit - so that we can load in images
// before page scroll.
var currentIndex = limit;
// When there are fewer than `limit` images left, this
// value will be the difference between the current index
// and the length of the images array.
var stop = limit;
var grid = $(".grid");
// Make a GET request to the api
$.getJSON("***********************/newsite/api.php", function(data) {
// save the data to be used later.
images = data.weddingCakes;
console.log(data);
})
// create the first round of images.
.done(function() {
var html = "";
for (var i = 0; i < limit; i++) {
html += '<div class="grid-item"><img src="' + images[i] + '"></div>';
}
grid.append(html)
.masonry({
gutter: 3,
itemSelector: '.grid-item',
animate: true
});
console.log("masonry")
})
.error(function() {
console.log("error");
});
$(document).scroll(function() {
// get the scoll position with support for IE
// see http://jsbin.com/egegu3/6/edit?html,js,output
// for original code.
var totalHeight, currentScroll, visibleHeight;
if (document.documentElement.scrollTop) {
currentScroll = document.documentElement.scrollTop;
} else {
currentScroll = document.body.scrollTop;
}
totalHeight = document.body.offsetHeight;
visibleHeight = document.documentElement.clientHeight;
// only load more images if the scroll bar is at the bottom
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
var diff = images.length - currentIndex;
// if the difference is > 0 then there are more images in the array
if (diff > 0) {
stop = diff > limit ? limit : diff;
getImages(currentIndex, stop);
currentIndex += stop;
}
// otherwise, reset the index before calling getImages()
else {
currentIndex = 0;
stop = diff > limit ? limit : diff;
getImages(currentIndex, stop);
currentIndex += stop;
}
}
});
});
// gets the path for each image from index to stop
function getImages(index, stop) {
var html = "";
// create the img tags.
for (var i = index; i < index + stop; i++) {
html += '<div class="grid-item"><img src="' + images[i] + '"></div>';
}
var str = $(html);
grid.append(html).masonry("appended", str);
}
});
My JSfiddle
you were almost correct just missed a small part while reading documentation, here while appending elements you need to append HTML elements and pass same to the masonry function.
You were adding string to append and later on you were passing element to the masonry, Also this code -> var str = $(html); returns Array of HTML elements rather than string, so you need to add these elements to the grid and pass it to masonry
so your little change would be...
// gets the path for each image from index to stop
function getImages(index, stop) {
var html = "";
// create the img tags.
for (var i = index; i < index + stop; i++) {
html += '<div class="grid-item"><img src="' + images[i] + '"></div>';
}
var str = $(html);
grid.append(str).masonry("appended", str); // This line is a change
}
I have dummy fiddle for this as well
Related
I was able to list the movies from JSON file but I want to increase total number of the limited variable so when I scroll down I add 10 more movies
Here's my code
(function () {
$.getJSON("m.json", function (movie) {
var limitMovies = [];
var totalMovies = 10;
for (var i = 0; i < totalMovies; i++) {
limitMovies.push(movie[i]);
}
var movies = document.getElementById('movies');
for ( i = 0; i < limitMovies.length; i++ ) {
var addMovies = '<a id="' + i + '" class="Movie" target="_blank" href="'+ limitMovies[i].url + '/"><img src="'
+ limitMovies[i].Poster + '"/></a>';
movies.innerHTML += addMovies;
}
i = 20;
$(window).scroll(function(){
});
});
}());
I have refactored few bits of your code, and the change I have done is load all movies from file, but append them to container on scroll event. You can take a look at a working version here.
;
(function () {
let loadedMovies = [];
let lastMoviePosition = 0;
let container = $('#movies');
$.getJSON("m.json", function (movies) {
if(movies && movies.length > 0){
loadedMovies = movies;
addMovies(10);
}
});
let addMovies = (n) => {
for(let i=0; i<n && lastMoviePosition < loadedMovies.length; i++){
var movie = '<a id="' + i + '" class="Movie" target="_blank" href="'+ limitMovies[lastMoviePosition].url + '/"><img src="'
+ limitMovies[lastMoviePosition].Poster + '"/></a>';
container.append(movie);
lastMoviePosition++;
}
};
$(window).scroll(function(){
addMovies(10);
});
})();
Add var limitMovies; into the first line of your code to make it globally accessible. Remove all var in front of other limitMovies declarations. Then do:
$(window).scroll(function(){
limitMovies+=10;
});
However, that wont answer your real question. Just increasing the counter wont work. You need to rerun the for loop to parse from that array. Also the scroll will fire a thousand times a second, you need another way of detecting it. May have a look at:
https://www.sitepoint.com/jquery-infinite-scrolling-demos/
You need to restructure your whole code, this wont fit into an answer on SO...
Right now I am animating an image by stringing multiple images together with setInterval(showNextSlide, 100); and it works really well.
The only thing that I'm running into problems with is adding values dynamically into var slides = [src, ] the while loop just loads the final image.
Also the way the images are saved the increment moves to the next zero so 01009 converts to 01010 whenever I use my loop it will convert to 010010 note the extra zero at the end.
Javascript
window.onload = function() {
var img = 0
while (img < 15) {
img++;
}
var src = 'assets/images/earth/Sequence%0100' + img + '.jpg.';
var slides = [src, ],
index = 0,
timer = 0;
// Show the first slide
showNextSlide();
// Show "next" slide every five seconds
timer = setInterval(showNextSlide, 100);
// The function we call to show the "next" slide
function showNextSlide() {
if (index >= slides.length) {
index = 0;
}
document.getElementById('earth').src = slides[index++];
}
};
JsFiddle
try this:It will keep on changing the image src of earth based on the index value.
Update based on JEES Comment.
<script>
window.onload = function() {
var i = 0
var slides = [];
while (i < 200) {
if(i <= 9){ img= '0100' + i++; }
else if(i <= 99){ img= '010' + i++; }
else{ img= '01' + i++; }
var src = 'assets/images/earth/Sequence%' + img + '.jpg';
slides.push(src);
}
console.log(slides);
index = 0,
timer = 0;
// Show the first slide
showNextSlide();
// Show "next" slide every five seconds
timer = setInterval(showNextSlide, 100);
// The function we call to show the "next" slide
function showNextSlide() {
if (index >= slides.length) {
index = 0;
}
document.getElementById('earth').src = slides[index++];
}
};
</script>
<img src="" id="earth">
Please Try It :
var img = 0;
var slides = new Array();
while (img < 5) {
img++;
var src = 'assets/images/earth/Sequence%0100' + img + '.jpg';
slides.push(src);
}
This is part of the answer and it will fix it when img value is 9 or 99 since he has 200 images, if images number > 1000 he'd need another one when img value 999.. please tell me if i should delete this answer:
UPDATED:
var img = 0;
while(img < 200) {
if (img < 10) { imgURL = '0100' + img; }
else if (img < 100) { imgURL = '010' + img;}
else { imgURL = '01' + img; }
slides.push('assets/images/earth/Sequence%' + imgURL + '.jpg');
img++;
}
check this Fiddle to see it in action..
I want to analyse every image of an article and set an class for all images smaller/equal than perhaps 400px (and another class for images bigger than 400px) so that I can give them a specific style.
In jQuery it would be perhaps something like this
$('div#content').find('img').each(function () {
var $this = $(this), width = $this.width();
if (width <= 400) {
$this.addClass('small_img');
}
var $this = $(this), width = $this.width();
if (width > 400) {
$this.addClass('large_img');
}
});
But I need it to be in pure Javascript. As a stupid Journalist and Webdesigner I don't get it... If you could help me, I would be very thankful.
You mean something FAST and short like this?
window.onload = function() {
var n=document.getElementById('content').getElementsByTagName('img'),
i=n.length;
while(i--){
n[i].className = n[i].clientWidth > 400 ? 'large_img' : 'small_img' ;
}
};
See this fiddle for working example.
Also read this question on SO for selecting a method to fetch the (computed) width.
window.onload = function() {
var content = document.getElementById('content');
if (content) {
var img = content.getElementsByTagName('img');
for (var i = 0, count = img.length; i < count; i++) {
if (img[i].offsetWidth <= 400) {
img[i].className += ' small_img';
} else {
img[i].className += ' large_img';
}
}
}
};
Something like this should work:
// Find the parent container 'div#content'
var container = document.getElementById( "content" ),
// Find all images within the parent
images = container.getElementsByTagName( "img" ),
// Total number of images to check
len = images.length,
// Loop counter
i = 0,
// Represents the current image in the loop
image;
// Loop through all the images
for ( ; i < len; i++ ) {
// Access the current image
image = images[ i ];
// Use the ternary operator to assign one of two classes, based on width
image.className += ( image.clientWidth > 400 ) ? " large_img" : " small_img";
}
Hope that helps. Cheers!
var contentDiv = document.getElementById('content');
var imgs = contentDiv.getElementsByTagName('img');
for(i=0;i<img.length;i++){
var img = imgs[i];
if(img.clientWidth <= 400) img.className += " small_img"
else img.className += " large_img"
}
I am looking for a way to load several hidden thumbnails on a page (around 500), calculate their total widths, and show their container once they are all loaded.
The problem is that the container keeps showing before they all are loaded.
Here is the simplified snippet i extracted from my script:
// $('#thumbScroller') is the container, and is initially hidden.
var imgs = ['http://www.google.com/images/nav_logo95.png', 'http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=4'];
for(var i = 0; i < i.length; i++){
var url = imgs[i];
$('#thumbScroller').append('<img src="' + url + '" class="thumb" />');
// all elements were appened at this point
if(i == $this.totalImages-1 ){
//variable to hold total container width
var totalContent=0;
// loop through images to calculate total width
$('#thumbScroller img').each(function (s) {
totalContent += $(this).width();
//last image, show interface elements
if(s == $('#thumbScroller img').length-1){
$('#thumbScroller').width(totalContent).fadeIn();
};
});
}
}
Any help would be appreciated!
for(var i = 0; i < imgs.length; i++){
var url = imgs[i];
$('#thumbScroller').append('<img src="' + url + '" class="thumb" />');
}
var imgCount = $('#thumbScroller img').length;
var totalContent=0;
$('#thumbScroller img').load(function() {
if (!--imgCount) {
$('#thumbScroller').width(totalContent);
$('.loader').removeClass('visible');
$('.interface').removeClass('hidden');
} else {
totalContent += $(this).width();
console.log('continue...');
}
});
Because a hidden element does not have width, you need to move the element "off page" while you are performing your calculations, then move it back when done. Note, if you can't move the container, you could add the images to a different container that is "off page" while you calculate the widths, then move them into the original container when done.
var imgs = ['http://www.google.com/images/nav_logo95.png', 'http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=4'];
$('#thumbScroller').css({position: 'absolute', left: '-99999px'});
for(var i = 0; i < i.length; i++){
var url = imgs[i];
$('#thumbScroller').append('<img src="' + url + '" class="thumb" />');
// all elements were appened at this point
if(i == $this.totalImages-1 ){
//variable to hold total container width
var totalContent=0;
// loop through images to calculate total width
$('#thumbScroller img').each(function (s) {
totalContent += $(this).width();
//last image, show interface elements
if(s == $('#thumbScroller img').length-1){
$('#thumbScroller').width(totalContent);
$('.loader').removeClass('visible');
$('.interface').removeClass('hidden');
};
});
}
}
$('#thumbScroller').css({position: '', left: ''});
You have a div, with 3 images in it.
How to create a simple slideshow that cycles through the images, and displays each image for 5 seconds and goes back to the first image when done and continues looping.
Without using jquery or any other framework.
(function () {
var imgs = document.getElementById('your_div').getElementsByTagName('img'),
index = 0;
imgs[0].style.display = 'block';
setInterval(function () {
imgs[index].style.display = 'none';
index = (index + 1) % imgs.length;
imgs[index].style.display = 'block';
}, 5000);
}());
Example HTML: http://jsfiddle.net/Zq7KB/1/
Edit: Saw a more elegant example above that used .length.
You can use setInterval to set up the timed callback, and set the src of an img element:
window.onload = function() {
var slides = [ "path_to_image_one",
"path_to_image_two",
"path_to_image_three" // ...
],
index = 0,
timer = 0;
// Show the first slide
showNextSlide();
// Show "next" slide every five seconds
timer = setInterval(showNextSlide, 5000);
// The function we call to show the "next" slide
function showNextSlide() {
if (index >= slides.length) {
index = 0;
}
document.getElementById('theImage').src = slides[index++];
}
};
...where your markup for the image is:
<img id="theImage" src="path_to_initial_placeholder">
Note that I've stored the timer handle in timer but not used it. This is just because you might use it to cancel the timer if you need to stop the slideshow.
Update: Just saw that you want to get the images from a div somewhere (whereas above I've supplied the paths in the code itself). Simple enough to create slides dynamically; revised edition of the above that grabs the images that are direct children of the div with the ID "theDiv":
window.onload = function() {
var slides = [],
index = 0,
timer = 0,
node;
// Get the slides
for (node = document.getElementById('theDiv').childNodes;
node;
node = node.nextSibling) {
if (node.nodeType == 1 && node.tagName == "IMG") {
slides.push(node.src);
}
}
// Show the first slide
showNextSlide();
// Show "next" slide every five seconds
timer = setInterval(showNextSlide, 5000);
// The function we call to show the "next" slide
function showNextSlide() {
if (index >= slides.length) {
index = 0;
}
document.getElementById('theImage').src = slides[index++];
}
};
Well you'd have to get a handle for the <div> first, so if it has an "id" value:
var theDiv = document.getElementById("imgContainer");
Now you just have to set up a timer to cycle through the images:
(function(div, sleep) {
var idx = 0;
var imgs = div.getElementsByTagName('img');
function showOne() {
for (var i = 0; i < imgs.length; ++i)
imgs[i].style.display = 'none';
imgs[idx].style.display = '';
idx = (idx + 1) % imgs.length;
setTimeout(showOne, sleep);
}
showOne();
})(theDiv, 5000);
var image = new Array('/img/1.jpg', '/img/2.jpg', '/img/3.jpg');
setTimeout("show_next()",5000);
function show_next()
{
var container = document.getElementById('image_container');
container.innerHTML = "<img src='" + image[i] + "' />";
if(i==2) { i = 1; }else { i = i + 1; }
}
I thought this was a nice simple answer, but there were a couple of errors.
setInterval rather than setTimeout and the initial index was not set. I also amended to load first image immediately.
var image = new Array('imgs/18/P1050294-XL.jpg', 'imgs/18/P1050293-XL.jpg', 'imgs/18/P1040984-XL.jpg', 'imgs/18/P1040983-XL.jpg', 'imgs/18/P1040982-XL.jpg');
var path = 'mypath';
document.getElementById('slideShow').innerHTML = "<img width='600px' src='" + path + image[0] + "' />" // Load First image
var i = 1; // Set counter to second image, for first use of loop
setInterval("show_next(path)",5000);
function show_next(path)
{
var container = document.getElementById('slideShow');
container.innerHTML = "<img width='600px' src='" + path + image[i] + "' />";
if(i==4) { i = 0; } else { i = i + 1; }
}