Alex Shul
Alex Shul

Reputation: 500

Javascript: Incomprehensible behavior when acessing iframe content

I have following html code:

<pre id="js-code"><iframe src="sass/main.sass.html" frameborder="0" id="c-frame"></iframe></pre>

... and js:

document.addEventListener('DOMContentLoaded', function(){

  var code = window.frames[0].document.body.innerHTML;
  alert(window.frames[0].document.body.innerHTML);

  alert(document.getElementById("c-frame").contentDocument.body.innerHTML);
  alert(document.getElementById("c-frame").contentDocument.body.innerHTML.indexOf('\n'));
  document.getElementById("c-frame").contentDocument.body.innerHTML = document.getElementById("c-frame").contentDocument.body.innerHTML.replace(/\n/g, '<br>');


});

I want to get iframe content and replace '\n' with <br>. But i see incomprehensible behavior when run this:
- (Chrome, Opera, Firefox) content shown on html page.
- (Chrome, Opera) alert 1: ''; alert 2: ''; alert 3: '-1'; replacing not work;
- (Firefox 64.0) alert 1: ''; alert 2: ''; alert 3: '28'; replacing work;
Note: in Firefox running this code:

  document.addEventListener('DOMContentLoaded', function(){

  alert(document.getElementById("c-frame").contentDocument.body.innerHTML.indexOf('\n'));
  document.getElementById("c-frame").contentDocument.body.innerHTML = document.getElementById("c-frame").contentDocument.body.innerHTML.replace(/\n/g, '<br>');


});

caused alert with result '-1', but replacing worked.

This code tested as local file run in browser, with browser sync and on remote server - results was similar.

Upvotes: 0

Views: 55

Answers (2)

Alex Shul
Alex Shul

Reputation: 500

I found alternative way to load files what i need using ajax and without iframe. Maybe for someone it can be useful. This way replacement '\n' with '<br>' not needed - content displayed correctly. HTML code:

<pre id="js-code"></pre>

JS code:

function loadFile(file) {

  var xhttp = new XMLHttpRequest();

  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {

      var codeHolder = document.getElementById("js-code");          
      codeHolder.innerHTML = this.responseText;          
    }        
  };

  xhttp.open("GET", file, true);
  xhttp.send();
}

document.addEventListener('DOMContentLoaded', function(){
   loadFile("sass/main.sass.html");
});

Upvotes: 0

Barmar
Barmar

Reputation: 781907

The DOMContentLoaded event in the main page fires before the iframes are loaded. You should use the iframe's DOMContentLoaded event.

document.addEventListener('DOMContentLoaded', function(){
    var iframe = document.getElementById("c-frame").contentDocument;
    iframe.addEventListener('DOMContentLoaded', function() {
        this.body.innerHTML = this.body.innerHTML.replace(/\n/g, "<br>");
    });
});

However, I wonder about this replacement operation. This is going to add a <br> whenever the content has newlines between HTML elements, not just in their text. Some of these are likely to be in invalid places, e.g.

<table>
<tr>
<td>Cell contents</td>
</tr>
</table>

will become:

<table><br><tr><br><td>Cell contents</td><br></tr><br></table>

And if you have any HTML elements that are split across lines, it will put <br> inside:

<input type="text"
       name="foo">

will become

<input type="text" <br> name="foo">

Upvotes: 1

Related Questions