2

I have loaded a stylesheet with AJAX, the file is stored in the data variable. Now I need to access it's rules (there's a functionality behind it). The solution I am using now is this:

stylesheet = document.createElement('style');
stylesheet.type = 'text/css';
stylesheet.innerHTML = data;

document.head.appendChild(stylesheet);
stylesheet = document.styleSheets[2]; // I know which one is my file

rules = stylesheet.rules || stylesheet.cssRules;

Now the problem is that when it is added to the head, styling is applied on the page. How do I do the same without adding to the head?

Tried various things with Object.create(CSSStyleSheet.prototype) but couldn't get it done...

Julius
  • 2,473
  • 3
  • 20
  • 26
  • I think you may want to set your CSS styles to be very narrow in specificity so that they only apply to the HTML section/elements you want to affect (and not the entire page) – blurfus Feb 27 '15 at 18:53
  • This can't be done. Basically it's a customised Bootstrap style which is then parsed in the admin panel for editing the style. The problem is, the admin panel uses Bootstrap too. So if the edited and again loaded file has, e.g. different colour of navbar, it is affecting admin's navbar too. But I don't really need that. – Julius Feb 27 '15 at 18:56
  • 1
    Set [`stylesheet.disabled = true`](https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet/disabled) to the newly-created stylesheet, that way it doesn't re-style the page. – Teemu Feb 27 '15 at 19:05
  • Disabling a style didn't work. – Julius Feb 27 '15 at 19:28
  • @Julius It works, but you've to disable an appended sheet, if you disable an unappended sheet, it has no effect in all browsers. – Teemu Feb 27 '15 at 19:41
  • You're right! Your solution works too. – Julius Feb 28 '15 at 15:57

1 Answers1

3

I would simply create an empty hidden iframe and append stylesheet there. This way it would not affect anything and you would still be able to read its cssRules.

For example:

stylesheet = document.createElement('style');
stylesheet.type = 'text/css';
stylesheet.innerHTML = data;

var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);

var iframeDoc = iframe.contentWindow.document || iframe.contentDocument;
iframeDoc.body.appendChild(stylesheet);

stylesheet = iframeDoc.styleSheets[0];
rules = stylesheet.rules || stylesheet.cssRules;

Demo: http://plnkr.co/edit/hlNlpzfRmLP8IYYwePeC?p=preview

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Why? Iframes are cool and sometimes very useful. Like in this case. – dfsq Feb 27 '15 at 19:09
  • It's debatable on whether they are cool... Useful hacks? yes... Cool? not by a long shot... (but everyone has a definition of cool, I suppose) - http://stackoverflow.com/questions/362730/are-iframes-considered-bad-practice – blurfus Feb 27 '15 at 19:11
  • Well, it was cool for many interesting things like cross-domain communications and powerful AJAX transport before AJAX even was invented, posing data to the server, ajax file upload before FormData and XMLHttpRequest2. – dfsq Feb 27 '15 at 19:18
  • I agree on its usefulness *for very specific use cases*. I disagree on it being *cool* - to me, it feels like the 'GoTo' statement of web development which, while useful at times, can be a sign of bad web app design... in this case - and some that you pointed out - it may be useful but my spidey senses tell me, there is a better approach – blurfus Feb 27 '15 at 19:23