jQuery ajaxStart Event

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Ajax events

What You’ll Learn

The ajaxStart event fires when the first qualifying jQuery Ajax request is about to begin — and only when no other global requests are already active. This tutorial covers binding on document with .on("ajaxStart"), pairing with ajaxStop for loading indicators, opting out with global: false, and comparing ajaxStart with per-request events like ajaxSend.

01

Global

AjaxEvent

02

document

Bind target

03

First only

Not every call

04

ajaxStop

Pair for UI

05

global:false

Opt out

06

Since 1.7

.on() API

Introduction

When your page loads data with $.ajax(), $.get(), or .load(), jQuery broadcasts lifecycle events to listeners on document. The ajaxStart event is your “activity just began” hook — it fires once when the first global Ajax request is about to start, giving you a single place to show a loading spinner or disable navigation.

Before jQuery sends a request, it checks whether any other global Ajax calls are still in progress. If none are active, jQuery triggers ajaxStart. When the last active global request finishes, jQuery triggers ajaxStop. That pairing makes ajaxStart ideal for page-wide loading UI without counting individual requests yourself.

Understanding the ajaxStart Event

ajaxStart is classified as an AjaxEvent — a global event triggered by jQuery’s Ajax transport, not a DOM event on a specific element. Whenever an Ajax request is about to be sent and no other global requests are in progress, jQuery triggers ajaxStart on document. Handlers are simple callbacks with no extra arguments — unlike ajaxSend, you do not receive jqXHR or settings.

The handler runs at the very beginning of global Ajax activity — before ajaxSend on the first request, and before any response arrives. For per-request logging or URL filtering, use ajaxSend instead. For hiding the spinner when all requests finish, bind ajaxStop alongside ajaxStart.

💡
Beginner Tip

Bind once: $(document).on("ajaxStart", showSpinner) and $(document).on("ajaxStop", hideSpinner). Three parallel $.get() calls trigger ajaxStart once and ajaxStop once — not three times each.

📝 Syntax

The modern jQuery API for the ajaxStart global event:

1. Bind a handler — $(document).on("ajaxStart" [, handler]) (since 1.7)

jQuery
$( document ).on( "ajaxStart", handler )
  • handler — function invoked when the first global Ajax request begins: function() { ... } — no jqXHR or settings arguments.
  • Fires only when no other global requests are already in progress.
  • Must attach to document since jQuery 1.9.

2. Official demo — document handler + .load() on click

jQuery
$( document ).on( "ajaxStart", function() {
  $( ".log" ).text( "Triggered ajaxStart handler." );
} );

$( ".trigger" ).on( "click", function() {
  $( ".result" ).load( "ajax/test.html" );
} );

3. Official demo — show loading message

jQuery
$( document ).on( "ajaxStart", function() {
  $( "#loading" ).show();
} );

Pair with ajaxStop to hide the indicator when the last request completes.

4. Unbind — $(document).off("ajaxStart" [, handler])

jQuery
$( document ).off( "ajaxStart" );              // remove all ajaxStart handlers
$( document ).off( "ajaxStart", myHandler );   // remove one handler

5. Deprecated method — .ajaxStart(handler)

jQuery
// Deprecated — use .on("ajaxStart") instead
$( document ).ajaxStart( function() {
  $( "#loading" ).show();
} );

The old .ajaxStart(handler) binding method still works but is deprecated since jQuery 3.5. Migrate to $(document).on("ajaxStart", handler).

Return value

  • .on("ajaxStart", handler) returns the jQuery object (document wrapped) for chaining.
  • Handler return values are ignored by jQuery’s global Ajax event system.

⚡ Quick Reference

GoalCode
Bind global start handler$(document).on("ajaxStart", fn)
Handler signaturefunction() — no extra arguments
When it firesFirst global request begins (none already active)
Hide spinner when done$(document).on("ajaxStop", fn)
Per-request hook$(document).on("ajaxSend", fn)
Opt out of global events$.ajax({ url: "/x", global: false })
Remove handlers$(document).off("ajaxStart")

📋 ajaxStart vs ajaxSend vs ajaxStop

Three global events at different points in the lifecycle — choose the scope that matches your task.

ajaxStart
first only

Fires once when the first global request begins — show page-wide loading UI

ajaxSend
every call

Fires before each individual request is sent — receives jqXHR and settings

ajaxStop
last only

Fires once when the last active global request finishes — hide loading UI

ajaxComplete
every call

Fires after each request finishes — success or error — with jqXHR and settings

Global event order: ajaxStartajaxSendajaxSuccess | ajaxErrorajaxCompleteajaxStop. ajaxStart and ajaxStop bracket the batch; ajaxSend and ajaxComplete fire per request.

Examples Gallery

Examples 1 and 2 follow the official jQuery API documentation. Examples 3–5 extend those patterns with parallel requests, global: false, and an ajaxStart + ajaxStop loading pair. Use the Try-it links to run each snippet in the browser.

📚 Official Patterns

Document-level handlers that observe when global Ajax activity begins.

Example 1 — Official Demo: Document Handler + .load() on Click

Attach ajaxStart on document, then trigger an Ajax request with .load() when the user clicks .trigger.

jQuery
$( document ).on( "ajaxStart", function() {
  $( ".log" ).text( "Triggered ajaxStart handler." );
} );

$( ".trigger" ).on( "click", function() {
  $( ".result" ).load( "ajax/test.html" );
} );
Try It Yourself

How It Works

.load() uses $.ajax() internally, so it triggers global Ajax events. Because no other requests were active, ajaxStart fires once before the request is sent.

Example 2 — Official Demo: Show #loading on ajaxStart

The classic loading-indicator pattern from the jQuery API docs — show a message whenever Ajax activity begins.

jQuery
$( document ).on( "ajaxStart", function() {
  $( "#loading" ).show();
} );
Try It Yourself

How It Works

ajaxStart is designed for this use case — one handler shows UI when global activity starts. Without ajaxStop, the indicator would stay visible forever after the first batch completes.

Example 3 — Parallel Requests: ajaxStart Fires Once

Launch two $.get() calls at once — ajaxStart runs only for the first active global request, not twice.

jQuery
var startCount = 0;

$( document ).on( "ajaxStart", function() {
  startCount++;
  $( "#start-count" ).text( startCount );
} );

$( "#run-two" ).on( "click", function() {
  $.get( "https://jsonplaceholder.typicode.com/posts/1" );
  $.get( "https://jsonplaceholder.typicode.com/posts/2" );
} );
Try It Yourself

How It Works

jQuery tracks active global requests internally. The second parallel call sees one already in progress, so ajaxStart does not fire again. Use ajaxSend if you need a hook for every individual outgoing request.

📈 Opt-Out & ajaxStop Pairing

global: false and the complete loading-indicator pattern with ajaxStop.

Example 4 — global: false — Event Does Not Fire

Requests with global: false skip all global Ajax events, including ajaxStart.

jQuery
var startCount = 0;

$( document ).on( "ajaxStart", function() {
  startCount++;
  $( "#log" ).append( " ajaxStart (" + startCount + ")" );
} );

$( "#global-btn" ).on( "click", function() {
  $.get( "https://jsonplaceholder.typicode.com/posts/1" );
} );

$( "#private-btn" ).on( "click", function() {
  $.ajax( {
    url: "https://jsonplaceholder.typicode.com/posts/2",
    global: false
  } );
} );
Try It Yourself

How It Works

Setting global: false opts that request out of ajaxStart, ajaxSend, ajaxComplete, and ajaxStop. Use it for background polling or third-party widgets that should not trigger your page-wide loading UI.

Example 5 — Pair ajaxStart + ajaxStop for Loading UI

Show a spinner when global activity begins and hide it when the last request finishes — the canonical loading-indicator pattern.

jQuery
$( document ).on( "ajaxStart", function() {
  $( "#loading" ).show();
} );

$( document ).on( "ajaxStop", function() {
  $( "#loading" ).hide();
} );

$( "#run-two" ).on( "click", function() {
  $.get( "https://jsonplaceholder.typicode.com/posts/1" );
  $.get( "https://jsonplaceholder.typicode.com/posts/2" );
} );
Try It Yourself

How It Works

ajaxStart and ajaxStop are designed as a pair. You do not need to count requests — jQuery tracks active global calls and fires ajaxStop only when the count returns to zero.

🚀 Common Use Cases

  • Loading spinners — show a page-wide indicator when the first Ajax request begins; hide it on ajaxStop.
  • Disable navigation — grey out buttons or block form submission while any global Ajax activity is in progress.
  • Activity badges — flip a “Loading…” status flag once per batch instead of per request.
  • Analytics — record when a page-wide Ajax session started (pair with ajaxStop for duration).
  • Third-party isolation — set global: false on widget requests so they do not trigger your ajaxStart UI.
  • Testing — assert that a test harness entered the “loading” state exactly once per batch.

🧠 Global Ajax Event Order

1

ajaxStart

First active global request begins — show loading UI. Fires once per batch, not per request.

ajaxStart
2

ajaxSend

Before each individual request is sent — all registered handlers execute with jqXHR and settings.

ajaxSend
3

ajaxSuccess or ajaxError

Outcome-specific global event — success handler or error handler runs per request.

success | error
4

ajaxComplete

Always runs after step 3 for each request — finished, success or error.

ajaxComplete
5

ajaxStop

Last active global request finished — hide loading UI. Fires once when the batch completes.

📝 Notes

  • Bind with $(document).on("ajaxStart", handler) since jQuery 1.7 — not the deprecated .ajaxStart(handler) method.
  • Since jQuery 1.9, attach global Ajax handlers to document — not window.
  • Fires only when no other global requests are in progress — not for every individual call.
  • Handler receives no extra arguments — use ajaxSend for jqXHR and settings.
  • Always pair with ajaxStop when showing loading UI — otherwise the indicator never hides.
  • Requests with global: false do not trigger ajaxStart and do not count as active global requests.
  • Multiple parallel requests share one ajaxStart / ajaxStop pair.
  • For per-request logging, prefer ajaxSend over ajaxStart.

Browser Support

The ajaxStart event is a jQuery global Ajax event — not a native DOM event. It works wherever jQuery’s Ajax transport runs: all browsers supported by your jQuery version. Bind with .on("ajaxStart") since 1.7; attach handlers to document since 1.9.

jQuery 1.7+

jQuery ajaxStart event

Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. Requires jQuery Ajax — requests made with fetch() or axios do not trigger jQuery global events.

100% With jQuery Ajax
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
ajaxStart Universal

Bottom line: Safe in any jQuery project using $.ajax(), $.get(), $.post(), or .load(). Prefer .on('ajaxStart') over deprecated .ajaxStart().

Conclusion

The jQuery ajaxStart event is the global “first request beginning” hook — it runs once when the first qualifying Ajax call starts and no others are active. Bind handlers on document with .on("ajaxStart", fn), pair with ajaxStop for loading UI, and remember the handler receives no jqXHR or settings.

Use ajaxSend when you need per-request details before each call leaves. Use global: false to opt out. Review the jQuery .serializeArray() tutorial for per-field form data before requests fire. Continue with the .ajaxStart() method tutorial for the legacy shorthand API.

💡 Best Practices

✅ Do

  • Bind on $(document).on("ajaxStart", handler)
  • Pair with ajaxStop to hide loading UI when all requests finish
  • Use for page-wide spinners — not per-request logging
  • Use global: false for silent background or third-party requests
  • Remove handlers with $(document).off("ajaxStart") on SPA teardown

❌ Don’t

  • Attach global handlers to window — use document since jQuery 1.9
  • Use deprecated .ajaxStart(handler) in new code
  • Expect jqXHR or settings in the handler — use ajaxSend instead
  • Show loading UI without binding ajaxStop to hide it
  • Assume ajaxStart fires for every request — it fires once per batch

Key Takeaways

Knowledge Unlocked

Six things to remember about ajaxStart

First request, global batch, pair ajaxStop.

6
Core concepts
02

First only

Per batch

Timing
stop 03

ajaxStop

Hide UI

Pair
send 04

ajaxSend

Per request

Details
off 05

global:false

Opt out

Private
.on 06

.on()

Not .ajaxStart()

Modern

❓ Frequently Asked Questions

ajaxStart is a global Ajax event (AjaxEvent) that fires when the first qualifying jQuery Ajax request is about to be sent — but only when no other global Ajax requests are already in progress. Bind handlers with $(document).on('ajaxStart', handler) since version 1.7.
Since jQuery 1.9, all global Ajax event handlers — including ajaxStart — must be bound to document, not window or other elements. Use $(document).on('ajaxStart', fn) and $(document).off('ajaxStart', fn) to remove them.
ajaxStart fires once when the first active global request begins — before ajaxSend on that request. ajaxSend fires before every individual qualifying request is sent. For a single request: ajaxStart → ajaxSend → (response) → ajaxSuccess|ajaxError → ajaxComplete → ajaxStop.
No. ajaxStart fires only when no other global Ajax requests are in progress. If you launch three parallel $.ajax() calls, ajaxStart runs once at the beginning. Pair it with ajaxStop, which fires once when the last active global request finishes.
When $.ajax() or $.ajaxSetup() sets global: false, that request opts out of all global Ajax events. ajaxStart will not fire for it, and it does not count toward active global requests for ajaxStart/ajaxStop pairing.
The handler is a simple function with no jQuery-specific arguments — function() { ... }. Unlike ajaxSend or ajaxComplete, you do not receive jqXHR or settings. Use ajaxSend or ajaxComplete when you need per-request details.
Did you know?

jQuery maintains an internal counter of active global Ajax requests. ajaxStart increments the session when the counter goes from 0 to 1, and ajaxStop fires when it returns to 0. That is why three parallel $.get() calls produce one spinner show and one hide — not three of each. The deprecated .ajaxStart(fn) method is equivalent to .on("ajaxStart", fn) on document.

Next: .ajaxStart() Method

Learn the deprecated shorthand for binding global ajaxStart handlers on document.

.ajaxStart() method tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful