I want load some HTML document by AJAX, but I want to show it when all images in this document are loded.
$('.about').click(function () {
$(".back").load('Tour.html', function () {
$(".back").show();
});
});
".back" should be visible when all images in Tour.html are loaded, when is triggered a success event??
$(".back").load('Tour.html', function (html) {
var $imgs = $(html).find('img');
var len = $imgs.length, loaded = 0;
$imgs.one('load', function() {
loaded++;
if (loaded == len) {
$(".back").show();
}
})
.each(function () { if (this.complete) { $(this).trigger('load'); });
});
This requires at least one <img> in the returned html.
What I would suggest is to use an iframe instead. Here is some sample code in plain JavaScript:
var ifr=document.createElement("iframe");
ifr.style.display="none";
document.body.appendChild(ifr);
ifr.onload=function() {
// Do what you want with Tour.html loaded in the iframe
};
ifr.src="Tour.html";
ImagesLoaded is what you are looking for.
Place all code (ajax request in this case), when the images specified are loaded.
The plugin specifies why you cannot use load() on cached images
Related
Is there a way to know if parent window has loaded from within iframe?
I want to run a function which is in iFrame but I need to run it after all the parent windows are loaded and the event listener will be inside the iframe.
I tried the following but it runs before parent windows are loaded.
window.addEventListener('load', function () {
alert("It's loaded!")
});
One way would be to add the iframe dynamically:
parent:
window.addEventListener('load', function () {
var iframe = document.createElement('iframe');
iframe.src = "https://www.example.com";
document.body.appendChild(iframe);
});
iframe:
window.addEventListener('load', function () {
alert('hello world!');
//doSomethingUseful();
}
This way, you could be certain that they will load in a specific order. However, as they'd be loading in series, the increase in total page load time could become noticeable.
Alternatively, you could use this approach. This one may not work as is, if one page happens to finish loading before the other. If you do opt for this approach, it may be necessary to communicate in both directions so that the first page to load finds out when the second page has loaded. That may look like this:
parent:
newEvent();
window.document.addEventListener('myCustomEventI', newEvent, false);
function newEvent() {
var data = { loaded: true }
var event = new CustomEvent('myCustomEventP', { detail: data })
window.parent.document.dispatchEvent(event);
}
iframe:
newEvent();
window.document.addEventListener('myCustomEventP', handleEvent, false);
function newEvent() {
var data = { loaded: true }
var event = new CustomEvent('myCustomEventI', { detail: data })
window.parent.document.dispatchEvent(event);
}
function handleEvent(e) {
alert('both loaded!');
//doSomethingUseful();
}
i have a script that i want to be performed after the whole page has loaded completely not while page is loading. I need you help. below is the script.
jQuery(function () {
var $els = $('div[id^=quote]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(function () {
$els.eq(i).fadeOut(function () {
i = (i + 1) % len
$els.eq(i).fadeIn(750);
})
}, 3750)
})
Try:
$(window).on("load", function () {
// your code here
});
See explanation here :
jQuery - What are differences between $(document).ready and $(window).load?
Use $( document ).ready();
This should work for you:
$( document ).ready(function () {
var $els = $('div[id^=quote]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(function () {
$els.eq(i).fadeOut(function () {
i = (i + 1) % len
$els.eq(i).fadeIn(750);
})
}, 3750)
});
Your code appears to be correct, your just using a different namespace for jQuery / alias...
$(function() {
// DOM Ready Event..
// Your already doing this
});
What is DOM Ready?? well basically it waits for all the elements on your page to be created/ready.. This does not include certain things like images loading or other events.. In general, It means that you should be able to access any element at this point.
If you can provide a jsFiddle of your code or explain further what the actual issue is as such then we can help. But my guess is that your actually looking more for an event against certain elements..
Otherwise use as #NenadP suggested, this should load after the DOM ready even and generally will cover most things.. But just keep in mind if you have certain elements or frameworks/libraries.. You might need to look at their events/callbacks.
I have a simple question but I couldn't find a clean answer. I need to load heavy images after an ajax call and I want to use an animated gif as a pre-loader. I'm using the follow code:
function loadProducts(url) {
$("#loading").show();
$('#inner').fadeOut(1).load(url + ' .product-list', function() {
$('#inner').fadeIn(1000, function() {
$("#loading").hide();
});
});
}
The #loading is hiding when the HTML is loaded .load(url + ' .product-list'. The problem is that the heavy images are still rendering on the screen and I would like to keep showing the animated .gif until the renders of the images are finished. Is there a way to know when the images on the screen are rendered?.
Thanks in advance.
You can use promises to check when all the images have loaded, and then remove the loading gif.
This creates a promise that is resolved when the image has loaded, all the promises are kept in an array, and when all promises are resolved, i.e. all images are loaded, the callback fires.
function loadProducts(url) {
$("#loading").show();
$('#inner').fadeOut(1).load(url + ' .product-list', function() {
var promises = [];
$('#inner').find('img').each(function(_, image) {
var img = new Image(),
def = new $.Deferred();
img.onload = function() {
def.resolve();
}
promises.push( def.promise() );
img.src = image.src;
if (img.complete) img.onload();
});
$.when.apply(undefined, promises).done(function() {
$('#inner').fadeIn(1000, function() {
$("#loading").hide();
});
});
});
}
You can use ImagesLoaded
Sample usage
imagesLoaded( document.querySelector('#container'), function( instance ) {
console.log('all images are loaded');
});
// selector string
imagesLoaded( '#container', function() {...});
// multiple elements
var posts = document.querySelectorAll('.post');
imagesLoaded( posts, function() {...});
Could add/remove the loader as a class? I have base 64encoded the loader, so there is no pre loader required. This also uses a closure to allow the counter to remember its value.
var imgDiv = document.getElementById("imgDiv");
imgDiv.onclick = (function () {
"use strict";
var count = 0; // init the count to 0
return function () {
count++; //count
if (count === 1) { // do something on first click
$('.img-loader-content').addClass('loader');
$('.imgDiv').load("images/img.jpg", function () {
$('.img-loader-content').removeClass('loader');
});
}
if (count > 1) {
$('.imgDiv').slideToggle(400);
}
};
})
();
You may try using Image object. E.g:
function loadImage(url) {
$("#loading").show();
var img = new Image();
img.src = url;
img.onload = function(e) {
$("#loading").hide();
//ur code to append/show the image
};
}
the most approach to this is using onLoad , so basically after the success call of ajax , invoke another call into success function :
http://www.w3schools.com/jsref/event_onload.asp
onload is most often used within the element to execute a
script once a web page has completely loaded all content (including
images, script files, CSS files, etc.).
or use native solution like this :
<img src="w3javascript.gif" onload="loadImage()">
http://www.w3schools.com/jsref/event_img_onload.asp
Also last answer of this question is very useful in your case :
Is there something similar to `$(window).load();` for executing a function after newly inserted Ajax content has finished loading?
You can do it easily by ajaxComplete callback, here check an example http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_ajax_ajaxcomplete
i have some links in a web page ,what i want to do :
Trigger click event on every link
When the page of every link is loaded , do something with page's DOM(fillProducts here)
What i have tried :
function start(){
$('.category a').each(function(i){
$.when($(this).trigger('click')).done(function() {
fillProducts() ;
});
})
}
Thanks
What you want to do is much more complicated than you seem to be giving it credit for. If you could scrape webpages, including AJAX content, in 7 lines of js in the console of a web browser you'd put Google out of business.
I'm guessing at what you want a bit, but I think you want to look at using a headless browser, e.g. PhantomJs. You'll then be able to scrape the target pages and write the results to a JSON file (other formats exist) and use that to fillProducts - whatever that does.
Also, are you stealing data from someone else's website? Cause that isn't cool.
Here's a solution that may work for you if they are sending their ajax requests using jQuery. If they aren't you're going to need to get devilishly hacky to accomplish what you're asking (eg overriding the XMLHttpRequest object and creating a global observer queue for ajax requests). As you haven't specified how they're sending the ajax request I hope this approach works for you.
$.ajaxSetup({
complete: function(jQXHR) {
if(interested)
//do your work
}
});
The code below will click a link, wait for the ajax request to be sent and be completed, run you fillProducts function and then click the next link. Adapting it to run all the clicks wouldn't be difficult
function start(){
var links = $('.category a');
var i = 0;
var done = function() {
$.ajaxSetup({
complete: $.noop//remove your handler
});
}
var clickNext = function() {
$(links.get(i++)).click();//click current link then increment i
}
$.ajaxSetup({
complete: function(jQXHR) {
if(i < links.length) {
fillProducts();
clickNext();
} else {
done();
}
}
});
clickNext();
}
If this doesn't work for you try hooking into the other jqXHR events before hacking up the site too much.
Edit here's a more reliable method in case they override the complete setting
(function() {
var $ajax = $.ajax;
var $observer = $({});
//observer pattern from addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery
var obs = window.ajaxObserver = {
subscribe: function() {
$observer.on.apply($observer, arguments);
},
unsubscribe: function() {
$observer.off.apply($observer, arguments);
},
once: function() {
$observer.one.apply($observer, arguments);
},
publish: function() {
$observer.trigger.apply($observer, arguments);
}
};
$.ajax = function() {
var $promise = $ajax.apply(null, arguments);
obs.publish("start", $promise);
return $promise;
};
})();
Now you can hook into $.ajax calls via
ajaxObserver.on("start", function($xhr) {//whenever a $.ajax call is started
$xhr.done(function(data) {
//do stuff
})
});
So you can adapt the other snippet like
function start(){
var links = $('.category a');
var i = 0;
var clickNextLink = function() {
ajaxObserver.one("start", function($xhr) {
$xhr.done(function(data) {
if(i < links.length) {
fillProducts();
clickNextLink();
} else {
done();
}
});
})
$(links.get(i++)).click();//click current link then increment i
}
clickNextLink();
}
try this:
function start(){
$('.category a').each(function(i){
$(this).click();
fillProducts() ;
})
}
I get ya now. This is like say:
when facebook loads, I want to remove the adverts by targeting specific class, and then alter the view that i actually see.
https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/
Is a plugin for firefox, this will allow you to create a javascript file, will then allow you to target a specific element or elements within the html rendered content.
IN order to catch the ajax request traffic, you just need to catcher that within your console.
I can not give you a tutorial on greasemonkey, but you can get the greasemonkey script for facebook, and use that as a guide.
http://mashable.com/2008/12/25/facebook-greasemonkey-scripts/
hope this is it
Part of my HTML page is the following div:
<div id="images_wrapper">
<img ... />
<img ... />
<img ... />
...
</div>
Initially, this div is hidden, and I show it only when all images are loaded:
$(window).load(show_images_wrapper);
However, if I'm not mistaken, show_images_wrapper will be called only when all the page is loaded. I would like show_images_wrapper to be called as soon as all images inside images_wrapper has been loaded, and don't wait until all the page is loaded.
I tried:
$("#images_wrapper").load(show_images_wrapper);
but it didn't work.
How should I do this?
Set up a counter to the quantity of the images using the length[docs] property, that is decremented as the images load.
var imgs = $("#images_wrapper > img").not(function() { return this.complete; });
var count = imgs.length;
if (count) {
imgs.load(function() {
count--;
if (!count) {
$("#images_wrapper").show();
alert('all done');
}
});
} else {
$("#images_wrapper").show();
}
The the not()[docs] method is removing from the matched set the images where their .complete property is true. This means the image has already downloaded, and was perhaps cached by bhe browser.
Of course the load()[docs] method fires as each image finishes loading.
Example: http://jsfiddle.net/uhmAR/1/
EDIT: Changed it so that the container will show if all the images happened to be cached.
EDIT:
Another variation on the above is to bind the .load() to all the images, and use the filter()[docs] method to get the ones that are .complete, and just manually invoke the .load() on them.
This removes the need for the if/else statement.
var imgs = $("#images_wrapper > img")
var count = imgs.length;
imgs.load(function() {
count--;
if (!count) {
$("#images_wrapper").show();
alert('all done');
}
}).filter(function() { return this.complete; }).load();
Example: http://jsfiddle.net/uhmAR/3/
I wrote a jQuery plugin that can do this.
$('#images_wrapper').waitForImages(function() {
// Done.
});
Alternatively,
var images = $('#images_wrapper img'),
imagesLength = images.length;
images.load(function() {
if ( ! --imagesLength) {
// Done.
}
});