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
Fundamentals
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.
Concept
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.
Sibling — beforescriptexecute ran earlier and could cancel execution.
Status — Deprecated and Non-standard on MDN; not part of any specification.
Important Rule
🔎 Static vs Dynamic Scripts
This is the detail beginners miss. MDN’s Document page is explicit:
How the script appears
Would 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.
Foundation
📝 Syntax
Use the event name with addEventListener, or set the handler property (legacy Firefox only):
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.
"onafterscriptexecute" in document (weak; still prefer alternatives)
Modern replace
script.addEventListener("load", fn)
MDN status
Deprecated · Non-standard
Snapshot
🔍 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
Hands-On
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.
Listener attached (event may never fire in modern browsers)
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.
onafterscriptexecute in document: false
Use script load/error events instead
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");
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);
Prefer load/error over afterscriptexecute
demo flag set via inline script: false
after append, __demoRan: true
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.
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 scriptload/error events.
✓ Deprecated · Non-standard
Document afterscriptexecute
Do not build features on this event. Use it only to understand or migrate legacy Firefox code.
LegacyNot for new apps
Google ChromeNever implemented
Unavailable
Mozilla FirefoxLegacy only · removed / disabled in modern versions
Avoid
Apple SafariNever implemented
Unavailable
Microsoft EdgeNever implemented (Chromium)
Unavailable
OperaNever implemented (Chromium)
Unavailable
Internet ExplorerNo afterscriptexecute support
Unavailable
afterscriptexecuteDeprecated
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.
Wrap Up
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.
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
Summary
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
📄01
After static script
legacy notify
Event
⚠️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.