Search code examples
domvbscripthta

When does InnerHTML execute immediately?


I would expect this HTA code to print a to be replaced some time later by b. However, what it does is it prints nothing for some time, and then b. With the MsgBox line enabled, it does print a first.

It seems that the execution of statusinfo.InnerHTML = "a" is postponed. Can any body tell me why this is? And how would I obtain the desired behavior (immediate refresh)?

<SCRIPT LANGUAGE=VBScript>
    Sub doThis()
        statusinfo.InnerHTML = "a"
        'MsgBox "stop"
        intensiveOperation
        statusinfo.InnerHTML = "b"
    End Sub

    Sub intensiveOperation()
        'takes long
    End Sub
</SCRIPT>

<BODY>
    <button onclick="doThis">Run</button>
    <div id="statusinfo">&nbsp;</div>
</BODY>
</HTML>

Solution

  • Scripts and rendering are executed in a single thread. This means, that doThis will be finished before rendering starts. In the meanwhile you've set the inner HTML to 'b', and that will be the only result you'll see.

    To fix this, you've to finish the first sub, and call intensiveOperation with a short delay, and make the final HTML update at the end of the second sub, like so:

    Sub doThis
        statusinfo.InnerHTML = "a"
        Call window.setTimeout(GetRef("intensiveOperation"), 4)
    End Sub
    
    Sub intensiveOperation()
        'takes long
        statusinfo.InnerHTML = "b"
    End Sub
    

    Finishing doThis will free the thread. Notice, that setTimeout won't halt the execution, the whole sub is executed to the end. After that browser can render the page.

    intensiveOperation is called at some point after the rendering is finished, not earlier than the given delay, but possibly much later, depending on tasks CPU is doing at the time.

    The answer to the question in the header of the question is basically: never.