Mahyar Pasarzangene
Mahyar Pasarzangene

Reputation: 373

Changing a div content twice in one pass

Hi this is my first question on stackoverflow , and I hope it can help me on my problem.

I have a empty div section on a user control like this :

<div id="attachmentlist"></div>

this div's content will load in a javascript function named bindattachment() in this function I used some jquery function to set html and set it to div content like this

jQuery("#attachmentlist").html(somegeneratedhtml);

it works ok but generating "somegeneratedhtml" takes too long and I want before that div content sets to this generated html, a text like "loading please wait ..." shows in same div . So I used same code to set html before setting div with "somegeneratedhtml" like this

jQuery("#attachmentlist").html('<p>loading please wait ...');

So bindattachment() will look like this

function bindattachment()
{
   jQuery("#attachmentlist").html('<p>loading please wait ...</p>');
   var html;
   html = "somegeneratedhtml";
   jQuery("#attachmentlist").html(html);
}

and what I get is a list of attachment links on div but "loading please wait ..." never shows.

I want until html generates on bindattachment "loading please wait ..." phrase shows in div

Upvotes: 2

Views: 520

Answers (5)

Ruan Mendes
Ruan Mendes

Reputation: 92274

During a JS execution context, the UI is usually only updated after your JS finishes. Therefore, calling

jQuery("#attachmentlist").html('<p>Loading, please wait ...</p>');
// long loop here
jQuery("#attachmentlist").html('<p>Finished</p>');

Means that the first update to the DOM (calling .html) will be ignored since the UI thread never gets run until the JS finishes. There are things you can do in JS that would trigger a layout but it doesn't mean the UI will actually update.

If you want to make sure the first message displays, you should update it, then run your code to generate the HTML asynchronously. For example,

var div = $('#attachmentlist');
// This will never display because the HTML is overwritten before the UI thread
// runs
div.html('<p>First call to set html, will not display');
// This will display because there are no other synchronous calls to update the same
// DOM elemements
div.html("second call to set html, this displays");
// The function passed to setTimeout runs after the UI has had a chance to update
setTimeout(function() {
    // Long running script
    var html = "";
    for (var i=0; i < 100000; i ++) {
        html+= "testing...<br/>";
    }
    // By updating the HTML with a timeout, the previous call to $.html
    // will be visible on the screen for a minimum amount of time
    div.html(html);
}, 1);

Note on Long Running Scripts

Note that if generating the HTML with JS is taking a long time, it could lock up the browser, and you should use Web Workers to generate the HTML asynchronously, that is, it wouldn't lock up the UI as JS running under the normal JS thread would.

Upvotes: 4

Walter Macambira
Walter Macambira

Reputation: 2605

The time it is taking is not to change the html inside the div, it is to render your html.

Upvotes: -1

Jon Harding
Jon Harding

Reputation: 4946

I created a jsfiddle with your code. I added a simple $(document).ready() function to run the function.

$(document).ready(function() {
   bindattachment(); 
});

function bindattachment()
{
   jQuery("#attachmentlist").html('<p>loading please wait ...</p>');
   var html;
   html = "somegeneratedhtml";
   jQuery("#attachmentlist").html(html);
}

The div shows the correct 'somegeneratedhtml'.

It would be helpful to see what is generating 'somegeneratedhtml'. The error might be happening within that function.

Upvotes: 0

Jias
Jias

Reputation: 174

I'm surprised that it takes that long to load but I would guess that what's happening is loading please wait is quickly replaced in jQuery("attachmentlist").html(somegeneratedhtml);. What I would do is create two divs inside attachmentlist. Have one contain the loading message and the other will be for the generated html. Use .hide() and .show() to choose which is shown.

Upvotes: 0

Ana Sampaio
Ana Sampaio

Reputation: 351

In jQuery you have to use

jQuery("#attachmentlist").html('<p>loading please wait ...</p>');

to add your text in a div with the id attachmentlist.

Ok, you already corrected it :)

Upvotes: 0

Related Questions