2

I am trying to redirect the user to a new URL (within the same domain) without reloading the page (to work around the browser's "must-interact-first" restrictions).

The page I am loading has some JavaScript added with <script> tags. However, the JavaScript does not run. In the example below I would expect I like cats to become green, but it stays black:

<html id="content">
    redirecting without reload
    <script>
        var redirectHtml = "<div id=\"docooljs\">I like cats</div> <script>document.getElementById(\"docooljs\").style.backgroundColor = \"#0F0\"<\/script>" // Pretend this is a GET request, any valid HTML could come here
        document.getElementById("content").innerHTML = redirectHtml;
    </script>
</html>

I can restructure this code to some extent (e.g. changing the triggers).


I tried the solution proposed in this post and it led me to the above code.

I cannot understand how to make it run.

Stack Overflow suggested this, but I might have more than 1 JavaScript I want to automatically run, and it would be really annoying to have to do this every time. Is there an easier way?

Also, this post explains that this is by design, and it's bad practice to work around it on the received URL, however, I am not doing anything cross-site, so attempting to work around it on the receiving URL seems like the best choice. Still, it seems to me that Youtube and others somehow load another URL from the same site without much trouble.

For example, going to the YouTube home page and clicking a video does not reload. However, it works identically (for all practical purposes) to directly loading the video URL. I am a JavaScript beginner and I cannot figure out how it does that by looking at the page source :(

2
  • 1
    It is definitely by design. Browsers will not run <script> element content from updated .innerHTML blocks. They simply do not. The jQuery library implements its own (rather involved) workaround by explicitly stripping out script contents and running it with eval(). Commented Jan 18, 2024 at 19:50
  • 1
    Use document.createElement("script") Commented Jan 18, 2024 at 19:51

1 Answer 1

2

You could find all the script elements and replace them with new ones created using document.createElement.

const content = document.querySelector('#content');
content.innerHTML = redirectHtml;
content.querySelectorAll('script').forEach(s => {
    const newScript = document.createElement('script');
    Object.assign(newScript, {textContent: s.textContent, src: s.src}); 
    s.replaceWith(newScript);
});
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.