Catch window.onload after DOM change - javascript

What I want is to be notified when all images are loaded after DOM change. I know there is a jQuery plugin, but I'm wondering if there is any native method.
Example of code that does not work:
https://jsfiddle.net/wanpd5su/3/
// Real implementation will do an AJAX request to retrieve new
// document content. This one just sets a timeout instead.
$('#button').on('click', function doAjaxRequest() {
// This function changes the document content so that it
// contains new uncached images.
window.setTimeout(function changeContent() {
document.body.innerHTML = '<div id="div" style="background-image:url(\'http://lorempixel.com/800/600/abstract/?' + Math.random() + '\'); height:600px; width:800px;"></div>';
// This handler should run when new conent
// is ready and all images are loaded.
// BOT IT DOES NOT :(
$(window).on('load', function onLoad() {
alert('Document updated successfully.');
});
}, 1000);
});

Related

jQuery / Javascript - get all images that are loaded

This is the code I'm using to get all loaded images:
$("img").on('load', function() {
console.log('Image Loaded');
}).each(function() {
if(this.complete){
//$(this).trigger('load');
var img = $(this).attr('src');
console.log(img);
}
});
but it's not working with those that are loaded with ajax afterwards, so I tried:
$(document).on('load', 'img', function(){
console.log('Image Loaded');
}).each(function() {
if(this.complete){
//$(this).trigger('load');
var img = $(this).attr('src');
console.log(img);
}
});
but it's not doing anything, what would be the correct way? I need to manipulate the parent divs of each image that is freshly loaded, so getting just all images period on every ajax load would be overkill and not elegant
How about this?
$(document).on('load', 'img', function(){
console.log('Image Loaded');
var parent = $(this).parent(); //or .parents('div') or .closest('div'), etc..
//do something with parent
});
I will suggest that you create a function for getting images and also call the same function after ajax execution.
Edit
Pass an id or class string present in document or returned ajax data to limit the scope of the function
function getImages(id) {
$('#' + id).find("img").on('load', function() {
console.log('Image Loaded');
}).each(function() {
if(this.complete) {
//$(this).trigger('load');
var img = $(this).attr('src');
console.log(img);
}
});
}
getImages('outsideAjax'); // call during normal execution. outsideAjax is an id within your html document but not in the returned ajax data
$.ajax({
// ajax settings
}).done(function() {
// post ajax code
// append returned data to document
getImages('insideAjax'); // recall after successful ajax execution and appending of returned data. 'insideAjax' is an id inside your return ajax data
}).fail(function(jqXHR, textStatus, errorThrown) {
// report error
});
This is how I solved it:
<img src="' + picUrl + '" onload="checkPic(\'' + picUrl + '\', this.naturalHeight, this.height);" class="pic">
Inside AJAX response.
I think it's self explanatory, works perfectly!
In the checkPic functuion I find this element by the src and get the parent elements and so on.

Call user defined jQuery function with JS

I use a jQuery window libray https://github.com/humaan/Modaal
which triggers events this way $("class of element").modaal({arg1, arg2,...});
--- I updated my question here to make it more general and used an iframe / Html instead of an external svg ---
To trigger an element e.g. in an external Html which is loaded within an iframe, I applied the following code to the iframe:
<iframe src="External.html" id="mainContent" onload="access()"></iframe>
which calls this function:
function access() {
var html = document.getElementById("mainContent").contentDocument.getElementById("IDofDIVelement");
html.addEventListener('click', function() {clicker();});
}
function clicker()
{
// console.log('hooray!');
$("#mainContent").contents().find("IDofDIVelement").modaal({});
//return false;
}
Actually it will only work on every second click. Any idea what I did not consider properly?
Best
You do not need to wait windows loading but iframe only:
$(function() {
$("#mainContent").bind("load",function(){
var myIframeElement = $(this).contents().find(".modaal");
myIframeElement.modaal({
content_source: '#iframe-content',
type: 'inline',
});
});
});
The reason why it did not work was that the iframe was not completely loaded, while jQuery tried to attach the function. As $(document).ready(function(){} did not work, the workaround was to initialize it with
$( window ).on( "load",function() {
$("#mainContent").contents().find("IDofDIVelement").modaal({});
});
This worked properly to attach the functionallity to an element within the iframe.
Actually modaal will vanish the envent handler after the overlay was opened and closed again.
So maybe someone wants to trigger an iframe element for modaal, too, here is a setup which would solve this issue.
(It can be optimised by #SvenLiivaks answer):
$(window).on("load", function() {
reload();
});
function reload() {
var length = $("#iframeID").contents().find("#IDofDIVelement").length;
// The following check will return 1, as the iframe exists.
if (length == 0) {
setTimeout(function() { reload() }, 500);
} else {
$("#iframeID").contents().find("#IDofDIVelement").modaal({
content_source: '#modalwrapper',
overlay_close: true,
after_close: function reattach() {
reload();
}
});
}
}

How to show loading image before Action is completed ASP.Net MVC 5

This is an ASP.Net MVC 5 project.
I have a simple javascript/jQuery as follow:
<script>
$(document).ready(function () {
$("#textBox").focusout(function () {
var phrase= $("#textBox").val();
phrase= phrase.replace(new RegExp(/\s+/, 'g'), "%20");
$("#commentDiv").load("../Search/SearchSingular?phrase=" + phrase);
});
});
</script>
As you can see, there is a jQuery .load method which calls SearchSingular action in the Search controller when the focus is out from HTML element with id = textBox. This works well, except that the SearchSingular action execution may sometimes take time to finish.
Thus, I want to show a loading image when the load is not finished. Is there any way to do this?
Turn it into a callback
// Somecode to display a image
$("#commentDiv").load("../Search/SearchSingular?phrase=" + phrase, function() {
// Somecode to remove image
});
You can use a loading image while div contents load
("#loadingImage").show();
$("#commentDiv").load("../Search/SearchSingular?phrase=" + phrase, function(){
$("#loadingImage").hide(); // hide the image after loading of div completes
});
Div for your loading image
<div id="loadingImage">
<img src="loader.gif">
</div>
There is a complete callback of jQuery .load function (read more http://api.jquery.com/load/)
You could revise your javascript as following:
<script>
$(document).ready(function () {
$("#textBox").focusout(function () {
var phrase= $("#textBox").val();
phrase= phrase.replace(new RegExp(/\s+/, 'g'), "%20");
ShowLoading();
$("#commentDiv").load(
"../Search/SearchSingular?phrase=" + phrase,
function () { HideLoading(); }
);
});
});
</script>

Load javascript after 5 seconds after page has loaded?

I have tried the following:
<body id="myBody" onload = "setTimeout('a()', 5000)" / >
Is this the correct method? The reason why I want to do this is because I have my entire website animating in (such as fade ins) on page load. Having my javascript only makes the animation unsmooth.
Any feedback appreciated.
This code will work. Just set your time in milliseconds and write your JS code on loadAfterTime function:
<script>
window.onload = function(){
setTimeout(loadAfterTime, 5000)
};
function loadAfterTime() {
// code you need to execute goes here.
}
</script>
window.addEventListener("load", function () {
animation();
setTimeout(otherOperation, 5000);
}, false);
function animation() {}
function otherOperation() {}
maybe you can use code like this
<body id="myBody" onload = "setTimeout(a, 5000)">
Try this
if you are using jQuery your animation has a callback that you can use to delay the firing of all other javascript events like so:
$( window ).on( 'load', function () {
$( '.someElements' ).animate({
// properties to animate
}, 300, function () {
initScripts();
});
});
function initScripts () {
// call all other functions here
}
The Browser is always load all of your script if any when you open the web page. So It depend on when you call your javascript functions.
Try this:
document.ready(function(){
// your code
});
or
$(function(){
// your code
});
both of them make sure that all of element on your page have been loaded.

How to wait for div to load before calling another function?

<script>
var href;
$(function(){
$("a.load").click(function (e) {
e.preventDefault();
href = this;
// cover all bookmarks
$("."+($(this).attr("class"))).css('border-bottom', 'solid 1px black');
$("."+($(this).attr("class"))).css('background-color', '#F5F5F5');
// uncover chosen bookmark
$("#"+($(this).attr("id"))).css('border-bottom', 'solid 2px white');
$("#"+($(this).attr("id"))).css('background-color', 'white');
$("#tempMain").load($(this).attr("href")); // load content to temp div
setTimeout(function() {resizeDivs();}, 500); // synchronize size of #main and #rightColumn
});
});
function resizeDivs() {
var heightNew = $("#tempMain").css("height");
$("#rightColumn").css('height',heightNew);
$("#main").css('height',heightNew);
// $('#main').load($(href).attr('href'));
$("#main").html($("#tempMain").html()); // is faster than loading again
}
</script>
I'm loading subpages to a selected div of my main page by a jQuery function. In order to synchronise main div's and right column's height I'm using jQuery's .css() method. I wanted that resizing to look smoothly, so I've resolved it to following steps:
1. Load content of a subpage to an invisible temp div.
2. Calculate the height of that temp div.
3. Change the height of main div and right column to the height of that temp div.
4. Load content of a subpage to main div.
However, I am aware that my current way of doing this is pretty lame because of using setTimeout() as an improvisation of waiting for content to load - I've tried using $(document).ready but with no luck. Using a global variable (var href) also doesn't seem lege artis, but passing this operator of $("a.load").click function by apply() didn't work either.
How to do it "the right" way?
with jquery
function waitForElement(elementPath, callBack){
window.setTimeout(function(){
if($(elementPath).length){
callBack(elementPath, $(elementPath));
}else{
waitForElement(elementPath, callBack);
}
},500)
}
e.g. to use:
waitForElement("#myDiv",function(){
console.log("done");
});
here is without jquery
function waitForElement(elementId, callBack){
window.setTimeout(function(){
var element = document.getElementById(elementId);
if(element){
callBack(elementId, element);
}else{
waitForElement(elementId, callBack);
}
},500)
}
e.g. to use:
waitForElement("yourId",function(){
console.log("done");
});
Use load callback
$("#tempMain").load($(this).attr("href"),function(){
resizeDivs();
// do other stuff load is completed
});
You can attach a callback in the jQuery load function :
$("#tempMain").load($(this).attr("href"), resizeDivs);
see : http://api.jquery.com/load/
a simple script that i use to check if a (dynamic) DIV is loaded:
var tid = setInterval(timer, 100);
function timer() {
var elementExist = $('#DIV');
if (elementExist.length == 1) {
functionToLoad();
}
}
function functionToLoad(){
clearInterval(tid);
// REST OF CODE
}

Categories