Ever wonder about the hidden <div>
with id mktoStyleLoaded
that gets injected by the Forms 2.0 library? Y’know, this one:
It serves a simple but (previously) undocumented purpose, and you wouldn’t be reading this if you didn’t hunger to know every little thing about Marketo Forms, right?
The mktoStyleLoaded
element helps the library know when both remote stylesheets — one sheet with the core form styles + one sheet for whichever theme you select in Form Editor — have been loaded from Marketo.
While waiting for the styles, the library hides the form for up to 1500 milliseconds (1.5 seconds), checking roughly every 25ms. But even if the timeout elapses, the form is still shown — it just may not have all styles applied.
In case of a timeout, this Console message is logged:
But again, the form is shown regardless.
How it works in (pretty shallow) depth
As seen in the screenshot above, the mktoStyleLoaded
element has a couple of inline styles:
-
display: none
to hide thediv
permanently -
border-top-color
set to #123456 — a very dark blue, but the color itself is completely arbitrary, it’s just an easy-to-remember hex color that’s never visible
Each of the remote stylesheets has a rule targeting the same element.
In forms2.css:
#mktoStyleLoaded {
background-color: #123456;
}
In forms2-theme-simple.css or your Form Editor theme:
#mktoStyleLoaded {
color: #123456;
}
The library repeatedly compares the border, background, and text (foreground) colors to see if all 3 match.
Weird! Is that kind of thing necessary?
Yep. When you inject a remote <link rel="stylesheet">
, the file is loaded and parsed asynchronously, at the browser’s and network’s discretion. The Link itself doesn’t fire an event like “Loaded” or “StylesReady” or “StyleSheetActivated.”
But you can check when certain “magic styles” have been applied — and thus by implication know when the remote ’sheet has been loaded and parsed.
Of course, you don’t have direct proof that a specific stylesheet was responsible for the applied styles. But you try to make them unique enough that only a deliberate attempt to tamper with the logic would mess it up.
Could it have been done another way?
Actually yes. There’s another way to wait for a remote Link to load, and that’s adding a capturing event listener for the load
event on document
. (This may ring a bell if you’ve been reading my blog for awhile.)
In all modern browsers (including IE 11) a load
event is fired with the remote <link>
as the target
. This only happens after it’s downloaded and parsed.
So you’d set a 1500-millisecond “continue anyway” timeout, then cancel that timeout when that event comes in. It’s a tiny bit more efficient, since you don’t waste any cycles on polling, and I hate polling from a pure design standpoint. But with such a short polling time it’s a wash.