-1

I'm trying to decorate jQuery document.ready function

<html>
<head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script type="text/javascript">
        $(function() {
            console.log("ready2");
        });
    </script>
    <script type="text/javascript">
        $.fn.ready = (function(fn) {
            return function() {
                console.log("ready1");
                return fn.apply(this, arguments);
            }
        })($.fn.ready);
    </script>
</head>
<body>
    <img src="http://deelay.me/1000?http://my-site.com/image.gif" />
</body>
</html>

What I'm expecting to see - is "ready1" and "ready2" in browser console, however there is only "ready2". What I'm missing?

FiddleJS: http://jsfiddle.net/GXCnu/

UPDATE #1: Well actually its clear why its not working - its because I'm calling ready() first.... Then another question - how to call custom function just before $.ready() will be triggered?

Vytalyi
  • 1,637
  • 3
  • 20
  • 33

3 Answers3

2

You call ready() first, and only then decorate it. Reverse the order.

Kos
  • 70,399
  • 25
  • 169
  • 233
  • 1
    `$.ready` is called immediately and schedules whatever you pass as an argument to be called when the document is ready. – Kos Mar 13 '14 at 15:26
  • @Vytalyi: The event is triggered after it's fully processed, yes. But `$(function() {` is the same as doing `$(document).ready(function(){`, so you are calling `.ready` *before* you modify it. – gen_Eric Mar 13 '14 at 15:27
  • yeah... so another question - is there a way how to call my custom function just before $.ready wil be triggered? – Vytalyi Mar 13 '14 at 15:28
  • @Vytalyi: Before the event gets triggered? Why do you want to do that? – gen_Eric Mar 13 '14 at 15:31
  • let's say I'm trying to to override some content from my external custom script which is included at the end of . So I need to do it just before DOM ready. Does it make sense? – Vytalyi Mar 13 '14 at 15:34
  • @Vytalyi: You can add multiple `$(document).ready` events. They will be triggered in the order they were set. Would that work for you? – gen_Eric Mar 13 '14 at 15:35
  • the problem is that MY script placed at the end of head - so I don't have a chance/access to modify previously declared $.ready functions. – Vytalyi Mar 13 '14 at 15:36
  • @Vytalyi: You can't re-order your scripts? – gen_Eric Mar 13 '14 at 15:38
  • No - I can't. My script is ALWAYS at the bottom of head – Vytalyi Mar 13 '14 at 15:38
  • @Vytalyi: Then I'm not sure what you can do. Can you modify the other scripts? – gen_Eric Mar 13 '14 at 15:38
  • No its a specific of our product.... The client includes our script at the end of head - we do rest of things. No access to their codebase – Vytalyi Mar 13 '14 at 15:40
  • @Vytalyi: I thought of one thing. The `.ready` event triggers on either the `onreadystatechange` or `DOMContentLoaded` event. Maybe you can manually bind to that and check `document.readyState` (`.ready` runs when it's "complete"). – gen_Eric Mar 13 '14 at 15:43
  • Unbind previous events from `ready()` and add your own? http://stackoverflow.com/questions/2008592/can-i-find-events-bound-on-an-element-with-jquery – Kos Mar 13 '14 at 15:46
1

jQuery just binds to either the onreadystatechange or DOMContentLoaded events [1]. It checks to see if document.readyState === "complete".

One idea I had was to bind an event to check instead for this.readyState === 'interactive'. This should happen before "complete".

$(function () {
    console.log("ready2");
});

$(document).on('readystatechange', function(){
    if(this.readyState === 'interactive'){
        console.log('ready1');
    }
});

DEMO: http://jsfiddle.net/vP5vZ/

1 http://james.padolsey.com/jquery/#v=1.6.2&fn=jQuery.bindReady

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
-1

This is the fix:

$.fn.ready = (function(fn) {
        return function() {
            console.log("ready1");
            return fn.apply(this, arguments);
        }
    })($.fn.ready)();

Note the () at the end right before the semicolon. You must invoke the inner function that gets returned.

Kevin Le - Khnle
  • 10,579
  • 11
  • 54
  • 80
  • No. You don't want to invoke the inner function. You want it to be returned and stored in `$.fn.ready`. – gen_Eric Mar 13 '14 at 15:31