I am developing a web page capturer and find that some stylesheet rules of a web page captured from Reddit are lost.
After a further investigation I found that the source HTML code of a Reddit page has a style element like this:
<style type="text/css" data-styled-ponents="..." data-styled-ponents-is-local="true">...</style>
When JavaScript has been on, the style element is processed by the script and be emptied:
<style type="text/css" data-styled-ponents="" data-styled-ponents-is-local="true"></style>
And that's why my capturer failed to get the stylesheets.
When the content of a style element is changed by script, the document stylesheet of the page would normally change accordingly and the page would be re-rendered to reflect the change.
However, for the Reddit page, after the style element is emptied, its stylesheet rules can still be accessed via document.styleSheets[1].cssRules
, while document.styleSheets[1].ownerNode.textContent
is ""
.
Additionally, if I modify the style element by running a script like document.styleSheets[1].ownerNode.textContent = "/*null*/"
, document.styleSheets[1].cssRules
bees empty and the web page is re-rendered, just like what my capturer has got.
I am confused by the bizarre behavior. I'd like to know why and how the Reddit page keep the styles after emptying the style element. Any information is appreciated.
I am developing a web page capturer and find that some stylesheet rules of a web page captured from Reddit. are lost.
After a further investigation I found that the source HTML code of a Reddit. page has a style element like this:
<style type="text/css" data-styled-ponents="..." data-styled-ponents-is-local="true">...</style>
When JavaScript has been on, the style element is processed by the script and be emptied:
<style type="text/css" data-styled-ponents="" data-styled-ponents-is-local="true"></style>
And that's why my capturer failed to get the stylesheets.
When the content of a style element is changed by script, the document stylesheet of the page would normally change accordingly and the page would be re-rendered to reflect the change.
However, for the Reddit. page, after the style element is emptied, its stylesheet rules can still be accessed via document.styleSheets[1].cssRules
, while document.styleSheets[1].ownerNode.textContent
is ""
.
Additionally, if I modify the style element by running a script like document.styleSheets[1].ownerNode.textContent = "/*null*/"
, document.styleSheets[1].cssRules
bees empty and the web page is re-rendered, just like what my capturer has got.
I am confused by the bizarre behavior. I'd like to know why and how the Reddit. page keep the styles after emptying the style element. Any information is appreciated.
Share Improve this question asked Feb 24, 2019 at 10:12 Danny LinDanny Lin 2,3201 gold badge22 silver badges36 bronze badges 6-
"However, for the Reddit. page, after the style element is emptied, its stylesheet rules can still be accessed via
document.styleSheets[1].cssRules
" If you are able to get the CSS rules what is the issue? – guest271314 Commented Feb 24, 2019 at 10:23 - 2 1. My capturer rely on raw stylesheet text rather than document.styleSheets, which is not accessible for a stylesheet file from another origin due to SOP. 2. This question is not only for the issue of my capturer, but also the reason why such inconsistency of style element content and the actual document stylesheet can exist. – Danny Lin Commented Feb 24, 2019 at 10:32
- What is a "raw stylesheet"? Am not certain what the issue is. How can the result be reproduced? Have you asked the authors of the site why the code performs in the manner that you have described? – guest271314 Commented Feb 24, 2019 at 10:36
-
Row stylesheet text is the text content of a style element or the retrieved file text of an external or imported stylesheet. You can open a page in Reddit., such as reddit. and run
document.styleSheets[1].cssRules
anddocument.styleSheets[1].ownerNode.textContent
from the console to see whether this issue exists. – Danny Lin Commented Feb 25, 2019 at 6:51 -
Still not following what the issue is.
document.styleSheets[1].cssRules
lists the rules of thestyleSheet
,document.styleSheets[1].ownerNode.outerHTML
is"<style type="text/css" data-styled-ponents="" data-styled-ponents-is-local="true"></style>"
,document.styleSheets[1].ownerNode.sheet
references thestyleSheet
. Are you expecting for nocssRules
to exist because no CSS text exists in the<style>
element? – guest271314 Commented Feb 25, 2019 at 6:56
2 Answers
Reset to default 5CSS rules of a <style>
element sheet
can be inserted, added or modified programmatically, where the .textContent
of the <style>
element returns an empty string ""
if CSS text is not set at or appended to the <style>
element.
<!DOCTYPE html>
<html>
<head>
<style id="style"></style>
</head>
<body>
<div>abc</div>
<p>123</p>
<script>
const style = document.querySelector("#style");
const {sheet} = style;
sheet.insertRule("div{color:blue}", 0);
sheet.addRule("p", "color:green", 1);
console.log(style.textContent);
style.textContent = "";
console.assert(style.textContent.length > 0, [style.textContent]); // assertion failed
console.log(style.textContent === ""); // true
</script>
</body>
</html>
See also Modify element :before CSS rules programmatically in React
Also check out Modify a stylesheet rule with CSSOM example from the MDN:
<html>
<head>
<title>Modifying a stylesheet rule with CSSOM</title>
<style type="text/css">
body {
background-color: red;
}
</style>
<script type="text/javascript">
var stylesheet = document.styleSheets[0];
stylesheet.cssRules[0].style.backgroundColor="blue";
</script>
</head>
<body>
The stylesheet declaration for the body's background color is modified via JavaScript.
</body>
</html>