tldr: I want to update the stylesheet link in an iframe's srcdoc attribute using vanilla Javascript without affecting the rest of the content.
More detailed version:
I am customizing a blog template from Publii and adding a comment widget from Cusdis using their hosted JS SDK.
The template includes HTML, CSS, Javascript, and Handlebars.
To embed the Cusdis widget, you need to insert the following code snippet into your html document:
<div id="cusdis_thread"
data-host="https://cusdis.com"
data-app-id="{{ APP_ID }}"
data-page-id="{{ PAGE_ID }}"
data-page-url="{{ PAGE_URL }}"
data-page-title="{{ PAGE_TITLE }}"
>
<script async src="https://cusdis.com/js/cusdis.es.js"></script>
The Cusdis SDK will locate the element with id cusdis_thread
and display the iframe widget inside it:
<iframe srcdoc='<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cusdis.com/js/style.css">
<base target="_parent" />
<link>
<script>
window.CUSDIS_LOCALE = undefined
window.__DATA__ = {"host":"https://cusdis.com","appId":"...","pageId":"...","pageUrl":"...","pageTitle":"..."}
</script>
</head>
<body>
<div id="root"></div>
<script src="https://cusdis.com/js/iframe.umd.js" type="module"
</script>
</body>
</html>'
style="width: 100%; border: 0px none; height: 323px;">
#document
</iframe>
The challenge I face is as follows:
- I aim to customize the appearance of the Cusdis widget by altering its CSS.
- Although I've tried modifying my own stylesheet to target Cusdis's classes, the changes do not show up in the output (even when using !important). This could be due to the fact that the widget generates an iframe where the elements I wish to adjust reside.
- A potential solution is to replace the stylesheet link within the iframe's "srcdoc" attribute with a link to another external stylesheet.
Since the iframe is dynamically generated by Cusdis's SDK, I lack control over that portion of the HTML. My goal is to find a way to swap out the stylesheet in the generated iframe's srcdoc solely through the use of vanilla Javascript.
Here are my attempts:
Using setAttribute to target and replace only the stylesheet link:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<!DOCTYPE html><html><head><link rel="stylesheet" href="..."><base target="_parent" /><link><script> window.CUSDIS_LOCALE = undefined window.__DATA__ = {"host":"https://cusdis.com", appId":"...","pageId":"{{id}}","pageUrl":"{{url}}","pageTitle":"{{title}}"} </script> </head> <body> <div id="root"></div> <script src="https://cusdis.com/js/iframe.umd.js" type="module"> </script></body></html>');
Outcome: Although the operation was successful in theory, the comments section did not appear. Upon inspection, I noticed that the handlebars expressions {{}} remained unchanged within the srcdoc contents, causing issues with dynamic content rendering.
Hence, I seek a method that will preserve the existing content within the srcdoc attribute while updating only the stylesheet link. Below are my endeavors towards achieving this:
Applying .replace to identify and swap the URL of Cusdis's stylesheet:
document.querySelector("#cusdis_thread iframe").replace("https://cusdis.com/js/style.css", "...");
Outcome: The attempt went unnoticed
Utilizing setAttribute specifically for the stylesheet:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<link rel="stylesheet" href="...">');
Outcome: The action was disregarded