jQuery on() fires only when declared in the $(document).ready's body

Problem

I have an unordered list of paragraphs that need to be revealed when the user clicks once the user clicks on the li that contains the paragraph. The problem is that it simply won't get called unless it is declared inside the $(document).ready() function. I've even tried it on JSFiddle (pay no attention to the language used) and it works just fine, as expected.

// HTML

<ul id="historyList">
        <li>header text<p>text</p></li>
        // ...
        <li>header text<p>text</p></li>
</ul>

// CSS

#historyList li p
{
    display: none;
}

// JS

$(document).ready(function () {
    revealParagraph();
});

// works just fine
function revealParagraph() {
    $("#historyList").on("click", "li", function (event) {
        $("p", this).show();
    });
}

// simply won't work no matter what I do
$("#historyList").on("click", "li", function (event) {
    $("p", this).show();
});

On of these two functions is of course commented-out when I am testing the code. I also have $(window).scroll() and $(window).resize() and they work just fine left "hanging in the air". What am I doing wrong here? I'm working on an ASP.NET project but it hardly matters since this is solely client-side code.

I will provide more info if needed.

Problem courtesy of: Venom

Solution

Excuse my answer since I cannot yet comment on questions due to small reputation

It seems as if your jQuery/Javascript code is within your head tag, and before jQuery is initialised. This means that your code is trying to run without any DOM elements to work with, and without jQuery working at all.

When working with jQuery, try to keep everything within $(document).ready(), or place all of your code before the closing body tag.

Solution courtesy of: Fizzix

Discussion

For efficiency purposes, all your scripts should go before the closing body tag. This will guarantee that everything in the DOM is properly loaded and everything will work smoothly.

It is a good practice to keep all your javascript/jQuery code inside the $('document').ready() event handler.

Also, notice that some elements might not exists, since it's pretty common that nowadays stuff is created in a dynamic way via many tools, the most common one known right now is AJAX in its many forms.

Make sure that all scripts are loaded in a hierarchical way, that will also prevent from javascript/jQuery snippets from loading before other dependencies are, and getting console errors such as jQuery is not defined.

Have in mind that document ready handler waits for ALL the DOM to load, so that it attaches event handlers, and keeps them live during the DOM cycle.

If you put an event handler outside of it, it will not work.

Discussion courtesy of: codeninja

This recipe can be found in it's original form on Stack Over Flow.