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
Fundamentals
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.
Concept
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.
Foundation
📝 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
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.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Bind global start handler
$(document).on("ajaxStart", fn)
Handler signature
function() — no extra arguments
When it fires
First 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")
Compare
📋 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: ajaxStart → ajaxSend → ajaxSuccess | ajaxError → ajaxComplete → ajaxStop. ajaxStart and ajaxStop bracket the batch; ajaxSend and ajaxComplete fire per request.
Hands-On
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.
User clicks .trigger → ajaxStart fires → .log shows "Triggered ajaxStart handler."
Then .load() sends the HTTP request and loads HTML into .result
Works for $.ajax(), $.get(), $.post(), and .load()
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.
First Ajax request begins → #loading becomes visible
Pair with ajaxStop to hide when all requests finish
Ideal for a page-wide spinner or "Loading..." banner
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.
Click #run-two → two parallel $.get() calls
startCount increments by 1 (not 2)
ajaxSend would fire twice — ajaxStart fires once per batch
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.
Click #global-btn → ajaxStart fires → log updated
Click #private-btn → request runs but ajaxStart does NOT fire
Private requests do not count toward active global batch
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.
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.
Applications
🚀 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.
Important
📝 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.
Compatibility
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 ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
ajaxStartUniversal
Bottom line: Safe in any jQuery project using $.ajax(), $.get(), $.post(), or .load(). Prefer .on('ajaxStart') over deprecated .ajaxStart().
Wrap Up
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.
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
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about ajaxStart
First request, global batch, pair ajaxStop.
6
Core concepts
doc01
document
Bind here
Global
1×02
First only
Per batch
Timing
stop03
ajaxStop
Hide UI
Pair
send04
ajaxSend
Per request
Details
off05
global:false
Opt out
Private
.on06
.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.