Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put a <script> in the "body" of a frameset document?

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

like image 568
Bergi Avatar asked Mar 17 '16 01:03

Bergi


People also ask

Can you put the script element inside the body?

JavaScript in body or head: Scripts can be placed inside the body or the head section of an HTML page or inside both head and body.

Should scripts be inside or outside body?

Always end with a body tag and make sure every single JavaScript part is within the body tag. You can also have links or scripts inside head tags, but it is not recommended unless you are really certain your JavaScript code is too big to have it inline.

Can I put script tag after body tag?

The script tag should either be included between the <head> tags or just before the closing <body> tag in your HTML document. JavaScript is often placed before the closing body tag to help reduce the page loading time.


2 Answers

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.)

like image 199
BoltClock Avatar answered Sep 17 '22 13:09

BoltClock


Similar problem was solved here: Dynamically set frame src using javascript

<head>
  <title>Framesets are interesting</title>
  <script type="text/javascript">
  function LoadPage(){
    console.log("hello world!");
    console.log(document.getElementById("frame-a")); // this is what I'm after
  }
  </script>
</head>
<frameset cols="50%,50%" onload="LoadPage();">    
  <frame id="frame-a" src="a.html">
  <frame id="frame-b" src="b.html">
</frameset>
like image 37
dev_masta Avatar answered Sep 18 '22 13:09

dev_masta