Skip to content

Commit 5828bd2

Browse files
committed
Fix ready() to work even when HTMX is loaded async
1 parent 448db78 commit 5828bd2

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

src/htmx.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5056,25 +5056,31 @@ var htmx = (function() {
50565056
//= ===================================================================
50575057
// Initialization
50585058
//= ===================================================================
5059-
var isReady = false
5060-
getDocument().addEventListener('DOMContentLoaded', function() {
5061-
isReady = true
5062-
})
5063-
50645059
/**
5065-
* Execute a function now if DOMContentLoaded has fired, otherwise listen for it.
5060+
* Execute a function once the DOM has loaded.
5061+
*
5062+
* If the DOM is still loading, the function will be run as a listener for
5063+
* the DOMContentLoaded event. Otherwise, the function will be synchronously
5064+
* executed now.
5065+
*
5066+
* This is tricky to get right since the DOMContentLoaded event only fires
5067+
* ones. We need to ensure we always wait for it if the DOM is still loading,
5068+
* but that we never wait for it if it's already been fired.
50665069
*
5067-
* This function uses isReady because there is no reliable way to ask the browser whether
5068-
* the DOMContentLoaded event has already been fired; there's a gap between DOMContentLoaded
5069-
* firing and readystate=complete.
5070+
* This is extra tricky if HTMX was loaded using a script tag with the async
5071+
* attribute (and no defer attribute). In that case the script will execute as
5072+
* soon as it has been loaded from the network, regardless of the value
5073+
* of readyState or whether DOMContentLoaded has been fired or not. In
5074+
* paricular, there is a gap of time where DOMContentLoaded has been fired,
5075+
* but readyState is not "complete".
50705076
*/
50715077
function ready(fn) {
5072-
// Checking readyState here is a failsafe in case the htmx script tag entered the DOM by
5073-
// some means other than the initial page load.
5074-
if (isReady || getDocument().readyState === 'complete') {
5075-
fn()
5078+
if (getDocument().readyState === "loading") {
5079+
// Loading hasn't finished yet
5080+
getDocument().addEventListener("DOMContentLoaded", fn);
50765081
} else {
5077-
getDocument().addEventListener('DOMContentLoaded', fn)
5082+
// `DOMContentLoaded` has already fired
5083+
fn();
50785084
}
50795085
}
50805086

0 commit comments

Comments
 (0)