javascriptjqueryinternet-explorerjquery-eventshtml-components

jQuery ready firing before custom behavior script initializes


Background

I've inherited an ancient web application that has input controls with custom behaviors defined with an old-fashioned HTC (HTML Component) script, e.g.:

<input name="txtFiscalYearEndDay" type="text" value="30" 
    maxlength="2" size="5" id="txtFiscalYearEndDay" class="Text1"       
    style="behavior:url(/path/js/InFocus.htc);" />

Here are the relevant parts of this HTC file to illustrate the issue:

<PUBLIC:COMPONENT tagName="InFocus">
<PUBLIC:METHOD NAME="setValid" />
<PUBLIC:ATTACH EVENT="ondocumentready" HANDLER="initialize" />
<SCRIPT LANGUAGE="javascript">

    function initialize() {
        // attaches events and adds CSS classes, nothing fancy
    }        

    function setValid(bInternal) {
        // checks some flags and changes a label
    } 

</SCRIPT>
</PUBLIC:COMPONENT>

So, nothing out of the ordinary so far. Additionally, I have some JS that runs on DOM-ready:

$(function() {
    txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
});

And the validation function:

function txtFiscalYearEndDay_Validate(el) {
    ...
}

Note: I'm not using $('#txtFiscalYearEndDay') because then I really can't try to call setValid(true); on the element, nor do I want to have to do $('#txtFiscalYearEndDay')[0].setValid(true);.

The problem

At one point in the validation function, I'm attempting to call a method on the element, the one added by the HTC script:

el.setValid(true);

However, the IE debugger gets sad and complains that setValid() is not a function. Inspecting it in the debugger confirms this:

typeof el.setValid // "unknown"

Of course, once the page has completed rendering (or whatever period of time is needed for the document to actually be ready has passed), the validation function works as expected (because I'm calling the same validation function on change and blur events as well). That is, when the function is called outside of jQuery's on-DOM-ready function, it works just fine.

Do any of you have any ideas at to what might be happening here? Is jQuery's "ondomready" being registered before the HTC script's "ondomready"? Can I somehow change that order?

I'm currently seeing this behavior in all versions of IE.

EDIT: WORKAROUND

I discovered a workaround. If you take the function call out of the jQuery ready function and throw it at the end of the page, it works (i.e.:)

...
    <script type="text/javascript">
        txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
    </script>
</body>
</html>

Solution

  • The easiest workaround I could find was to move the validation function call out of the jQuery ready() callback and move it to the end of the page:

    ...
        <script type="text/javascript">
            txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
        </script>
    </body>
    </html>
    

    However, I found a more elegant solution. Because I seemingly need to wait for all page resources to be loaded, I simply needed to move the function call out of the jQuery ready() callback and instead put it in a window load() callback:

    $(window).load(function() { // instead of $(function() {
        txtFiscalYearEndDay_Validate(document.getElementById('txtFiscalYearEndDay'));
    });
    

    I'm using the latter so I can keep all of the JS code together.