I am using jQuery Lazy to load images in a page progressively. When the images are called with AJAX, they do do not load. Please, how to use this Plugin with AJAX?
I tried:
$(function() {
$('.lazy').lazy({
placeholder: "data:image/gif;base64,R0lGODlhEALAPQAPzl5uLr9Nrl8e7...",
effect: "fadeIn",
effectTime: 2000,
threshold: 0
});
});
However it is not working. Some time back, when I had that challenge with Colorbox, the solution was to call for body click, like:
$("body").on("click", ".photos", function(event){
$(".photos").colorbox({rel:'photos', transition:"fade"});
});
That made the trick to enable colorbox to work with an AJAX call - but with Lazy there is no body click, so even though I did:
$(function() {
$('body .lazy').lazy({
placeholder: "data:image/gif;base64,R0lGODlhEALAPQAPzl5uLr9Nrl8e7...",
effect: "fadeIn",
effectTime: 2000,
threshold: 0
});
});
So, how to use jQuery Lazy with AJAX?
Please think about how jQuery (and Lazy) work. There is not kind of auto detection of new elements (expect somebody builds it on its own). So, if you load new elements via AJAX you need to tell jQuery/Lazy that there are new elements.
In case of Lazy, there are some public functions you can use of an instance. In your case, you would need to use addItems and update.
With addItems, you can add new elements to an existing instance of Lazy. So the plugin knows that he has to handle these elements too. With update, you can force Lazy to do a single update of the current viewport, without using scroll or resize event.
So, that means, you have to slightly update your code:
var instance = $('.lazy').lazy({
chainable: false, // tell lazy to return its own instance
placeholder: "data:image/gif;base64,R0lGODlhEALAPQAPzl5uLr9Nrl8e7...",
effect: "fadeIn",
effectTime: 2000,
threshold: 0
});
Afterwards you need to use the two public functions, mentioned above, after the AJAX request got finished. I don't know how you load the new elements, but there might be a callback or something where you could execute these.
instance.addItems('.jquery-selector-for-new-items-only');
instance.update();
If you have the new elements already as jQuery object, you can use addItems with them too. So instead of a selector, just add the object:
instance.addItems($('.jquery-object'));
instance.update();
And that's it ...
Related
In this website that I am building https://vase.ai/blog/ , I am using a script of infinite scrolling to make several pages into one page for scrolling.
I would like to hide the loader(the spinning one) when there is no more page to be loaded. I figured that the following code might be able to help me to detect the error (Failed to load resource: the server responded with a status of 404 (Not Found)) and execute the hiding. However, it does not work. Am I missing something out?
window.addEventListener('error', function(e) {
$('loading').fadeOut()
}, true);
Code that I use to to load more :
//implementing infinite scrolling
$grid.infinitescroll({
// Pagination element that will be hidden
navSelector: '.pagination',
// Next page link
nextSelector: '.pagination a',
// Selector of items to retrieve
itemSelector: '.grid-blog',
},
// Function called once the elements are retrieved
function(new_elts) {
var elts = $(new_elts).css('opacity', 0);
elts.animate({opacity: 1});
$grid.packery('appended', elts);
$('.target-resize').textfill({
maxFontPixels: 36,
changeLineHeight:false
})
$grid.packery({
itemSelector: '.grid-blog',
gutter: 20,
})
});
It's difficult to answer your question without the code that make the http calls in order to load your content. But,
1) you may have an error, and still have contents to be loaded, in that case your loader will disappear even if contents are still loading.
2) You should have something that tel your site what you have to load.
an array of url, or anything, you can maybe use this to hide your loader when all contents has been loaded.
3) You should have somewhere a function that make httpcalls to get your content. This function should have a callback. In this callback, you should be able to catch an error, and then hide your loader.
I cannot give you more informations with the amount of code you show in your exemple.
edit : after looking at your code, you may try to do :
// Function called once the elements are retrieved
function(new_elts) {
if(!new_elts) {
$('loading').fadeOut();
return;
}
...
}
I don't think this is the right solution, your plugin should have a built-in function to stop calling new pages, but since I don't see the function that make the http call, or any array/iterator of URLs, it's difficult top help you.
you should check this demo to : https://codepen.io/desandro/pen/rwwoGe
I'm using the fantastic Stellar.js (http://markdalgleish.com/projects/stellar.js/) for parallax on a recent project, but I've run into a challenge:
Stellar isn't noticing when I change content via AJAX (in this case loading in new div's from an html file and using jQuery's replaceWith method). So, my new elements have no parallax, even though they have stellar data attributes.
I've tried calling the .stellar function on my window again after the AJAX is complete, but it doesn't do anything.
How can I get Stellar to correctly apply parallax to the new AJAX'd in elements?
I know this question was posted a long time ago has been accepted, but for me the solution above did not work, so I just wanted to share this which worked for me.
After you AJAX call has been successful you can call Stellar's refresh function like so:
$.stellar('refresh');
Here is the full code:
$.ajax({
type: 'GET',
url: ajaxUrl
}).done(function(data) {
$(targetElement).html(data);
$.stellar('refresh');
}).fail(function() {
// Do something else
});
I found that I can run this code in my jQuery AJAX callback and Stellar will then correctly apply parallax to my new AJAX'd in elements:
$(window).data('plugin_stellar').destroy();
$(window).data('plugin_stellar').init();
I know that the topic is old but I want to share the solution that I found, hoping that it will be useful for people who are still searching.
First create the function:
function init () {
$(window).data('plugin_stellar').refresh();
}
jQuery(document).ready(function () {
// Initialise the plugin when the DOM is ready to be acted upon
init();
});
Second insert this line in your Ajax call:
// Reinitialise plugins:
init();
this may get complicated so I will try to explain my situation as best as I can.
I am using this jquery plugin http://www.infinite-scroll.com/ along with masonry: http://masonry.desandro.com/
Everything is working fine.
However, I'm trying to make some info relating to each post appear when you hover over a post. Here is my code:
$(".main").hover(function(){
$(this).next(".info").slideToggle("fast");
});
This only works on the first page content and not the extra content that is loaded by the infinite scroll.
So I tried adding the function to the callback of my masonry code:
// 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);
});
$(".main").hover(function(){
$(this).next(".info").slideToggle("fast");
});
});
(Excuse me if I'm doing this completely wrong, I have never worked with Ajax before and am merely experimenting)
This made the hover function work on the new extra content loaded by Infinite scroll, however it then conflicted with the original content.
So, what is the best way to implement my hover function so it will work properly for all posts loaded before and after the Ajax call?
Thanks.
EDIT:
Solved the problem by changing my method to this:
$(document).on("click",".main",function(){
$(this).next(".info").slideToggle("fast");
});
http://api.jquery.com/on/
I will leave the original question here incase someone with a similar problem finds it useful.
$(document).on("click",".main",function(){
$(this).next(".info").slideToggle("fast");
});
For latest version of http://www.infinite-scroll.com/ along with masonry: http://masonry.desandro.com/ following code worked for me:
$grid.on( 'append.infiniteScroll', function( event, response, path, items ) {
$(this).next(".info").slideToggle("fast");
// OR your code you want to load after infinite scroll loads
});
Check for more here https://infinite-scroll.com/events.html#append
I have a scrolling image script that I'd like to update the scroll speed of on the fly, using a hover function. I've researched and just can't figure out how to get the variable to update inside of the function without calling the function again. I don't want it to start over, I'd just like the speed to increase as it is running.
(function ($) {
$(function () { //on DOM ready
var defspeed = 1;
$(".simply-scroll-list").simplyScroll({
speed: defspeed,
});
});
})(jQuery);
$('.fast-forward').hover(function () {
var defspeed = 5;
});
As you can see above, I don't know how to integrate those two blocks of code properly.
You cannot increase the speed on the fly in a decent way, because the speed is set only once when you initialize the simpleyScroll plugin.
You could reinitialize the plugin but that could have unwanted side effects. jQuery plugins sometimes add extra html to your DOM and reinitializing it would do that multiple times. Multiple event handlers could get attached to the same nodes and all kinds of stuff could go wrong. I do not know if this is the case with this plugin though. Try it :)
I myself would just add it to the plugin. I don't think it would be hard as the plugin is pretty small.
I'm working on my website and I decided it would be to my advantage to use 'designed' scroll bars instead of the ones browsers come with. I was lucky enough to come across this script http://www.hesido.com/web.php?page=customscrollbar which basically does exactly what I need.
The only problem I've got is that I am trying to apply the custom scrollbars to some divs which are initially hidden and then toggle via a link div between hide/show.
As the programming page (http://www.hesido.com/flexcroll/flexcroll-programming.htm) explains, sometimes the scrollbar needs to be updated and/or manually applied, because being in hidden divs they do not load when the page opens.
I've checked my CSS and my HTML and the code works fine if the div is not hidden, so I am 100% that this has to do with the way I am hiding my divs.
The basic format for that is
$(document).ready(function() {
$('#iddiv').hide();});
$(document).ready(function() {
$('#id').click(function() {
$('#iddiv').animate({
height: 'toggle'
}, 2000
);
});});
So I hide it initially, and then toggle it via a button.
Now, in this logic - the manual application of fleXenv.fleXcrollMain("your-div-id"); should be somewhere above the last line of script (the one containing }); ).
This, however, either makes the div unscrollable or messes up the rest of my Javascript (scrollTo functions stop working, etc...)
My question is, as a bit of a noobie JS user - WHERE do I need to place that piece of code that manually activates the custom scrollbar in my code AFTER the toggle is activate and WHAT is the structure?
By which I mean, does fleXenv.fleXcrollMain("your-div-id"); stand on its own, does it need its own separate function, does it get a $ before it?
Loads of thanks to anyone who can help me with this! Final bit stopping me from launching my website.
UPDATE!
HERE is the CSS/HTML and code for an example of what I am trying to achieve; because one of the files in the script needs to be downloaded to work, I think the only way is to copy and paste all the bits in a new HTML document.
The jQuery .animate() function accepts more arguments. One of them is a function that gets called when the animation completes.
function activateScrollbar () {
fleXenv.fleXcrollMain('iddiv');
}
$('#iddiv').animate({
height: 'toggle'
},
2000,
activateScrollbar
);
You can also use an anonymous function, like this:
$('#iddiv').animate({
height: 'toggle'
},
2000,
function () {
fleXenv.fleXcrollMain('iddiv');
}
);
Most functions in jQuery that include an animation, (like .hide() or .fadeOut()), allow you to pass a function that gets called when the animation completes. Most of these jQuery functions allow you to pass these extra arguments in a configuration object which can be more readable:
$('#iddiv').animate({
height: 'toggle'
},
{
duration: 2000,
complete: function () {
fleXenv.fleXcrollMain('iddiv');
}
}
);
See the .animate() documentation for more details.
Here's a full example with the click behavior included:
$('#myButton').click(function () {
$('#iddiv').animate({
height: 'toggle'
},
{
duration: 2000,
complete: function () {
fleXenv.fleXcrollMain('iddiv');
}
}
);
});
Try this:
$(document).ready(function() {
$('#id').click(function() {
$('#iddiv').animate({
height: 'toggle'
}, 2000,
function(){
fleXenv.fleXcrollMain( $(this).attr('id') );
}
);
});
That function is callback executed after animate function is complete.