[Fixed] Dynamically add script tag and execute $(document).ready, without using iframe or document.write

Issue

I have a string which comes from api response. Now i want to integrate this script and style tag in my application and execute script.

  const styleScriptText = '<style type="text/css">#checkoutmodal .checkoutmodal-box{background:#FFF !important}</style><script src="https://someurl/lib/jquery.min.js" type="text/javascript"></script><script type="text/javascript">$(document).ready(function() { console.log("test")});</script>'

I tried to load it using iframe and i could achieve expected result

  const iframe = document.createElement('iframe');

   const html = `<body>${styleScriptText}</body>`;
   iframe.srcdoc = html;
 
   iframe.style.width = "47%";
   iframe.style.left = "25%";
   iframe.style.height = "100vh";
   iframe.style.position = "relative";
   document.getElementById("parentId").appendChild(iframe);

But i don’t want to use iframe as it has future constraints i have to redirect to bank page and when it comes back whole application is iframed which i don’t want

Next i tried it using document.write as below

  const html = `<html>
        <head>
      
        </head>
          <body>
          ${styleScriptText}
         
          </body>
    </html>`;
document.open("text/html", "replace");
document.write(html);
document.close();

But problem with above approach is i am getting below error
A parser-blocking, cross site (i.e. different eTLD+1) script, https:externalscript.js, is invoked via document.write

If i take any other approch $(document).ready function in script doesnot execute.
Tried almost everything but not able to figure out how can i load and run script coming from api response.
Goal here is i need to take a script coming as string and load it in html and execute every script files

Solution

this should work, use it at your own risk:

const styleScriptText =
  '<style type="text/css">body {background: #000}</style><script type="text/javascript">alert("OK")</' + 'script' + '>';

const insertStyleScriptText = () => {
    const div = document.createElement('div');
    div.innerHTML = styleScriptText;
    div.childNodes.forEach(child => {
        document.head.appendChild(child.cloneNode(true));
        if (child.tagName === 'SCRIPT')
            eval(child.textContent);
    });
};
<button onclick="insertStyleScriptText()">insert StyleScriptText</button>

Leave a Reply

(*) Required, Your email will not be published