11

I've attached multiple functions in multiple files to $(document).ready and would like to attach a single function to happen before them as either the first that $(document).ready handles or to independently trigger before the $(document).ready handler.

Is there any way to handle the order of functions that jQuery triggers internally as part of jQuery.fn.ready or to hook in a function that calls just before jQuery.fn.ready.

Is editing jQuery.fn.ready in a 3rd party script safe to do or will it cause horrible knock on effects in other 3rd party plugins (apart from plugins that edit jQuery.fn.ready themselves)

[Edit]:

as an example

$(document).ready(function b() {});
....
$(document).ready(function a() {/* optional setup*/});
....
$(document).ready(function c() {});

function a needs to happen first irrelevant of order, but only gets called on a few pages. I cant guarantee the order of b or c so I cant trigger custom events at the start of b or c to trigger a.

So I would like a generic solution that I can use to forcefully place a at the start of jQuery's internal readyList or hook into jQuery's ready function and edit it safely so it calls a before any of the other functions in readyList.

[Further Edit]

If possible I would rather not have to redesign the javascript code execution order or have to touch any other code apart from function a(). I'm aware restructuring would allow me to get around this problem but I'd rather just write a single function like

$.beforeReady(function a() {});
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • What will you do when you need to add code that runs before the beforeReady function? Will you add a beforeBeforeReady? Sometimes you just need to bite the bullet and do what needs to be done and fix the code so it makes sense. – Jani Hartikainen Nov 04 '10 at 16:19
  • @Jani you may have a valid point. Still I'd rather create a beforeReady then replaces all occurances .ready with .bind("loaded") and replacing beforeReady with .bind("setup") – Raynos Nov 04 '10 at 16:25
  • This problem should be fixed in the next version of jQuery: https://github.com/jquery/jquery/pull/80 – Mottie Nov 04 '10 at 17:32
  • @fudgey are your referring to the fact he states that the ready system will get an overhaul with 1.5 ? – Raynos Nov 04 '10 at 17:42
  • I don't know the actual timeline for the overhaul to the core, or if that specific change will be added. I meant to share that it is a known issue and will be fixed in a future version. Sorry =( – Mottie Nov 04 '10 at 18:28

3 Answers3

16

This would be a time where I would trigger a custom event that all of your other files would bind to, you would only have one ready handler, which would do stuff, then trigger the custom event.

So, somewhere else in your code, instead of using $(document).ready, you would use

$(window).bind('setup', function() {
   //code here...
});

And/or

$(window).bind('loaded', function() {
   //some other code here...
});

And in your one and only ready handler, you'd do something like this:

$(document).ready(function() {
   $(window).trigger('setup');
   $(window).trigger('loaded'):
});
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
  • The "//do setup stuff" is optional and only done of a few pages. the "//code here" is done on every page. So doing it like that feels backwards. I dont want to include $(window).trigger("someCustomEvent") on every page – Raynos Nov 04 '10 at 15:59
  • @Raynos, You can trigger another custom event to do the setup stuff then. – Jacob Relkin Nov 04 '10 at 16:01
  • If I have multiple functions on document ready I cant guarantee order nor pick a function in which to trigger the setup because I cant guarantee that any of the ready functions are the first one to be called by jQuery – Raynos Nov 04 '10 at 16:08
  • @Raynos, the order of inclusion on the page determines that. – Jacob Relkin Nov 04 '10 at 16:10
  • I'd rather not change the use .ready throughout all my pages. Maybe I'm just being picky. Ill look into how it works internally and use your solution if I cant hook into it directly, thanks. – Raynos Nov 04 '10 at 16:18
  • I give up, calling custom events is a better solution. – Raynos Nov 04 '10 at 17:28
0

$(document).ready() or simply $(function(){}) is just an .addEventListener implementation (well not exactly, but close), meaning you can add listeners before and after.

$(document).ready(listener); // goes off first.
$(document).ready(otherListener); // goes off 2nd.

And so on, it's not hard to sandwich functions. There's no need to hack .ready() imo.

BGerrissen
  • 21,250
  • 3
  • 39
  • 40
  • I rather not have to worry about the exact order about my code with the includes everywhere but rather set the order in code. – Raynos Nov 04 '10 at 15:58
  • Hmm, perhaps you should stop pasting .ready() all over the place. I usually use only a single .ready() where I init all my plugins in and keep it in a single file with nothing else in it (pun intended). ;) – BGerrissen Nov 04 '10 at 16:02
  • 2
    If I had the time to edit the entire legacy project to work like that I would. For the time being I'm stuck with gradual improvement. – Raynos Nov 04 '10 at 16:09
0

I just had the exact same problem. I put a tiny script on GitHub that adds a $.beforeReady() function. Funny :)

https://github.com/aim12340/jQuery-Before-Ready

Just load the script right after jQuery like in this example:

<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
        <script src="jquery-before-ready.js"></script>
    </head>
    <body>
        <script>
            $(document).ready({
                alert("This function is declared first!")
            })
        </script>
        <script>
            $.beforeReady(function(){
                alert("This function is declared second but executes first!")
            })
        </script>        
    </body>
</html>
EamonnM
  • 2,201
  • 1
  • 13
  • 18