JavaScript Document afterscriptexecute Event

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Deprecated
Non-standard
Document event

What You’ll Learn

The Document afterscriptexecute event once fired after a static <script> finished running in Firefox. Learn what it meant, why dynamic scripts were excluded, how it differed from beforescriptexecute, and which portable APIs to use instead—with five examples and try-it labs.

01

Kind

Document event

02

Type

Event

03

Target scripts

Static only

04

Status

Deprecated · Non-standard

05

Engine

Legacy Gecko only

06

Modern path

script.onload

Introduction

Sometimes you want to know when a <script> has finished executing—for logging, analytics, or coordinating code that depends on that script. Early Gecko experiments added a pair of proprietary Document events: beforescriptexecute (before run) and afterscriptexecute (after run).

On Document, afterscriptexecute answered: did this static script just finish? It was never adopted by other browsers, never finished as a standard, and MDN warns not to rely on it.

⚠️
Deprecated & non-standard

Learn this event for legacy Firefox code and interviews. For new apps, use standard script lifecycle hooks (load / error on the script element) or ES modules instead of Gecko-only events.

Understanding afterscriptexecute

A Document event listened on document in supporting Gecko. Per MDN, it fired when a static <script> finished executing—not when you insert a script later with appendChild() or similar.

  • Fires after a static script has been executed (legacy Firefox).
  • Does not fire for scripts added dynamically (for example appendChild()).
  • Generic Event — no special payload properties; event.target is the script element.
  • Siblingbeforescriptexecute ran earlier and could cancel execution.
  • RelatedDocument.currentScript identifies the script currently running.
  • Status — Deprecated and Non-standard on MDN; not part of any specification.

🔎 Static vs Dynamic Scripts

This is the detail beginners miss. MDN’s Document page is explicit:

How the script appearsWould afterscriptexecute fire? (legacy Gecko)
Written in the HTML as <script>...</script> or <script src="...">Yes — static script finish
Created in JS and inserted with appendChild() / insertBefore()No — dynamic scripts skipped

That limitation is another reason not to build features on this event. Portable load / error listeners attach to the script element you create, whether it is static or dynamic.

📝 Syntax

Use the event name with addEventListener, or set the handler property (legacy Firefox only):

JavaScript
addEventListener("afterscriptexecute", (event) => { });

onafterscriptexecute = (event) => { };

Event type

A generic Event.

Typical listener (MDN style)

JavaScript
function finished(e) {
  console.log(`Finished script with ID: ${e.target.id}`);
}

document.addEventListener("afterscriptexecute", finished);
// or
document.onafterscriptexecute = finished;

⚖️ afterscriptexecute vs beforescriptexecute vs load

APIWhen it firesPortable?
beforescriptexecuteScript about to run (could cancel)No — legacy Gecko only
afterscriptexecuteStatic script just finished runningNo — legacy Gecko only
script loadExternal classic script finished loading/executingYes — use this
script errorScript failed to loadYes — use this
document.currentScriptPoints at the script currently executingYes — standard property

🚀 What to Use Instead

For an external classic script, attach standard listeners to the script element itself:

JavaScript
const script = document.createElement("script");
script.src = "/libs/helper.js";

script.addEventListener("load", () => {
  console.log("Script loaded and executed");
});

script.addEventListener("error", () => {
  console.error("Script failed to load");
});

document.head.appendChild(script);

For modules, use <script type="module"> and normal import / top-level await so dependencies are explicit. To watch scripts being inserted into the DOM, use MutationObserver—not proprietary execute events.

⚡ Quick Reference

GoalCode / note
Listen (legacy)document.addEventListener("afterscriptexecute", fn)
Handler propertydocument.onafterscriptexecute = fn
Static scriptsOnly those (legacy Gecko)
Dynamic scriptsDo not fire (MDN)
Event typeGeneric Event
Feature-detect"onafterscriptexecute" in document (weak; still prefer alternatives)
Modern replacescript.addEventListener("load", fn)
MDN statusDeprecated · Non-standard

🔍 At a Glance

Four facts to remember about Document afterscriptexecute.

Event type
Event

Generic

Scripts
static

Not dynamic

Standard?
no

Non-standard

New code?
avoid

Use script load

Examples Gallery

Examples follow MDN Document: afterscriptexecute event and show safe feature detection plus modern replacements. In most current browsers the proprietary event will never fire—the labs still teach the patterns clearly.

📚 Getting Started

Register handlers the MDN ways (legacy Gecko).

Example 1 — addEventListener("afterscriptexecute")

MDN style: listen on document and log the finished script’s id (where supported).

JavaScript
function finished(e) {
  console.log(`Finished script with ID: ${e.target.id}`);
}

document.addEventListener("afterscriptexecute", finished);

// In legacy Firefox, a static <script id="demo"> could fire this after it ran.
// In modern browsers it typically never fires.
Try It Yourself

How It Works

You register the same way as any other DOM event. Support is the hard part: without legacy Gecko behavior, the handler sits idle. When it did fire, event.target was the <script> element that finished.

Example 2 — onafterscriptexecute Property

MDN’s alternate style using the event handler property on document.

JavaScript
document.onafterscriptexecute = (event) => {
  console.log("Script finished (onafterscriptexecute)");
  console.log("target id:", event.target && event.target.id);
};

// Assigning again replaces the previous handler.
// Prefer addEventListener when you need multiple listeners.
Try It Yourself

How It Works

Same event, different registration API. One property means one handler—easy to overwrite by accident.

📈 Detect, Limits & Replace

Feature-detect safely, remember the static-only rule, and migrate.

Example 3 — Feature Detection

Never assume the event exists. Check before you depend on it.

JavaScript
const supported = "onafterscriptexecute" in document;

console.log("onafterscriptexecute in document:", supported);

if (supported) {
  document.addEventListener("afterscriptexecute", () => {
    console.log("Legacy path: afterscriptexecute");
  });
} else {
  console.log("Use script load/error events instead");
}
Try It Yourself

How It Works

Presence of the handler property is a rough signal. Even when the property exists, modern engines may not dispatch the event—so still prefer portable APIs.

Example 4 — Static vs Dynamic (MDN Rule)

Document the MDN rule in code comments: dynamic appendChild() scripts would not trigger afterscriptexecute even in old Firefox.

JavaScript
document.addEventListener("afterscriptexecute", (e) => {
  console.log("afterscriptexecute for:", e.target && e.target.id);
});

// Dynamic insert — MDN: afterscriptexecute does NOT fire for this path
const dynamic = document.createElement("script");
dynamic.id = "dynamic-demo";
dynamic.textContent = "console.log('dynamic script ran');";
document.body.appendChild(dynamic);

console.log("Dynamic script appended");
console.log("MDN: afterscriptexecute skips dynamically added scripts");
console.log("Prefer script load/error or modules instead");
Try It Yourself

How It Works

The injected script still runs immediately when appended. The proprietary Document event simply was not designed to announce dynamic inserts—another reason load / error (or modules) are better teaching targets.

Example 5 — Modern Replacement with load

Portable pattern: listen on the script element you create (works for dynamic scripts too).

JavaScript
const script = document.createElement("script");
script.textContent = "window.__demoRan = true;";

script.addEventListener("load", () => {
  // Note: inline scripts may not fire load the same way as external ones.
  console.log("load fired (external scripts are the usual case)");
});

// External example pattern:
// script.src = "https://example.com/lib.js";
// script.addEventListener("load", () => console.log("executed"));
// script.addEventListener("error", () => console.error("failed"));
// document.head.appendChild(script);

console.log("Prefer load/error over afterscriptexecute");
console.log("demo flag set via inline script:", typeof window.__demoRan !== "undefined");
document.body.appendChild(script);
console.log("after append, __demoRan:", window.__demoRan === true);
Try It Yourself

How It Works

Inline scripts run as soon as they are inserted. External scripts expose a reliable load event when fetch + execute succeed. That is the cross-browser replacement for proprietary after-execute notifications.

🚀 Common Use Cases

  • Understanding legacy Firefox / Gecko code that monitored static script execution.
  • Migrating old extensions or pages off proprietary script-execute events.
  • Interview / history knowledge of early HTML script lifecycle proposals.
  • Teaching why static-vs-dynamic limits and standards matter for DOM events.
  • Choosing load / error, currentScript, or ES modules for real production work.

🔧 How It Works

1

Static script is ready

A <script> already in the markup is about to run.

Prepare
2

Script executes

JavaScript runs to completion (or throws).

Run
3

afterscriptexecute (legacy)

Old Gecko dispatched a Document Event; dynamic inserts skipped.

Notify
4

Prefer standard load hooks

Use load / error or modules in new code.

📝 Notes

  • MDN: Deprecated and Non-standard — avoid in production.
  • Applies to static scripts only; dynamic appendChild() scripts do not fire it.
  • Proprietary to Gecko; never a cross-browser API; not part of any specification.
  • Modern Firefox stopped shipping useful web-facing support for these events.
  • Related learning: currentScript, scripts, addEventListener(), JavaScript hub.

Very Limited / Legacy Browser Support

afterscriptexecute is a deprecated, non-standard Gecko Document event. Logos use the shared browser-image-sprite.png sprite from this project. Other engines never implemented it; modern Firefox no longer dispatches it to web content. Prefer script load/error events.

Deprecated · Non-standard

Document afterscriptexecute

Do not build features on this event. Use it only to understand or migrate legacy Firefox code.

Legacy Not for new apps
Google Chrome Never implemented
Unavailable
Mozilla Firefox Legacy only · removed / disabled in modern versions
Avoid
Apple Safari Never implemented
Unavailable
Microsoft Edge Never implemented (Chromium)
Unavailable
Opera Never implemented (Chromium)
Unavailable
Internet Explorer No afterscriptexecute support
Unavailable
afterscriptexecute Deprecated

Bottom line: Feature-detect if you must touch legacy Gecko code. For new work, use script load/error events or ES modules. Remember: even historically, dynamically appended scripts did not fire this Document event.

Conclusion

Document afterscriptexecute once told Firefox pages that a static script had finished running. Today it is a deprecated, non-standard footnote: useful for reading old code, not for shipping new products.

Continue with beforescriptexecute, currentScript, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Prefer script load / error for external scripts
  • Use ES modules when dependency order matters
  • Feature-detect before touching legacy Gecko-only APIs
  • Remember the static-only MDN rule when reading old code
  • Plan migration off proprietary script-execute events

❌ Don’t

  • Build new features on afterscriptexecute
  • Assume Chrome, Safari, or Edge ever supported it
  • Expect it to fire for appendChild()-inserted scripts
  • Confuse it with the standard load event
  • Treat non-standard Gecko events as future-proof

Key Takeaways

Knowledge Unlocked

Five things to remember about Document afterscriptexecute

Legacy Gecko “static script finished” signal — prefer standard load hooks now.

5
Core concepts
⚠️ 02

Deprecated

avoid new use

Status
🚫 03

Non-standard

Gecko only

Compat
🚫 04

Not dynamic

appendChild skips

MDN rule
🚀 05

Replace

script load

Modern

❓ Frequently Asked Questions

It is a proprietary Gecko (Firefox) Document event that fired after a static <script> element finished executing. MDN marks it Deprecated and Non-standard. It was never a finished web standard.
No. Per MDN, it does not fire when a script element is added dynamically (for example with appendChild()). It only applied to static scripts already in the document markup in supporting legacy Firefox.
No. Prefer portable APIs such as script.onload / script.onerror for classic scripts, the load event on the script element, module scripts with type="module", or MutationObserver when you need to watch scripts being inserted.
Historically only Firefox (Gecko). Other major browsers never shipped it. Modern Firefox stopped dispatching it to web content and later removed the implementation.
In supporting legacy Firefox: document.addEventListener("afterscriptexecute", handler) or document.onafterscriptexecute = handler. Always feature-detect; do not assume the event exists.
A generic Event. There is no special payload beyond a normal Event object. Related learning: Document.currentScript and the sibling beforescriptexecute event.
Did you know?

Mozilla later unshipped beforescriptexecute and afterscriptexecute from web content because they were non-standard and unused by other browsers. Script blockers that once relied on them moved to portable techniques such as changing a script’s type via MutationObserver.

Next: Document beforescriptexecute

Learn the sibling event that fired before a static script ran (and could cancel it).

beforescriptexecute →

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.

5 people found this page helpful