Usually we put our JavaScript <script>
tags at the bottom of an HTML document, right before the closing </body>
tag, with the benefit that they are executed after all the elements are already available in the DOM and some more things.
However, I'm using a frame document1 which does have a <frameset>
instead of a <body>
tag. I don't want to put them in the <head>
of the document because they wouldn't have immediate access the DOM elements below3. And I don't want to use <iframe>
s in a standard body tag either4. I've tried
<head>
<title>Framesets are interesting</title>
</head>
<frameset cols="50%,50%">
<frame id="frame-a" src="a.html">
<frame id="frame-b" src="b.html">
<script type="text/javascript">
console.log("hello world!");
console.log(document.getElementById("frame-a")); // this is what I'm after
</script>
</frameset>
However, the script was not executed at all, it didn't even show up in the DOM inspector. Sure, a <frameset>
may only contain <frame>
and <noframes>
tags. But, is there really no way to get scripts execute after a <frame>
tag?
Just for reference, placing them after </frameset>
like it's sometimes done with <body>
s doesn't work either.
1: Yes, I know they're deprecated. They were just the natural choice2 for my project, a neat side-by-side view that shows two documents and scrolls them together in a sophisticated manner.
2: …and I never used them before, so I wanted to give it a try.
3: That is what I ended up with, after all an onload handler is trivial. Still the question remains, I'm curious.
4: works fine, but requires intricate CSS styling
A <script>
element can only appear in either a <head>
element or <body>
element. It cannot appear as a child of a <frameset>
element; a <frameset>
can only contain <frame>
elements, <noframes>
elements, or other <frameset>
elements. See the Transitional DTD:
<!ELEMENT FRAMESET - - ((FRAMESET|FRAME)+ & NOFRAMES?) -- window subdivision-->
Normally, browsers are happy to insert elements into other elements where they don't belong in complete defiance of what the DTD says since the DTD is just a rulebook, but this doesn't always happen (for example, you can never put any other flow element into an HTMLParagraphElement no matter how hard you try), so if a browser is refusing to place an HTMLScriptElement in an HTMLFrameSetElement, chances are this is why.
Any workarounds will involve placing a <script>
element in either the frameset's <head>
element, or within one of the frames. (You can also place a <script>
element within a <noframes>
element since <noframes>
has the same content model as <body>
, but this won't solve your problem for obvious reasons.)