I call those functions on href:
function LoadDiv1() {
var uri = '#this.Routes().Parts.Div1.FullUrl(Model.SignedInUser.User.Id)';
$('#home_content').load(uri).css("display", "none").fadeIn(500);
}
function LoadDiv2() {
var uri = '#this.Routes().Parts.Div2.FullUrl(Model.SignedInUser.User.Id)';
uri = uri.replace('amp;', '');
$('#home_content').load(uri).css("display", "none").fadeIn(500);
}
They switch correctly, but every time i switch to another div, first of all i get current div loaded again, and then switched to another. It looks like delay.
You're making an asynchronous call to the server but the methods in the chain are executed immediately. The div's contents are updated only later when the data has been loaded from the server. You must add the fadein method to the callback function of the Ajax call so that it executes only after the contents have been updated.
$('#home_content').css("display", "none").load( uri,
function() { $( '#home_content' ).fadeIn(500) } );
Related
I am creating tests for a page and HAVE to use jQuery to change elements on the control version of the page for each different experience.
I'm using jquery to load an element from an external page and replace a div. However, on the external page, it uses an ajax call to an api to populate the div, so I copied over the function with the ajax call.
I think it is attempting to make the ajax call before the new div is actually loaded on the page.
I've tried moving the function, wrapping the load function within the ajax call, but it still doesnt work.
I could be missing something obvious, but here's that part of my code:
$('.replace-div').load('external.html #replace-div');
function waitForLoad() {
if ($('#replace-div')) {
var object;
$.ajax({
url: "https://api.com",
async: false,
success: function(result) {
object = result;
var variable1 = object["blah"][0].value,
var variable2 = object["blah"][0].value,
var variable3 = object["blah"][0].value,
var variable4 = object["blah"][0].value,
$('newElement').attr('href', variable1);
$('newElement2').attr('src', variable2);
$('newElement3').attr('href', variable3);
$('newElement4').text("text" + variable4 + "more text");
}
});
} else {
setTimeout(waitForLoad, 15);
}
}
waitForLoad();
I don't get any errors in the console, and when I paste the above waitForLoad function into the console, it populates totally fine. obviously this is after the page loads the new div, so i just need to know how to make the ajax call wait for the load.
I've tried .ajaxComplete(), but it doesnt help.
$(function() {}); also does not work
.load() has a callback argument where you supply a function to run after the data is loaded.
$('replace-div').load('external.html #replace-div', function() {
$.ajax(...);
});
So, what happens is that, once waitForLoad is called for the first time, it doesn't see the div loaded, the code goes to the else block and executes again with a 15ms timeout. 15ms is not enough for the div to load, most likely.
You can try three things (ordered from worse to better):
Try increasing the timeout to a bigger number. Start with 1000 (1000ms - 1 second) and see if it works or you need to increase it. It's more likely you'll have to decrease it
Try using setInterval instead of setTimeout, which will repeat itself. Of course, once it loads, you'll need to clear the interval so it stops. Also, better use bigger timeouts/intervals, like 50 or 100ms b/c the fast firing timers can slow down a page a lot
E.g.
$('.replace-div').load('external.html #replace-div');
function waitForLoad() {
if ($('#replace-div')) {
clearInterval(window.waiter);
...
} else {
window.timer = setInterval(waitForLoad, 50);
}
}
waitForLoad();
Same as 2, but using more idiomatic callback function after load call.
// the window.waiter is the interval handle, and it will run every 100ms. It calls .load every time, and if the #replace-div is found, unsets the interval handle.
window.waiter = setInterval(function() {
$(".replace-div").load("external.html #replace-div", function() {
if ($(".replace-div #replace-div").length) {
// found the DIV
// code...
clearInterval(window.waiter); // bye interval handle, thanks
}
});
}, 100);
I use jquery load to put a html structure in my body page. Afterwards, I want to call another function to display the table headers. It is suppose to run the function after the load. However, when I insert the completion function in the load parameters, the load is never complete. If I take it out, I don't get to call my function.
app.js
function insertHTML(){
var thead = document.getElementByID("thead");
thead.innerHTML = theadOutput(); //function works fine
}
window.onload = function(){
$(body).load(body_loc, insertHTML());
}
You need to pass the function reference, instead of calling it:
$(body).load(body_loc, insertHTML);
I have a function that I use to reload an Iframe, and I want it to do more things after the Iframe is reloaded rather than at the same time.
var heightArray = [];
function changeScroll() {
console.log(Number(heightArray[0]));
$('#vidList').contents().scrollTop(Number(heightArray[0]));
}
function changeVideo(source, title, desc) {
heightArray = [];
$("#current-video_html5_api").attr('src', source);
$(".vidTitle").html(title);
$(".vidDesc").html(desc);
document.getElementById('vidList').contentWindow.location.reload();
//Stuff I want to happen after ^ this happens
var vidListHeight = $('#vidList').contents().scrollTop();
heightArray.push(vidListHeight);
console.log(heightArray);
changeScroll();
}
How would I go about making it so all the things within changeVideo() that appear after document.getElementById('vidList').contentWindow.location.reload(); actually happen after it. In other words, how do I make the function finish running each thing individually before running the next (i.e First, heightArray is cleared, then the source of curreent-video_html5_api changes, etc.)
All your code runs synchronously instead of reloading a frame.
So, you need to call you code that you need run after you need call asynchronously after reloading that frame.
Frame has onload event that you could subscribe for:
document.getElementById('vidList').load = function() {
var vidListHeight = $('#vidList').contents().scrollTop();
heightArray.push(vidListHeight);
console.log(heightArray);
changeScroll();
};
I got this seemingly simple problem, yet I cannot find the correct way of execution.
I have 2 select tags, the first one is COLOR and the second one is SIZE. The second one is dependent on the first one.
To retrieve the price of the products (which is from the database), I intend to call a function within another function. The code stated below.
function checksizes(id)
{
var color=document.getElementById('colors').value;
$("#sizediv").show();
$("#sizediv").load('sizes.php?id='+id+'&color='+color);
var size = document.getElementById('size2').value;
alert(id+size+color);
confirmprice2(id,size,color);
}
function confirmprice2(id,size)
{
$("#price").show();
$("#price").load('price.php?id='+id+'&size='+size);
}
The alert is to check whether the invoked values to be passed on the next function are correct.
Code is working, but returning different results. It seemed that the function checksizes() passes values which are from the previous select (from the size). It calls the second function even before it finishes executing this: $("#sizediv").load('sizes.php?id='+id+'&color='+color);
Help is much appreciated. Thank you!
That's because .load() is asynchronous. It basically forks off another thread to continue its work while the calling code continues what it was doing. If you have code which needs to happen in response to .load() then it needs to be placed in a callback function, not after the function. Something like this:
function checksizes(id) {
var color=document.getElementById('colors').value;
$("#sizediv").show();
$("#sizediv").load('sizes.php?id='+id+'&color='+color, function () {
var size = document.getElementById('size2').value;
alert(id+size+color);
confirmprice2(id,size,color);
});
}
Passing this function as a parameter to .load() will invoke this function after .load() completes.
The load function is an asynchronous function. When the function is "finneshed" does not mean that the result is loaded.
You need the completed Callback for that. See http://api.jquery.com/load/
function checksizes(id)
{
var color=document.getElementById('colors').value;
$("#sizediv").show();
$("#sizediv").load('sizes.php?id='+id+'&color='+color, function(){
var size = document.getElementById('size2').value;
alert(id+size+color);
confirmprice2(id,size,color);
});
}
function confirmprice2(id,size)
{
$("#price").show();
$("#price").load('price.php?id='+id+'&size='+size, function(){
alert('price is loaded');
});
}
As from the jQuery documentation, $.load does indeed not finish before it returns. You should use the callback function:
$( "#result" ).load( "ajax/test.html", function() {
alert( "Load was performed." );
});
http://api.jquery.com/load/
In your case, everything in the checksizes function under the load function call should be placed in the callback.
To my way of thinking, I might be over-engineering with the recursive solution.
Wait 2 seconds for first set of modules to be loaded:
function loadContents() {
$('[data-content]:not(.loaded)').each( function() {
$(this).load($(this).data('content'));
$(this).addClass('loaded');
});
}
loadContents();
setInterval(loadContents, 2000);
When all of first set of modules are loaded, check for new modules:
function loadContents() {
var notLoaded = $('[data-content]:not(.loaded)'),
notLoadedLength = notLoaded.length;
notLoaded.each( function(i,element) {
$(element).addClass('loaded');
$(element).load($(element).data('content'), function() {
// one more has been loaded
notLoadedLength--;
if (notLoadedLength == 0) {
alert("countdown good");
loadContents();
}
});
});
}
loadContents();
You should be able to do all of this with success handlers and no polling with timers.
You don't specify exactly what you want to do, but if you want to load multiple things in parallel and know when they are all loaded, then you can just keep some sort of state on how many have been loaded and when the count shows that they are all now loaded, you will know you're done.
If you want to load them sequentially, then you can just load the next one from each success handler. It's probably easiest to create a list of things to be loaded and just have a generic success handler that gets the next one in the list and kicks off it's load and removes it from the list. When the list of remaining items to load is empty, you're done.
Edit: Looking further at your code, it looks like you're loading them all in parallel. You can just create a success handler for each one that is loading, add the loaded class in that success handler and see how many more have not yet finished. I would suggest this:
function loadContents() {
$('[data-content]:not(.loaded)').each( function() {
var obj = $(this); // save in local variable in function closure so we can reference it in the success handler
obj.load(obj.data('content'), function() {
obj.addClass('loaded');
if ($('[data-content]:not(.loaded)').length == 0) {
// all pieces of content are now loaded
} else {
// some pieces of content are still loading
}
});
});
}
loadContents();
Edit 2: OK, based on your comments, I now understand the problem better. I would scope loadContents to a parent of the DOM tree and then call it on the newly loaded content from the success handler. This will work for inifinite levels and it's safe because it only ever calls itself once for any given parent of the DOM tree. When there is no new content to load, it just has nothing to do and thus doesn't call itself any more. Here's what I would recommend:
function loadContents(root) {
$('[data-content]:not(.loaded)', root).each( function() {
var obj = $(this); // save in local variable in function closure so we can reference it in the success handler
obj.load(obj.data('content'), function() {
obj.addClass('loaded');
loadContents(obj); // now load any contents from the newly loaded content
});
});
}
loadContents(document.body); // start it off by looking in the whole DOM tree