jQuery: Call function after ajax has completely rendered - javascript

I am using a function pinterest_it() to adjust a view with masonry.js and I'm using another function recipeLoader() to show a loading icon until the page completely loads, then display content. This works on page refresh, but when I load content using ajax, my $( window ).load(...) function never fires.
How can make the function call after everything completely loads (not .ready)
function pinterest_it() {
$(".loader").show(); # shows loading icon
$("#recipe-index").css("opacity", 0); # makes content invisible
if ( $(document).innerWidth() < 991 ) {
gutter = 0
} else {
gutter = 16
}
var $grid = $('.grid').imagesLoaded( function() {
var $blah = $('.grid').masonry({
itemSelector: '.grid-item',
columnWidth: function( containerWidth ) {
return $('.grid-sizer').width();
},
percentPosition: true,
gutterWidth: gutter
});
}, fixGrid())
recipeLoader(); # see below
}
function recipeLoader() {
console.log("recipe loader")
$(window).load(function() { # doesn't fire after Ajax completes!
console.log("loaded")
$(".loader").hide(); # hides loading icon
$("#recipe-index").animate({
opacity: 1 # shows content
}, 400);
});
}
# one of the Ajax function that calls pinterest_it()
$(".togglebutton input").click(function () {
console.log($(this).serialize());
$.get(this.action, $('#recipes_search').serialize(), function() {
pinterest_it();
}, 'script')
});
I've tried $(x).ready(...) with no luck, as well as ajaxComplete(). Perhaps there is some way to use $(x).load(...) with a specific element rather than window to allow the function to fire? I've tried calling it on $("#recipe-index") but that didn't work either.

$(window).load doesn't fire on success/completion of an Ajax request. Move that bit to its own function:
function handlePageRefresh () {
console.log("loaded")
$(".loader").hide(); # hides loading icon
$("#recipe-index").animate({
opacity: 1 # shows content
}, 400);
}
And then call it in $(window).load & the Ajax success callback
$(window).load(function() { # doesn't fire after Ajax completes!
handlePageRefresh()
});
# one of the Ajax function that calls pinterest_it()
$(".togglebutton input").click(function () {
console.log($(this).serialize());
$.get(this.action, $('#recipes_search').serialize(), function() {
handlePageRefresh()
pinterest_it();
}, 'script')
});

Related

smoothState.js conflicting with other plugins

I have managed to implement the smoothState.js plugin on my website and it works nicely, but my other very simple jQuery plugin will not work, wich starts with:
$(document).ready()
I need to refresh the page in order for it to work again.
I've read the smoothState documentation and it says I should wrap your plugin initializations in a function that we call on both $.fn.ready() and onAfter — but I'm farely new to programming, so I'm asking for your help.
How can I make my jQuery plugins work with smoothState?
You need to wrap scripts that are initiated with $(document).ready() in a function, and then call that function when you need it.
For example, let’s say this is your current script:
$(document).ready(function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
});
It’ll work fine when the page loads as it’s wrapped in $(document).ready(function()), but as the page won’t be reloading when using Smoothstate, we need a way to call the snippet both when the page originally loads and when smoothstate loads content. To do this we’ll turn the above snippet in to a function like this:
(function($) {
$.fn.onPageLoad = function() {
$('.btn--homepage').click(function(e) {
e.preventDefault();
var goTo = $(this).attr('href');
$('#page').addClass('is-exiting');
$(this).addClass('exit-btn');
setTimeout(function() {
window.location = goTo;
}, 260);
});
};
}(jQuery));
As you can see, we’ve swapped $(document).ready(function()) with the function wrapper, everything else stays the same.
So now we’ve got a function all we need to do is call it when the page loads and in Smoothstate.
To call it when a page loads all we need to do is this:
$(document).ready(function() {
$('body').onPageLoad();
});
And to trigger it in Smoothstate we need to call it in the InAfter callback like this:
onAfter: function($container) {
$container.onPageLoad();
}
And here's an example Smoothstate script showing where to put the onAfter callback:
$(function() {
var $page = $('#main');
var options = {
prefetch : true,
pageCacheSize: 4,
forms: 'form',
scroll: false,
onStart: {
duration: 1200,
render: function($container) {
$container.addClass('is-exiting');
smoothState.restartCSSAnimations();
}
},
onReady: {
duration: 0,
render: function($container, $newContent) {
$container.removeClass('is-exiting');
$container.html($newContent);
$('html, body').scrollTop(0);
}
},
onAfter: function($container) {
$container.onPageLoad();
}
};
var smoothState = $('#main').smoothState(options).data('smoothState');
});
Happy to provide further assistance if needed.

.ajaxComplete is not triggered after deleting item with AJAX?

I'm using Rails 4, Bootstrap and Masonry. I have the following code working for jQuery Masonry to arrange my divs, in application.js:
$(function(){
$('#pins').masonry({
itemSelector: '.box',
isFitWidth: true
});
});
var masonryUpdate = function() {
setTimeout(function() {
$('#pins').masonry();
}, 200);
}
$(document).on('click', masonryUpdate);
$(document).ajaxComplete(masonryUpdate);
It works otherwise, but when I try to delete an item with AJAX, Masonry doesn't update. Here is my destroy.js:
$('.deleting').bind('ajax:success', function() {
$(this).closest('.poista').fadeOut();
});
How could I force Masonry to reload, after the code example above? For some reason .ajaxComplete(masonryUpdate) is not triggered?
From the jQuery Documentation on ajaxComplete it seems as though it doesn't perform a function call on a given argument but instead calls a handler function when the Ajax requests complete.
handler
Type: Function( Event event, jqXHR jqXHR, PlainObject ajaxOptions )
The function to be invoked.
Your best bet would be to use an anonymous function to call masonryUpdate.
$(document).ajaxComplete(function(event, xhr, settings) {
masonryUpdate();
};
Edit
It might be better to cache your masonry spec in a variable.
var mas = $('#pins').masonry({
itemSelector: '.box',
isFitWidth: true
});
Then you can call masonry on that variable
var masonryUpdate = function() {
setTimeout(function() {
mas.masonry('reload');
}, 200);
}

JavaScript failing on page postback

I have got this script to give effects to buttons which i have, it fails after the page is posted back, i have also put the code in a pageLoad method yet it still does not function. any idea how i can go about making this script run once the page has loaded.
$(document).ready(function () {
/*preloader for image loading bar*/
jQuery(function ($) {
function preLoad() {
//alert("script running");
$("#divQuestionMatrix").addClass("hidden");
}
function loaded() {
$("#divQuestionMatrix").removeClass("hidden");
$('div#preLoader').css({ display: 'none' }).remove();
}
preLoad();
window.onload = loaded;
});
/* End of preloader*/
$("#btnPrevious").click(function (e) {
$("#navigation").val("previous");
}
);
$("#btnNext").click(function (e) {
$("#navigation").val("next");
}
);
/* $(".qmatrix").click(function () {
//get id of button
alert($(this).attr('id'));
$("#navigation").val($(this).attr('id'));
}
);*/
$(".qmatrix").hover(function (e) {
//get id of button
//alert($(this).attr('id'));
//get src of image before hover
var origimage = $(this).attr('src');
// alert(origimage);
//$(this).attr({ src: 'images/questionMatrix/100' + $(this).attr('id') + '.png' });
$(this).stop().animate({ "opacity": "0.1" }, "fast")
},
function () {
// $(this).attr({ src: '' + origimage.toString() + '' });
$(this).stop().animate({ "opacity": "1" }, "fast");
}
);
The document.ready event is fired once the page has finished loading.
Inside the handler for the ready event, you're then using the ready event shortcut (passing a function directly to the global jQuery function (which is the same as the global $ function btw) to add another handler function for the ready event.
Inside this second ready handler you're then trying to assign the loaded function to window.onload, which would have already fired by this point.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
Put this Latest Jquery Library Just just above to your document.ready() function and try to run your program.

Infinite scroll jumps to top of page

I'm using infinite scroll with masonry everything works fine and lines up correctly. I have a button that when i click it makes that div bigger and shows extra content. the button works and loads fine when the page initially loads but when i scroll down and infinite loads new items and if i click the button to show more it jumps to the top of the screen.
I'm guessing i have to do some callback? Im kinda confused on this. How should I approach it?
this is the code im using:
$(function(){
$(".fancybox").fancybox();
var $container = $('.main_containera');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.item1',
columnWidth: 0
});
});
var nextSelector = '.pagination-next a';
var origNextUrl = $(nextSelector).attr('href');
var offsetRegex = /(offset=)([0-9]+)/;
var offset = origNextUrl.match(offsetRegex)[2];
$container.infinitescroll({
navSelector : '.paginate', // selector for the paged navigation
nextSelector : '.pagination-next a', // selector for the NEXT link (to page 2)
itemSelector : '.item1', // 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 );
});
}
);
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
});
});
Try changing
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
});
to
$('.comment_tr').click(function (e) {
$(this).toggleClass('disabled');
$(this).parent().parent().parent().find('form').slideToggle(250, function () {
$('.main_containera').masonry();
});
e.preventDefault();
e.stopPropagation( );
});
The click event may be propagating up to another link element which has an empty href or one that returns the user to the same page which usually just takes you back to the top. Alternatively, you could replace e.preventDefault(); and e.stopPropagation(); with return false;.
It's hard to say for sure that that's the issue without seeing the HTML though.
Could you post the HTML if that change doesn't work?

jQuery Tools Overlay with preload delay

I'm using the Overlay plugin from jQuery Tools: http://flowplayer.org/tools/overlay/index.html to display a full size image when a link is clicked, but the overlay is displayed immediately and shows the image loading.
I'd like to change this behavior and wait until the image is loaded before launching the overlay. The Overlay plugin has an onBeforeLoad property to which a callback function can be attached. But, of course, the overlay display resumes as soon as this callback is executed, and will not wait for the image load event to be fired.
The plugin has a few API methods, but they don't seem very helpful for my purpose.
In my example below, the two lines I've commented out should give you an idea of what I thought might work, but doesn't.
Here's a simplified test case: http://jsfiddle.net/GlauberRocha/9jkU5/
Any idea?
var $trigger = $("#trigger"),
api;
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .8
},
onBeforeLoad: function() {
console.log("onBeforeLoad");
api = $trigger.data("overlay"); // see http://flowplayer.org/tools/overlay/index.html "Scripting API"
//api.close(); // Temporarily "close" the overlay?
setTimeout(function() { // This will be replaced by the image load event
console.log("Waiting is over!");
//api.load(); // Load the overlay now?
}, 2000);
},
onLoad: function() {
console.log("onLoad");
}
});
Ok, I think I understand what you are wanting. To prevent the overlay from loading, you need to return false, but only if the image is not yet loaded. See if this JSFIDDLE helps:
var $trigger = $("#trigger"),
api;
var imageLoaded = false;
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .8
},
onBeforeLoad: function() {
console.log("onBeforeLoad");
api = $trigger.data("overlay"); // see http://flowplayer.org/tools/overlay/index.html "Scripting API"
//api.close(); // Temporarily "close" the overlay?
if(!imageLoaded){
setTimeout(function() { // This will be replaced by the image load event
console.log("Waiting is over!");
api.load(); // Load the overlay now?
}, 2000);
imageLoaded = true;
return false;
}
},
onLoad: function() {
console.log("onLoad");
}
});
I've modified my code. This version seems to work (see http://jsfiddle.net/GlauberRocha/rwtvK/). The main difference comes from the way the API method is called ($trigger.overlay().load() vs $trigger.data("overlay").load()). This inconsistency is present in the jQuery Tools docs and examples.
$(function () {
var $trigger = $("#trigger");
$trigger.overlay({
fixed: true,
mask: {
color: "#000",
opacity: .4
},
onBeforeLoad: function () {
if (typeof this.init === "undefined") {
this.init = true;
setTimeout(function () { // This will be replaced by the image load event handler
console.log("OK, let's show it!");
$trigger.overlay().load(); // Load the overlay
}, 5000);
console.log("Not now!");
return false;
}
}
});
});

Categories