I've found some solutions online for this but couldn't make them work for me. Or maybe I was doing it wrong. I am completely newbie in JS, can you please help me to delay this function?
jQuery(window).on('load', function(){ var $ = jQuery;
var $container = $('.social_container');
$container.masonry({
columnWidth:350,
gutterWidth: 355,
itemSelector: '.masonryImage'
});
});
You can use setTimeout() of javascript :-
jQuery(window).on('load', function() {
setTimeout(function() {
var $ = jQuery;
var $container = $('.social_container');
$container.masonry({
columnWidth: 350,
gutterWidth: 355,
itemSelector: '.masonryImage'
});
}, 2000);
});
Use setTimer()
jQuery(window).on('load', function() {
setTimer(function() {
var $ = jQuery;
var $container = $('.social_container');
$container.masonry({
columnWidth: 350,
gutterWidth: 355,
itemSelector: '.masonryImage'
});
}, 1000);
});
This will delay it for 1 second.
The approach should be to wait for the plug-in to load and only then call your function.
var finished_rendering = function() {
console.log("finished rendering plugins");
}
// In your onload handler
FB.Event.subscribe('xfbml.render', finished_rendering);
Related
I am trying to get Packery.js to work with LazyLoad.js, while having the ability to filter the gallery by tags.
www.temp.fokuspunkt.de
On the initial page load everything works fine:
After clicking throgh the tags and then clicking on the "all" button again, the layout is scrambled, however:
I assume this has to do with the lazy loading, as it can throw off the layout, as described in the documentation here:
https://packery.metafizzy.co/layout.html#imagesloaded
Adding the recommended solution
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
throws an error, though:
My complete javascript file calling Isotope looks like this, I had tried to copy the above code right beneath the "$(window).on('load',function[...]" function block:
jQuery(function ($) {
var $grid = $('.isotope-list').packery({
layoutMode: 'packery',
filter: '*',
itemSelector: '.isotope-item',
gutter: 0,
});
$(window).on('load',function(){
$grid.packery('layout');
});
imagesLoaded( $grid ).on( 'progress', function() {
pckry.layout();
});
$('.filters li').click(function(){
//css button styling
$('.filters li').removeClass('current');
$(this).addClass('current');
// set isotope filter
var selector = $(this).attr('data-filter');
$grid.isotope({
filter: selector,
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
});
$grid.packery('layout');
return false;
});
var $win = $(window),
$imgs = $("img"),
$loadVisible = function($els, trigger) {
$els.filter(function () {
var rect = this.getBoundingClientRect();
return rect.top >= 0 && rect.top <= window.innerHeight;
}).trigger(trigger);
}
$grid.packery('on', 'layoutComplete', function () {
$loadVisible($imgs, 'lazylazy');
$grid.packery('layout');
});
$win.on('scroll', function () {
$loadVisible($imgs, 'lazylazy');
});
$win.on('resize', function () {
$grid.packery('layout');
});
$imgs.lazyload({
effect: "fadeIn",
failure_limit: Math.max($imgs.length - 1, 0),
event: 'lazylazy'
});
});
I am certain I am doing something stupid, would anybody be kind enough to tell me what I am doing wrong? Thank you very much in advance!
So, it took a while, but I wanted to return and share my solution. Maybe it helps out somebody else in the future. My main problem was that I used isotope and packery (which is a standalone library), and not isotope and isotope-packery (which is an addon for isotope). I also changed my lazy loading plugin to "lozad", which makes a lot of thins easier.
In the code below you can also find a solution for using multiple filter terms in combination. In my case I use a row of row of radio buttons below the old button row you can see above.
jQuery(function ($) {
// initialize Packery
var $pckry = $('.isotope-list').isotope({
layoutMode: 'packery',
filter: '*',
itemSelector: '.isotope-item',
packery: {
gutter: 0
},
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
});
// layout on first page load, so that the gutter gets set up
$(window).on('load', function () {
$pckry.isotope('layout');
});
// filter items on button click
$('.filters li').click(function () {
$('.filters li').removeClass('current');
$(this).addClass('current');
var combinedFilter = getFilter($('.filters li.current').attr('data-filter')) + getFilter($('input[name="isotope-type-filter"]:checked').val().toLowerCase());
$pckry.isotope({ filter: combinedFilter });
$pckry.isotope('layout');
});
// filter items on radio button change
$('input[name="isotope-type-filter"]').change(function () {
var combinedFilter = getFilter($('.filters li.current').attr('data-filter')) + getFilter($('input[name="isotope-type-filter"]:checked').val().toLowerCase());
$pckry.isotope({ filter: combinedFilter });
$pckry.isotope('layout');
});
function getFilter(buttonGroup) {
var filterValue = '';
if (buttonGroup === '*') {
filterValue = "";
} else {
filterValue = "." + buttonGroup;
}
return filterValue;
};
});
I've got this code
var goRight = function() {
$(this).animate({'left:' '40px'}, 1000, goLeft);
};
var goLeft = function() {
$(this).animate({'left:' '-40px'}, 1000, goRight);
};
var main = function() {
$('.square').hover(function() {
$(this).toggleClass('active');
});
$('.square').goRight();
};
$(document).ready(main);
It supposed to move the square(a div) to the right then back to the left infinitely and make it blue when the user hovers over it. But it doesn't work. The problem is probably in the goRight and goLeft, functions. Since if I remove them completely the hover changes the color fine. And when these functions are there nothing works.
You need to do the chaining like this
$.fn.goRight = function() {
this.animate({
'left': '40px'
}, 1000, function() {
$(this).goLeft()
});
return this;
};
$.fn.goLeft = function() {
this.animate({
'left': '-40px'
}, 1000, function() {
$(this).goRight()
});
return this;
};
var main = function() {
$('.square').hover(function() {
$(this).toggleClass('active');
});
$('.square').goRight();
};
$(document).ready(main);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="width:100px;height:100px;background:black;position:relative;" class="square"></div>
For more about jQuery plugin development : https://learn.jquery.com/plugins/basic-plugin-creation/
So here's what I'm trying to do. I have a grid with a lot of images, so I'm using the imagesLoaded library along with masonry.
Here's my CSS:
.grid {
opacity:0;
}
And HTML:
<div class="grid">
<div class="grid-sizer"></div>
<div class="gutter-sizer"></div>
<div class="item">image</div>
<div class="item">image</div>
<div class="item">image</div>
</div>
And here's my JS:
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.imagesLoaded( function() {
$container.masonry({
columnWidth: '.grid-sizer',
itemSelector: '.item',
gutter: '.gutter-sizer'
});
$container.masonry('on', 'layoutComplete', function(){
console.log('got here');
$container.animate({'opacity':1});
});
});
My goal is to have the grid hidden until all images are load and the layout is complete, and then fade it in. For some reason in my code above, it's never getting into the on layoutComplete block.
If I move that block outside of imagesLoaded, $container.masonry is undefined that point.
Any ideas?
FIDDLE HERE
If you change the grid opacity to 1 you can see everything is getting laid out fine. Just trying to figure out how to get the layoutComplete to call to set the opacity to 1.
You don't need to use the layoutComplete event on masonry. As you can just add your animation code under the masonry initialization .
When all images are loaded, the imageLoaded function will execute. You can then create the masonry object and animate right away like so:
var $grid = $('.grid').imagesLoaded( function() {
// init Masonry after all images have loaded
$grid.masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
console.log('got here');
$('.grid').animate({'opacity':1});
});
Here is a jsfiddle that demonstrate that
jQuery(document).ready(function($){
var wdm_wait = function(){
jQuery("body").find("img").each(function(i) {
if(!this.complete)
{
return false;
}
});
// when code reaches here Its assured that all the images are loaded
clearInterval(waiting);
console.log('got here');
var $container = $('.grid');
// initialize Masonry after all images have loaded
$container.masonry({
columnWidth: 100,
itemSelector: '.item',
gutter: 10
});
$container.animate({'opacity':1});
}
waiting = setInterval(wdm_wait,100);
});
This would certainly assure that your js code executes only after all the images have been loaded (rendered)
Hope this helps! :)
have you ever try this one, I think this is your answer
var $container = $('.grid').masonry({
columnWidth: 200,
itemSelector: '.item',
gutter: 10
});
$container.masonry( 'on', 'layoutComplete', function() {
$container.animate({'opacity':1});
});
$container.masonry();
I am creating the function Bricks(). It works the first time it is called, but when I call it later with another event, I get an error saying that Bricks() hasn't be defined. What could I be doing wrong?
Function Created:
<script>
$(document).ready(function(){
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector:'.post-wrap'
});
});
}
Bricks();
});
</script>
Called Upon later:
<script>
$(document).ready(function() {
$(".comment-button").click(function() {
$(this).parents(".post-bottom").find(".commenting-area").toggle();
Bricks();
});
});
</script>
Because the function Bricks is defined in closure scope(the dom ready handler) so it will be available inside that dom ready handler only.
If you want to use it in a different scope, you need to define the function in a shared scope, in this case you can use the global scope(window scope), that is define the function outside the dom ready handler
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.post-wrap'
});
});
}
$(document).ready(function () {
Bricks();
});
Another solution as suggested by #AlienArrays is to move the contents of both document ready handlers to one so that both of them will share the same closure scope
$(document).ready(function () {
function Bricks() {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.post-wrap'
});
});
}
Bricks();
$(".comment-button").click(function () {
$(this).parents(".post-bottom").find(".commenting-area").toggle();
Bricks();
});
});
To be able to reference your function globally, you must define it globally:
$(document).ready(function(){
window.Bricks = function () {
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : '.post-wrap'
});
});
};
Bricks();
});
Note: there are better, cleaner ways to write the above code, but this serves as an answer to the question at hand.
I have a JQuery script that I run multiple times, with multiple events. I would like to save space and turn it into a function to call whenever I need it. How do I do this in JQuery?
My JQuery Script:
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : '.post-wrap'
});
});
You can simply extract the function:
var $container = $('#timeline-posts-wrap');
$container.imagesLoaded(afterImagesLoaded);
function afterImagesLoaded(){
$container.masonry({
itemSelector : '.post-wrap'
});
}
It's not "jQuery specific", simply javascript functions.