Search code examples
javascripthtmliframe

How can I assign an iframe to the innerHTML of a div element


I'm trying to assign an iframe to innerHTML of a div element, but I can't figure out how to get it to render. Here's some relevant snippets

function showText(debugElement, message) {
    if(debugElement != null) {
        debugElement.innerHTML = message;
    }
}

function escapeHtml(html){
    var text = document.createTextNode(html);
    var p = document.createElement('p');
    p.appendChild(text);
    return p.innerHTML;
}

function getDebugText(request) {
    var responseText = "";
    try {
        var responseJSON = JSON.parse(request.response);
        for (const [key, val] of Object.entries(responseJSON)) {
            responseText += `  ${key}: ${val}\n`;
        }
    } catch(error) {
        if(request.responseText.startsWith('<!doctype html>')) {
            responseText = `<div>${request.statusText}</div><iframe scrolling="yes" style="width: 100%;" srcdoc="${escapeHtml(request.responseText)}"></iframe>`
        } else {
            responseText = escapeHtml(`${request.statusText}\n${request.responseText}`);
        }
    }

    console.log(responseText)
    return responseText;
}

suffice it to say, somewhere there's something along the lines of

showText(document.getElementByID('details'), getDebugText(response))

I can see a frame rendered, but it doesn't show any content. I've seen other answers that do something along the lines of document.appendChild(iframe), but I can't figure out how to do this with a named div.


Solution

  • Your problem probably lies here:

    <iframe scrolling="yes" style="width: 100%;" srcdoc="${escapeHtml(request.responseText)}"></iframe>

    Try creating this element through javascript, then you can assign your srcdoc attribute through the iframe element object (you won't even need to escape request.responseText as javascript will do it for you...

    Then you attach it to the debugElement inside your showText function.

    Note that not all browsers support the srcdoc attribute...

    const MyFrame = document.createElement('iframe');
    
    MyFrame.srcdoc = "<b>TESTING ESCAPABLE CHARACTERS:" +
    '"' + "'" + '\\' + '<' + '>' + '</b>';
    
    // This will work... But will keep adding frames instead of replacing...
    // MyFrameContext.appendChild(MyFrame);
    
    // This will just replace anything that was there with your iFrame.
    MyFrameContext.replaceChildren(MyFrame);
    <div id='MyFrameContext'>
      <!-- Here goes your dynamic iFrame -->
    </div>

    This works just fine for me.