I have some code which does the following:
External content is loaded via AJAX (video thumbnail images)
The new content is then inserted into a div using $("#content").append();
A mobile touch scrolling helper (iScroll) is applied to this div.
However the jQuery "load" event is not firing when the DOM changes due to an AJAX event, which means the call to initialise the scroller is happening too soon (before the images inthe content has loaded) which means it often doesn't get intiiallised. Without waiting for the images to load the content box is often short enough such that a scroll function isn't needed, but then when the images subsequently load, the box is not scrollable.
$("#videoList").append(videoThumbnails);
$(document).load(function () {
// doesn't fire
initScroller();
});
It appears that jQuery's append function does not block until all images referenced in the appended HTML have loaded.
How can I detect that all of the images loaded by the AJAX function have finished loading in order to call the initScroller() function AFTER all images have loaded?
OK I've found the solution in another similar question. It turns out there's a jQuery waitForImages plugin which does exactly what I want:
So I can just do this:
$("#videoList").waitForImages(function () {
// Fires when all images in the #videoList div have loaded
initScroller();
});
The methods you are trying to use are triggered only once, when the page is loaded, but not for changes you make to the DOM aftewards (e.g. inserting content with ajax).
If you want to observer DOM changes you can use the DOMNodeInserted event
$(document).bind("DOMNodeInserted", function(event) { ....do stuff...here });
But generally it would be better to trigger this with the ajax callback.
$('#targetElementForYourContent').load('server/url.html', function() {
...do stuff here....
});
Related
I am trying to show a loading animation / spinner on every Ajax request
my application.js
$(document).on("turbolinks:load", function() {
window.addAjaxLoaderHandler();
});
window.addAjaxLoaderHandler = function() {
$(document).on('ajax:send', function() {
$('#ajax-loader').show();
});
$(document).on('ajax:complete', function(){
setTimeout(() => {$('#ajax-loader').hide();}, 100);
});
}
This works perfectly, UNTIL I load a remote form by AJAX. If I submit that newly loaded form the ajax:send fires, but after completion (without any errors) the ajax:complete does not (the spinner will not be hidden).
The problem seems to be that I remove the loaded form with the ajax call.
What can I do to make this work?
I am just trying to click a link, load a form and remove the form after sending its information.
UPDATE
My application.html.haml (I use HAML so syntax is accordingly, so #... means <div id="...">#all indented code lines#</div>)
#main
= yield
#ajax-loader
The form will be loaded like:
$('#main').append('<%= j(render(:partial => 'new', :locals => {:model => #model})) %>');
The problem is that #ajax-loader is not hidden and still shows after form is submitted.
I think the problem is, that I remove the AJAX-call triggering element. But I was hoping, that since I bound the listener to document, that it still triggers.
Of course in this case I just can do $('#ajax-loader').hide();, but I am trying to understand why ajax:complete is not fired.
I guess you answered your own question: the problem is that when you remove the form, so does the event listener.
You can check what event listeners still apply to your document object using
getEventListeners(document). Try this on your console* after the spinner is fired and refuses to hide.
*edit: this is a Google Chrome function, might not work in other browsers, though most of them have ways to inspect the listeners on a node
I think of these workarounds:
a) Rebinding the listeners everytime you remove a form;
b) Attaching the listener to the window object instead of document
c) If you are using jQuery Ajax you could use the beforeSend and complete properties to show and hide the spinner instead of events. If it's not jQuery Ajax there's probably a similar way to achieve the same behavior.
I am using UberGallery for my site:
http://www.ubergallery.net/
Here is a sample of the page with Uber Gallery called directly in the HTML
http://www.goloyal.com/clients/dealers-mlm.php
If you click on a thumbnail it opens the popup div.
Some pages have a lot of thumbs, so they load slowly, so I tried to call the Uber Gallery through an Ajax so the page would load, then the thumbs could take their time:
/old-dealers-mlm.php
The loader works exactly as I hoped, however when you click on the thumbnails it opens in a new page (not the pop up div)
I am calling THIS div in my ajax
/div-dealers-mlm.php
Which also has the popups showing correctly.
I do understand that the pages are loaded separately, and I know it requires a special conversation to tell one page to do something in the other. However, I am not sure what I need to relay to the parent/original page, or how to do it to start testing. Any ideas?
THANKS!
The problem is that you're setting up the colorbox on links that don't exist yet. You need to replace your current colorbox code with this:
$(document).ready(function(){
$(document).on("click", "a[rel='colorbox']", function(e){
e.preventDefault();
var url = this.href;
$.colorbox({href: url, maxWidth: "99%", maxHeight: "99%", opacity: ".5"});
});
});
This uses jQuery .on() to bind the click event to all current and future a elements with a rel attribute that equals colorbox.
I'm attempting to run the following simple bit of code on an html snippet contained in a php file, loaded with jquery's .load() function:
$(".thumbnail").on("click", function(event){
alert("thumbnail clicked");
});
However, I can't seem to get it to work on this portion of my page. I have other calls to elements not loaded via ajax and they work fine with the .on() function. I was under the impression that .on() would recognize ajax loaded content.
My .thumbnail elements are pictures in img tags contained within a series of divs all loaded via ajax, jquery can't seem to find any of this content. All of my code is contained within the ready function.
Is there a way to get jquery to recognize these new elements?
Thanks.
You need a delegated event handler for dynamic content :
$('#container').load('somefile.php');
$('#container').on('click', '.thumbnail', function(event){
// do stuff
});
The closest non-dynamic parent would probably be the element you're loading the content into, and you need to attach the event handler to that element, filtering based on the .thumbnail class, like the code above.
So I've decided to use the jQuery Mobile framework to build my new mobile website. It has this feature of loading any local href link by ajax, which is great. But the new page that loads doesn't respond to any of the javascript. I've got a home page and page 2, both of which have the same html layout which a few changes in the content, I'll give an example.
I have made a navigation menu that slides in from the left and pushes the main content to the right. When I click on a page link, it loads the new page through ajax, but then on the new page, if I click the menu button, jQuery doesn't pick this up and so nothing happens (the menu doesnt slide out).
$(document).ready(function() {
$( ".menu-trigger" ).click(function() {
console.log("1")
if ($( 'nav' ).hasClass('navTransform')) {
console.log("2")
$( 'nav' ).removeClass('navTransform');
$( 'article' ).removeClass('articleTransform');
}
else {
console.log("3")
$( 'nav' ).addClass('navTransform');
$( 'article' ).addClass('articleTransform');
}
});
});
This jQuery script is in a seperate .js file thats included in the header of both the pages. I know the script works normally because when i refresh the page, the menu trigger works. Is there a known work around for this?
The workaround for this is to use appropriate jQM handler pageinit() instead of jQuery ready handler.
pageinit = DOM ready
One of the first things people learn in jQuery is to use the
$(document).ready() function for executing DOM-specific code as soon
as the DOM is ready (which often occurs long before the onload event).
However, in jQuery Mobile site and apps, pages are requested and
injected into the same DOM as the user navigates, so the DOM ready
event is not as useful, as it only executes for the first page. To
execute code whenever a new page is loaded and created in jQuery
Mobile, you can bind to the pageinit event.
So, your code might look like this:
$(document).on("pageinit", "#page1", function(){
//Your init code for page 1 goes here
});
$(document).on("pageinit", "#page2", function(){
//Your init code for page 2 goes here
});
I've got some links coming in from ajax that need lightbox functionality:
<img src='...'>
Normally this is given behavior via an on page load handler, but since the content is coming from ajax, the UJS isn't getting triggered.
Any way to do this?
If the content is coming from AJAX, then din't setup the event handling during page load. Instead, let the event bubble to the topmost container that is not being changed or replaced by AJAX. Worst case, use document as the topmost node.
$('<root element selector>').on('click', 'a.lightbox', function() {
// activate lightbox on the clicked element.
});
I'm not sure how you're triggering the ajax requests, but if it's with jQuery which seems likely, you can bind the lightbox in the success callback:
$.ajax({
url: '/route',
success: function (response, status) {
$('.lightbox').lightbox();
}
});
You can pass in a context to the jQuery selector so you don't re-attached the lightbox to links that are already in the page, for example if your ajax call is adding the links to a div with id 'lightbox_links', use this selector instead:
$('.lightbox', '#lightbox_links').lightbox();