We have this bug only in Safari browser (on iPad and iPhone too).Basically, when user visit page, it would show him images with articles, if he scroll down, it would load new articles but images are missing.
The thing I noticed is that images are here, but their height is equal to 0 - probbably something related to the imagesLoaded plugin.Bellow is our CommonJS code
define([
'imagesloaded',
'masonry-layout',
'vendor/infinitescroll'
], function(imagesLoaded, Masonry, infinitescroll){
$(document).ready(function() {
'use strict';
// Main content container
let gridSelector = 'div.Grid',
$container = $(gridSelector),
itemSelector = '.StandardArticle';
// Masonry + ImagesLoaded
$container.imagesLoaded(function(){
$container.layout = new Masonry(gridSelector, {
itemSelector: itemSelector,
percentPosition: true
});
});
// Infinite Scroll
$container.infinitescroll({
navSelector: "#infinite_navigation",
nextSelector: "#infinite_navigation a",
itemSelector: itemSelector,
dataType: 'html',
path: [$('#infinite_navigation a').attr('href') + '?page=', ''],
loadingImg: $('#infinite-loading-img').attr('src'),
loading: {
finishedMsg: 'All articles are loaded !'
}
},
function( newElements ) {
var $newElems = $( newElements ).css({opacity: 0});
$newElems.imagesLoaded(function(){
$newElems.animate({opacity: 1});
$container.layout.appended( $newElems );
});
}
);
});
});
There are no nothing weird in our CSS - pretty basic structure.
Related
I am new to web development. I am trying to use Isotope & infiniteScroll.js plugin & lightGallery.js to create a gallery. lightGallery.js isn't working on my code.
JS
let $grid = $('.grid').isotope({
itemSelector: 'none', // select none at first
layoutMode: 'masonry',
masonry: {
columnWidth: '.grid__col-sizer',
gutter: '.grid__gutter-sizer',
},
percentPosition: true,
stagger: 30,
// nicer reveal transition
visibleStyle: { transform: 'translateY(0)', opacity: 1 },
hiddenStyle: { transform: 'translateY(100px)', opacity: 0 },
});
// initial items reveal
$grid.imagesLoaded( function() {
$grid.removeClass('are-images-unloaded');
$grid.isotope( 'option', { itemSelector: '.grid__item' });
var $items = $grid.find('.grid__item');
$grid.isotope( 'appended', $items );
});
// init Infinte Scroll
// get Isotope instance
let iso = $grid.data('isotope');
$grid.infiniteScroll({
path: function() {
return `http://localhost/galleryy/details.php?pageno=${this.pageIndex}`;
},
// load response as JSON
responseBody: 'json',
outlayer: iso,
status: '.page-load-status',
history: false,
});
$grid.on( 'load.infiniteScroll', function( event, body ) {
// compile body data into HTML
let itemsHTML = body.map( getItemHTML ).join('');
// convert HTML string into elements
let $items = $( itemsHTML );
// append item elements
$items.imagesLoaded( function() {
$grid.append( $items ).isotope( 'appended', $items );
})
});
$grid.on( 'append.infiniteScroll', function( event, response, path, items ) {
$( items ).find('.lighgallery').lightGallery();
});
// load initial page
$grid.infiniteScroll('loadNextPage');
function getItemHTML({ image_name, image_title }) {
return `<div id="gal" class="grid__item itemm" data-src=="uploads/${image_name}">
<img src="uploads/${image_name}" alt="Photo by ${image_title}" /> </a>
<div class="itemm__details">
${image_title}
</div>
</div>`;
};
//light gallery targeting dev by id
lightGallery(document.getElementById('gal') , {});
I have read lightGallery docs. There it was said to initialize .lightGallery() on the newly appended content. But even if I try to append it doesn't work. Could anyone tell me how to append newly added content using JavaScript? Any suggestion would be helpful.
masonry infinite scroll append html5 videos overlapping
i am currently using imagesLoaded library which checks whether images are loaded then calls masonry.
But it was not working with html5 video tag, because of this videos gets overlapped on one another.
so i changed calling masonry from document.ready to window.load and removed call to imagesLoaded on initial loading i.e.
from this
$(document).ready(function(){
var $container = $('#media');
// layout Masonry again after all images have loaded
$container.imagesLoaded( function() {
$container.masonry({
"columnWidth": "." + "col-sm-2",
itemSelector: '.item',
gutter: 0,
});
$('.item').css('opacity', '1.0');
});
});
to this
$(window).load(function(){
var $container = $('#media');
$container.masonry({
"columnWidth": "." + "col-sm-2",
itemSelector: '.item',
gutter: 0,
});
$('.item').css('opacity', '1.0');
});
now html5 videos in masonry are not overlapping, and are rendering perfectly on page's first load i.e. initial load,
but as i am also using infinite-scroll which adds more images/videos on scrolling page down, so when new videos are being added to container they are being overlapped , this behavior is caused by early running of masonry before all the video elements are being loaded as imagesloaded cant check the videos loaded.
this is the code.
$(document).ready(function(){
var $container = $('#media');
var no_more_media = "<?= Lang::get('lang.no_more_to_load') ?>";
var loading_more_media = "<?= Lang::get('lang.loading_more_media') ?>";
$container.imagesLoaded(function(){
$container.masonry();
});
$container.infinitescroll({
loading: {
finished: undefined,
finishedMsg: "<p>" + no_more_media + "</p>",
img: "data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==",
msg: null,
msgText: "<div class='loading'><i></i><i></i><i></i></div><p>" + loading_more_media + "</p>",
selector: null,
speed: 'fast',
start: undefined,
},
navSelector : "ul.pagination",
// selector for the paged navigation (it will be hidden)
nextSelector : "ul.pagination a:first",
// selector for the NEXT link (to page 2)
itemSelector : ".container #media .item",
animate: false,
bufferPx: 160,
},
function( newElements ) {
// hide new items while they are loading
//var $newElems =
$.each($(newElements), function(index, value){
item_click_events($(value));
});
$( newElements ).css({ opacity: 0 });
$(newElements).imagesLoaded(function(){
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
}
);
});
});
i have tried changing document.ready to window.load in above code too, and removing running imagesloaded altogether, but its not working with infinitescroll.,
e.g. modified code
$(window).load(function(){
var $container = $('#media');
var no_more_media = "<?= Lang::get('lang.no_more_to_load') ?>";
var loading_more_media = "<?= Lang::get('lang.loading_more_media') ?>";
$container.masonry();
$container.infinitescroll({
loading: {
finished: undefined,
finishedMsg: "<p>" + no_more_media + "</p>",
img: "data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==",
msg: null,
msgText: "<div class='loading'><i></i><i></i><i></i></div><p>" + loading_more_media + "</p>",
selector: null,
speed: 'fast',
start: undefined,
},
navSelector : "ul.pagination",
// selector for the paged navigation (it will be hidden)
nextSelector : "ul.pagination a:first",
// selector for the NEXT link (to page 2)
itemSelector : ".container #media .item",
animate: false,
bufferPx: 160,
},
function( newElements ) {
// hide new items while they are loading
//var $newElems =
$.each($(newElements), function(index, value){
item_click_events($(value));
});
$( newElements ).css({ opacity: 0 });
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
});
});
there is another way i can solve this overlapping issue, by specifying video width and height, but as its responsive design, specifying video width and height breaks the responsiveness.
so my question is ,
is there any js library simmilar to imagesloaded which makes sure all videos are loaded and then i can call to masonry ?
or how can i make sure the videos wont get overlapped on infinitescroll ?
update 1 :
i have tried many techniques, for infinitescroll
$(newElements).load(function(){
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
});
doesnt loads new content after pagescroll.
$(window).load(function(){
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
});
doesnt loads new content after pagescroll.
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
overlaps video content
so i have came up with calling infinite-scroll early and slowing down the container.masonry by 3 seconds which is working perfectly for now., but still waiting for proper solution.
e.g.
bufferPx: 700,
setTimeout(function(){
var $newElems = $( newElements );
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true);
}, 3000);
above is delaying running masonry by 3 seconds.
i tried looking for something like window.load for div, but there is none, so my best option is check whether all the videos and images are loaded and then call masonry after calling infinite-scroll
added working demo http://plnkr.co/edit/46YzHBJ7eFAXfsPqZB1q
you can see the issue, by clicking run and scrolling down.
Looks like you can fix it by waiting for the loadeddata event of the video's
Here is the basic idea:
function waitForvidLoad(vids, callback) {
/* if no videos i.e. mobile mode only gifs and jpgs then call callback else masonry breaks.*/
if(vids.length === 0){
callback();
}
var vidsLoaded = 0;
vids.on('loadeddata', function() {
vidsLoaded++;
if (vids.length === vidsLoaded) {
callback();
}
});
}
.
var $container = $('#container');
var vids = $('#container').find('video');
waitForvidLoad(vids, function() {
$container.imagesLoaded(function() {
$container.masonry({
itemSelector: '.box',
columnWidth: 100
});
});
Working plunker here:
http://plnkr.co/edit/jXJ7oFxF3sFWBAJuBqdQ?p=preview
I am trying to get infinite scroll to work with Masonry.
+function ($) {
var $container = $('.masonry');
$container.imagesLoaded(function(){
$container.masonry({
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
itemSelector: '.item'
})
});
$container.infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector : '.item', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
}
);
}(jQuery);
It seems if I remove the imagesLoaded function and just call the masonry, it shows the images how Masonry intended, but doesn't infinitely scroll.
As it is I get an error:
Uncaught TypeError: undefined is not a function
I am using Foundation and I am calling my scripts in this order:
#import 'vendor/masonry.pkgd.js';
#import 'vendor/jquery.infinitescroll.min.js';
#import 'scripts.js';
Scripts included the code I have highlighted at the start. jQuery version is 2.0.3
you will have to add the imagesloaded library.
try this code
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-infinitescroll/2.0b2.120519/jquery.infinitescroll.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/masonry/3.1.2/masonry.pkgd.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/3.0.4/jquery.imagesloaded.min.js"></script>
(function() {
// Main content container
var $container = $('.masonry');
// Masonry + ImagesLoaded
$container.imagesLoaded(function(){
$container.masonry({
// selector for entry content
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
itemSelector: '.item'
});
});
// Infinite Scroll
$container.infinitescroll({
// selector for the paged navigation (it will be hidden)
navSelector : "#page-nav",
// selector for the NEXT link (to page 2)
nextSelector : "#page-nav a",
// selector for all items you'll retrieve
itemSelector : ".item",
// finished message
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// Trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
});
/**
* OPTIONAL!
* Load new pages by clicking a link
*/
// Pause Infinite Scroll
$(window).unbind('.infscr');
// Resume Infinite Scroll
$('.#page-nav a').click(function(){
$container.infinitescroll('retrieve');
return false;
});
})();
Well i'm trying to make Masonry work with infinite-scroll, and i found the official appended method (http://desandro.github.io/masonry/demos/infinite-scroll.html) and tried to make it work on my code. but i needed to change some of the $ to jQuery and now it's working as masonry but the infinte scroll still not working, and i'm wondering if i forgot a dollar sign to change to jQuery from my code, Please help me
<script >
jQuery(function(){
var $container = jQuery('ul.products');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: 'li.product',
columnWidth : 295,
isFitWidth: true,
gutterWidth : 2
});
});
$container.infinitescroll({
navSelector : '#page-nav-woo', // selector for the paged navigation
nextSelector : '.next', // selector for the NEXT link (to page 2)
itemSelector : 'li.product', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = jQuery( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
}
);
});
</script>
Ok the solution for my problem is like this:
1.i installed the wp-plugin
2.for callback section added:
var $newElems = jQuery( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.append( $newElems ).masonry( 'appended', $newElems, true );
});
3.behavior: Masonry
And it works like a charm! Thanks all!
Alternatively you can wrap your script in a closure:
(function($) {
// i can use $ instead of jQuery
} (jQuery));
or
(function(jQuery) {
// i can use jQuery instead of $
} ($));
How to catch "GET" parameter of masonry infinite scrolling for show number of page in url address.
JS:
$(function(){
var $container = $('#masonry-container');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.box',
columnWidth: 100
});
});
$container.infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector : '.box', // selector for all items you'll retrieve
loading: {
finishedMsg: 'No more pages to load.',
img: 'http://i.imgur.com/6RMhx.gif'
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
}
);
});
How to find
vk_posts?page=2
and save to var.
After scrolling I have localhost:3000/vk_posts in all loaded pages. Masonry deletes selector $(".pagination a") and I cant to find href of this selector.