tags:

views:

461

answers:

3

Is it possible to have one jQuery ready block executed after all others have done so.

I have this in my master page ...

<script type="text/javascript">
    $(document).ready(function()
    {
        $("input[type='text']:enabled:first", document.forms[0]).focus().select();
    });
</script>

and this in one of my other pages ...

<script type="text/javascript">
    $(document).ready(function()
    {
        $('textarea.message-body').wysiwyg();
    });
</script>

The problem I am seeing is that the first block is executed before the second block, which is causing a problem with the tab key. What's happening is that the keyboard focus goes to the address bar in my browser when I press the tab key. I've changed the code slightly to have this in my master page ...

<script type="text/javascript">
    $(document).ready(function()
    {
        var bodies = $('textarea.message-body');
        if (bodies.length > 0)
        {
            bodies.wysiwyg();
        }

        $("input[type='text']:enabled:first", document.forms[0]).focus().select();
    });
</script>

and do away with the other ready block completely. Doing that makes the tab key work properly, and set the focus onto my textarea.

I'd rather not have page specific code in my master page.

So, is there a way to make my textbox focusing code run after the wysiwyg code?

A: 

How about only you only registring one document.ready() on the master page, and then let that one execute the code based on a variable? This solution is not that elegant, but a search for JavaScript thread synchronization didn't really turn op anything.

You could change the code on the master page to:

<script type="text/javascript">
    var runWysiwyg = false;
    $(document).ready(function()
    {
        if (runWysiwyg) {
            $('textarea.message-body').wysiwyg();
        }
        $("input[type='text']:enabled:first", document.forms[0]).focus().select();
    });
</script>

And put this script in you page:

<script type="text/javascript">
    runWysiwyg = true;
</script>
Jan Aagaard
Thanks, I'd sort of got the same solution. I've gone for having an OnLoad() function in my page, with this in the master ... <script type="text/javascript"> $(document).ready(function() { if (typeof (OnLoad) != "undefined") { OnLoad(); } $("input[type='text']:enabled:first", document.forms[0]).focus().select(); }); </script>
Antony Scott
I looked some more for a general solution on the synchronization problem and found that JavaScript is not multithreaded: http://stackoverflow.com/questions/39879/why-doesnt-javascript-support-multithreading
Jan Aagaard
+2  A: 

You could just put a setTimeout in the one that you want to run last, and have it start after 50ms, which should be enough time for the rest to have finished, but not enough for a user to notice. Your code that you want to run last will be within the setTimeout.

James Black
A: 

This is the solution I went with.

In my master page I have this...

<script type="text/javascript">
<!--
    $(document).ready(function()
    {
        if (typeof (OnLoad) != "undefined")
        {
            OnLoad();
        }

        $("input[type='text']:enabled:first", document.forms[0]).focus().select();
    });
//-->
</script>

and in my detail pages I have this...

<script type="text/javascript">
<!--
    function OnLoad()
    {
        $('textarea.message-body').wysiwyg();
    }
//-->
</script>
Antony Scott