jQuery ajaxComplete Event

Beginner
8 min read
Updated: Oct 2026
5 examples
Live preview

What Is ajaxComplete?

ajaxComplete is a global AjaxEvent (since jQuery 1.0; .on() binding since 1.7). jQuery triggers it on document whenever any qualifying Ajax request finishes — success or error. All registered handlers run.

Remember
$(document).on("ajaxComplete", function (event, jqXHR, ajaxOptions) {
  // runs after every qualifying Ajax request finishes
});

// Order (per request):
// ajaxSuccess | ajaxError  →  ajaxComplete  →  (ajaxStop when idle)

// Opt out for one call:
$.ajax({ url: "/x", global: false });
NeedUse
Global “always finished”$(document).on("ajaxComplete", fn)
Success onlyajaxSuccess
Error onlyajaxError
One request only$.ajax(...).always(fn)
Hide loading when idleajaxStop

How to Use ajaxComplete

Bind once on document, then any jQuery Ajax call can notify that handler.

  1. Attach the handler to document with .on("ajaxComplete", handler).
  2. Make requests with $.ajax(), $.get(), $.post(), or .load().
  3. Optionally filter with ajaxOptions.url (or other settings).
  4. Read the body via jqXHR.responseText when needed.
  5. Use global: false on requests that must stay silent.
PieceRequired?Role
documentYes (1.9+)Only valid bind target for global Ajax events
handlerYesfunction(event, jqXHR, ajaxOptions)
ajaxOptions.urlOptionalFilter which requests you react to
global: falseOptionalSkip all global Ajax events for that call

Pseudocode

Pseudocode
bind ajaxComplete on document with handler(event, jqXHR, ajaxOptions)

when a jQuery Ajax request finishes:
    if request.global === false:
        do not fire ajaxComplete
        return

    if request succeeded:
        fire ajaxSuccess first
    else:
        fire ajaxError first

    fire ajaxComplete
        for each registered handler:
            call handler(event, jqXHR, ajaxOptions)

    if no other global Ajax requests are active:
        fire ajaxStop

Cheat Sheet

Keep these facts handy while wiring global Ajax cleanup.

TopicDetail
Bind$(document).on("ajaxComplete", handler)
Unbind$(document).off("ajaxComplete" [, handler])
Signaturefunction(event, jqXHR, ajaxOptions)
WhenEvery finished request (success + error)
SinceEvent 1.0 · .on() form 1.7 · document-only 1.9+
Response bodyjqXHR.responseText
Filterif (ajaxOptions.url === "...")
Opt outglobal: false in $.ajax() / $.ajaxSetup()

Live Preview

Run a real $.get() and watch the global ajaxComplete handler update the log.

Live demo uses a public JSON API. Needs network access.

Result
Ready — pick an action and click Run.

jQuery Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Document Handler + .load()

Official pattern: log a message when any Ajax request completes after a click.

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

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

How It Works

  1. Bind. .on("ajaxComplete") on document listens globally.
  2. Click. .load() starts an Ajax request under the hood.
  3. Complete. When the request finishes, every ajaxComplete handler runs.
  4. Update. The log text confirms the global event fired.

Example 2 — Filter by settings.url

Handlers run for every request — narrow them with the settings object.

jQuery
$(document).on("ajaxComplete", function (event, xhr, settings) {
  if (settings.url === "ajax/test.html") {
    $(".log").text(
      "Triggered ajaxComplete handler. The result is " +
      xhr.responseText
    );
  }
});
Try It Yourself

How It Works

  1. Args. jQuery passes event, xhr, and settings.
  2. Compare. Check settings.url against the endpoint you care about.
  3. Read. Use xhr.responseText for the raw response body.
  4. Skip. Non-matching URLs leave your UI alone.

Example 3 — Append “Request Complete.”

Official demo: append a short status string for every finished request.

jQuery
$(document).on("ajaxComplete", function (event, request, settings) {
  $("#msg").append(" Request Complete. ");
});
Try It Yourself

How It Works

  1. Global. One handler covers every qualifying Ajax call.
  2. Append. Each completion adds another status fragment.
  3. Count. Parallel requests each fire their own ajaxComplete.
  4. Use. Handy for a simple activity strip or debug log.

Example 4 — Opt Out with global: false

Private requests skip all global Ajax events, including ajaxComplete.

jQuery
$(document).on("ajaxComplete", function () {
  $("#log").append(" ajaxComplete");
});

// Fires ajaxComplete
$.get("/api/public");

// Does NOT fire ajaxComplete
$.ajax({ url: "/api/silent", global: false });
Try It Yourself

How It Works

  1. Default. Ajax calls participate in global events.
  2. Opt out. global: false skips ajaxComplete (and the other globals).
  3. Local still works. .done() / .fail() / .always() still run.
  4. When. Use for silent prefetch, polling, or third-party widgets.

Example 5 — ajaxComplete vs .always()

Global event sees every request; .always() is tied to one call.

jQuery
var globalCount = 0;
var alwaysCount = 0;

$(document).on("ajaxComplete", function () {
  globalCount++;
});

$.ajax("/a").always(function () { alwaysCount++; });
$.ajax("/b").always(function () { alwaysCount++; });

// After both finish:
// globalCount === 2, alwaysCount === 2
// but each .always() only saw its own request
Try It Yourself

How It Works

  1. Global. One ajaxComplete handler counts every finished request.
  2. Local. Each .always() only increments for its own jqXHR.
  3. Same totals. Counts can match, but the scope is different.
  4. Choose. Site-wide UI → global event; one call’s cleanup → .always().

Edge Cases & Pitfalls

Check these before relying on global Ajax handlers in production.

target

Bind on document only (1.9+)

Handlers on window or other elements will not receive global Ajax events.

scope

Not success-only

ajaxComplete runs after failures too. Use ajaxSuccess / ajaxError or check status when outcome matters.

global

global: false stays silent

Those requests never trigger ajaxComplete. Per-request callbacks still work.

cost

Heavy work in every handler hurts

Parsing large responseText or updating lots of DOM on every request can slow busy pages — filter first.

Browser Support

ajaxComplete has been part of jQuery since 1.0. Prefer $(document).on("ajaxComplete", …) (1.7+). Since 1.9, handlers must attach to document.

✓ Stable · jQuery 1.0+

jQuery ajaxComplete

Works in every browser that runs your loaded jQuery version. Prefer a current jQuery 3.x build for modern projects.

100% jQuery Ajax event
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
ajaxComplete Universal

Bottom line: Safe for everyday apps. Bind on document, filter by URL when needed, and use global: false for silent background calls.

Performance Notes

ApproachCostBest for
One filtered ajaxCompleteCheapSite-wide loading / logging
Per-request .always()CheapCleanup for a single call
Heavy DOM work every completeExpensiveAvoid — filter or debounce

Global handlers are fine when they stay light. Filter by URL before touching the DOM, and prefer .always() for request-specific work.

Key Takeaways

  • Role: global “request finished” hook — success or error.
  • Bind: $(document).on("ajaxComplete", fn) — document only since 1.9.
  • Filter: inspect ajaxOptions.url; read body via jqXHR.responseText.
  • Local alternative: use .always() for one-request cleanup.

One line: ajaxComplete is jQuery’s global always-runs-at-the-end Ajax event — bind it on document.

Frequently Asked Questions

ajaxComplete is a global AjaxEvent that fires whenever any qualifying jQuery Ajax request finishes — success or failure. Bind it with $(document).on("ajaxComplete", handler) (since 1.7). Every registered handler runs for every completed request.
Since jQuery 1.9, all global Ajax event handlers must be bound to document — not window or other elements. Use $(document).on("ajaxComplete", fn) and remove with $(document).off("ajaxComplete", fn).
Yes. It always runs after a request completes. On success it follows ajaxSuccess; on failure it follows ajaxError. Use those outcome-specific events when you only care about one result.
ajaxComplete is a global document event — one handler observes every qualifying request on the page. always() is per-request on the jqXHR from $.ajax() — it runs only for that call. Use global events for site-wide UI; use always() for request-specific cleanup.
When $.ajax() or $.ajaxSetup() sets global: false, that request opts out of all global Ajax events. ajaxComplete will not fire for it. Per-request done(), fail(), and always() still run.
Three: function(event, jqXHR, ajaxOptions). event is the jQuery event; jqXHR is the request object (read responseText); ajaxOptions is the settings used to create the request (filter with ajaxOptions.url).
The shorthand method .ajaxComplete(handler) is deprecated as of jQuery 3.5. Prefer $(document).on("ajaxComplete", handler) — the event API this page teaches.

Next: .ajaxComplete() method

See the deprecated shorthand and how to migrate to .on("ajaxComplete").

.ajaxComplete() 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.

9 people found this page helpful