jQuery Document Ready: the $(function(){}) Shorthand and noConflict

A flat vector illustration showing a code document outline containing a cyan dollar sign, marked with a gold checkmark. Text: JQUERY READY.

The cleanest way to run jQuery code after the page is ready is $(function () { ... }), the shorthand for $(document).ready(function () { ... }). This DevAnswers guide covers the shorthand, what jQuery 3.0 changed, and the WordPress quirk that throws the "$ is not a function" error.

Use the $(function(){ … }) Shorthand 

Pass your function straight to $(). jQuery runs it once the DOM is ready, the point at which the document is safe to manipulate:

JavaScript
$(function () {
    // Runs once the DOM is ready
    console.log('ready!');
});

That is exactly equivalent to the longer, more familiar form. Both attach the same handler, and both fire at the same moment:

JavaScript
$(document).ready(function () {
    // Same thing, longer to type
    console.log('ready!');
});

“Ready” here means the browser has finished building the page structure (the DOM) from your HTML, so your selectors can actually find elements and your handlers can attach to them. It does not wait for images or stylesheets to finish downloading, which is why running code on ready feels instant compared to waiting for the whole page to load.

Shorthand vs Long Form (and What jQuery 3.0 Changed) 

jQuery offers several ways to attach a ready handler, and they are all equivalent: $(handler), $(document).ready(handler), even oddities like $("img").ready(handler) (the selector is ignored). Passing the function directly to $() is the form the jQuery team recommends, so the shorthand is not just shorter, it is the preferred syntax.

One form to avoid: $(document).on("ready", handler) was deprecated in jQuery 1.8 and removed in jQuery 3.0. If you are maintaining old code, replace it with the shorthand.

Do not confuse ready with load. The window load event waits for the entire page, including images and iframes, while ready fires earlier, as soon as the DOM is parsed. Use ready unless you genuinely need images measured:

EventFires whenUse for
$(function(){}) (ready)The DOM is parsedAlmost everything: event handlers, plugin init
$(window).on('load', ...)The whole page is loaded (images, iframes)Code that needs final image dimensions

Fixing “$ is not a function” in WordPress 

This is the error that catches almost everyone working in a WordPress theme or plugin. WordPress loads its bundled copy of jQuery in noConflict() mode, which releases the $ shortcut so it cannot clash with other libraries. Your code that uses $ directly then throws Uncaught TypeError: $ is not a function.

The fix is to map $ back to jQuery inside your handler. Conveniently, jQuery(function ($) { ... }) is both a document-ready wrapper and the noConflict-safe pattern in one:

JavaScript
jQuery(function ($) {
    // $ works as normal inside here, and the DOM is ready
    $('.menu-toggle').on('click', function () {
        $(this).toggleClass('is-open');
    });
});

Load this through the proper enqueue route so jQuery is present first: see adding a custom JS file the correct way. With the wrapper above you never touch the bare $ outside the function, so noConflict can never bite.

The Plain-JavaScript Equivalent: DOMContentLoaded 

If you are writing code without jQuery, the native event that fires at the same point is DOMContentLoaded. It fires when the initial HTML has been completely loaded and parsed, without waiting for stylesheets, images, and subframes:

JavaScript
document.addEventListener('DOMContentLoaded', function () {
    // The DOM is parsed and ready
    console.log('DOM ready');
});

For new projects you often need no ready wrapper at all: add the defer attribute to your <script> tag, or place the script just before </body>, and the DOM is already there when your code runs.

Troubleshooting 

  • $ is not a function or $ is not defined. jQuery is in noConflict mode (the default in WordPress). Wrap your code in jQuery(function ($) { ... }) as shown above, or call jQuery instead of $.
  • The handler never runs. A jQuery ready handler still fires even if the DOM was already ready when you attached it. The native DOMContentLoaded does not: if you add that listener after the event has fired, check document.readyState first and run the code directly when it is already "interactive" or "complete".
  • Elements come back empty. A script that runs before the DOM exists (for example in the <head> with no wrapper) selects nothing. Wrap it in ready, add defer, or move the script to the end of the body.

Summary 

Reach for $(function () { ... }): it is the recommended jQuery shorthand for $(document).ready(). Inside WordPress, wrap it as jQuery(function ($) { ... }) so the $ shortcut works despite noConflict. And when you are not using jQuery at all, document.addEventListener('DOMContentLoaded', ...) is the native equivalent.

Support DevAnswers
Written, tested and maintained by one developer. Your support keeps these guides accurate and ad-light.
Buy me a coffee

Comments

Leave a reply