Javascript содержимое css файла

How do you read CSS rule values with JavaScript?

I would like to return a string with all of the contents of a CSS rule, like the format you’d see in an inline style. I’d like to be able to do this without knowing what is contained in a particular rule, so I can’t just pull them out by style name (like .style.width etc.) The CSS:

function getStyle(className) < var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules for(var x=0;x> > getStyle('.test') 

17 Answers 17

Adapted from here, building on scunliffe’s answer:

function getStyle(className) < var cssText = ""; var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules; for (var x = 0; x < classes.length; x++) < if (classes[x].selectorText == className) < cssText += classes[x].cssText || classes[x].style.cssText; >> return cssText; > alert(getStyle('.test')); 

Note that className must exactly match the selector used in CSS file. For example getStyle(«.article a») won’t find anything if a style has been described like this «.article a, article a:hover < color: #ccc; >«.

if there are multiple stylesheets, then you will also need to loop through those as well.for(var i=0;i

@Johnydep var classes should be document.styleSheets[0].rules[0].cssRules in Chrome. This could be (creatively) added to the shim in the answer.

Even still, in late March 2020, this doesn’t work in Chrome, per Vilius Paulauskas’s comment from back in September 2011. I came up with a complete code that works (DISCLAIMER: I only tested it on Chrome.) idk whether to revise this answer with it, since it is accepted answer, or create my own answer.

Читайте также:  Ваш браузер устарел php

Since the accepted answer from «nsdel» is only avilable with one stylesheet in a document this is the adapted full working solution:

 /** * Gets styles by a classname * * @notice The className must be 1:1 the same as in the CSS * @param string className_ */ function getStyle(className_) < var styleSheets = window.document.styleSheets; var styleSheetsLength = styleSheets.length; for(var i = 0; i < styleSheetsLength; i++)< var classes = styleSheets[i].rules || styleSheets[i].cssRules; if (!classes) continue; var classesLength = classes.length; for (var x = 0; x < classesLength; x++) < if (classes[x].selectorText == className_) < var ret; if(classes[x].cssText)< ret = classes[x].cssText; >else < ret = classes[x].style.cssText; >if(ret.indexOf(classes[x].selectorText) == -1)< ret = classes[x].selectorText + ""; > return ret; > > > > 

Notice: The selector must be the same as in the CSS.

your code fails if a stylesheet has no rules or cssRules (which can happen!) add if (!classes) continue; after var classes = styleSheets[i].rules || styleSheets[i].cssRules; var classesLength = classes.length; see my edit

SOLUTION 1 (CROSS-BROWSER)

function GetProperty(classOrId,property) < var FirstChar = classOrId.charAt(0); var Remaining= classOrId.substring(1); var elem = (FirstChar =='#') ? document.getElementById(Remaining) : document.getElementsByClassName(Remaining)[0]; return window.getComputedStyle(elem,null).getPropertyValue(property); >alert( GetProperty(".my_site_title","position") ) ; 

SOLUTION 2 (CROSS-BROWSER)

function GetStyle(CLASSname) < var styleSheets = document.styleSheets; var styleSheetsLength = styleSheets.length; for(var i = 0; i < styleSheetsLength; i++)< if (styleSheets[i].rules ) < var classes = styleSheets[i].rules; >else < try < if(!styleSheets[i].cssRules) > //Note that SecurityError exception is specific to Firefox. catch(e) < if(e.name == 'SecurityError') < console.log("SecurityError. Cant readd: "+ styleSheets[i].href); continue; >> var classes = styleSheets[i].cssRules ; > for (var x = 0; x < classes.length; x++) < if (classes[x].selectorText == CLASSname) < var ret = (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText ; if(ret.indexOf(classes[x].selectorText) == -1)";> return ret; > > > > alert( GetStyle('.my_site_title') ); 

Sadly, by now the problem is basically unsolvable universally in a good way. The 1st solution does not work since at times the browser still did not finish the computing of styles so it does not return a correct value yet (a reason to read actual CSS rules). And there is no event to listen to for this. The 2nd solution only works on your own styles as both FF & Chrome (and maybe others) throw a ‘Security Error’ due to CORS violation when you try to access style sheets. The only way is ugly: to use setInterval waiting for styles to be computed if you know that values might change.

I’ve found none of the suggestions to really work. Here’s a more robust one that normalizes spacing when finding classes.

//Inside closure so that the inner functions don't need regeneration on every call. const getCssClasses = (function () < function normalize(str) < if (!str) return ''; str = String(str).replace(/\s*([>~+])\s*/g, ' $1 '); //Normalize symbol spacing. return str.replace(/(\s+)/g, ' ').trim(); //Normalize whitespace > function split(str, on) < //Split, Trim, and remove empty elements return str.split(on).map(x =>x.trim()).filter(x => x); > function containsAny(selText, ors) < return selText ? ors.some(x =>selText.indexOf(x) >= 0) : false; > return function (selector) < const logicalORs = split(normalize(selector), ','); const sheets = Array.from(window.document.styleSheets); const ruleArrays = sheets.map((x) =>Array.from(x.rules || x.cssRules || [])); const allRules = ruleArrays.reduce((all, x) => all.concat(x), []); return allRules.filter((x) => containsAny(normalize(x.selectorText), logicalORs)); >; >)(); 

Here’s it in action from the Chrome console.

enter image description here

This is the mecha of all the answers on this page. I would even go as far as to say this should be on github

This doesn’t work in IE11, because Array.map() with the provided syntax is not supported. I’d suggest changing it to the old function() < return xxx; >syntax for better compatibility. Otherwise, great answer!

I modified this to work with IE11 (e.g. ES5). Here’s a JSFiddle with everything you need: jsfiddle.net/xp5r8961

Some browser differences to be aware of:

and given InsDel’s example, classes will have 2 classes in FF and 3 classes in IE7.

My example illustrates this:

    div#a < >div#b, div#c    
RULES:

Here is code to iterate through all rules in a page:

function iterateCSS(f) < for (const styleSheet of window.document.styleSheets) < const classes = styleSheet.rules || styleSheet.cssRules; if (!classes) continue; for (const cssRule of classes) < if (cssRule.type !== 1 || !cssRule.style) continue; const selector = cssRule.selectorText, style=cssRule.style; if (!selector || !style.cssText) continue; for (let i=0; i> > > iterateCSS( (selector, propertyName, propertyValue, propertyPriority, cssRule) => < console.log(selector+' < '+propertyName+': '+propertyValue+(propertyPriority==='important' ? ' !important' : '')+' >'); >);
function getStyle(className) < document.styleSheets.item("menu").cssRules.item(className).cssText; >getStyle('.test') 

Note : «menu» is an element ID which you have applied CSS. «className» a css class name which we need to get its text.

Have adapted julmot’s answer in order to get a more complete result. This method will also return styles where the class is part for the selector.

//Get all styles where the provided class is involved //Input parameters should be css selector such as .myClass or #m //returned as an array of tuples function getStyleWithCSSSelector(cssSelector) < var styleSheets = window.document.styleSheets; var styleSheetsLength = styleSheets.length; var arStylesWithCSSSelector = []; //in order to not find class which has the current name as prefix var arValidCharsAfterCssSelector = [" ", ".", ",", "#",">","+",":","["]; //loop through all the stylessheets in the bor for(var i = 0; i < styleSheetsLength; i++)< var classes = styleSheets[i].rules || styleSheets[i].cssRules; var classesLength = classes.length; for (var x = 0; x < classesLength; x++) < //check for any reference to the class in the selector string if(typeof classes[x].selectorText != "undefined")< var matchClass = false; if(classes[x].selectorText === cssSelector)else > if(matchClass === true) < //console.log("Found "+ cssSelectorWithNextChar + " in css class definition " + classes[x].selectorText); var styleDefinition; if(classes[x].cssText)< styleDefinition = classes[x].cssText; >else < styleDefinition = classes[x].style.cssText; >if(styleDefinition.indexOf(classes[x].selectorText) == -1)< styleDefinition = classes[x].selectorText + ""; > arStylesWithCSSSelector.push(); > > > > if(arStylesWithCSSSelector.length==0) < return null; >else < return arStylesWithCSSSelector; >> 

In addition, I’ve made a function which collects the css style definitions to the sub-tree of a root node your provide (through a jquery selector).

function getAllCSSClassDefinitionsForSubtree(selectorOfRootElement) < //stack in which elements are pushed and poped from var arStackElements = []; //dictionary for checking already added css class definitions var existingClassDefinitions = <>//use jquery for selecting root element var rootElement = $(selectorOfRootElement)[0]; //string with the complete CSS output var cssString = ""; console.log("Fetching all classes used in sub tree of " +selectorOfRootElement); arStackElements.push(rootElement); var currentElement; while(currentElement = arStackElements.pop())< currentElement = $(currentElement); console.log("Processing element " + currentElement.attr("id")); //Look at class attribute of element var classesString = currentElement.attr("class"); if(typeof classesString != 'undefined')< var arClasses = classesString.split(" "); //for each class in the current element for(var i=0; i< arClasses.length; i++)< //fetch the CSS Styles for a single class. Need to append the . char to indicate its a class var arStylesWithCSSSelector = getStyleWithCSSSelector("."+arClasses[i]); console.log("Processing class "+ arClasses[i]); if(arStylesWithCSSSelector != null)< //console.log("Found "+ arStylesWithCSSSelector.length + " CSS style definitions for class " +arClasses[i]); //append all found styles to the cssString for(var j=0; j< arStylesWithCSSSelector.length; j++)< var tupleStyleWithCSSSelector = arStylesWithCSSSelector[j]; //check if it has already been added if(typeof existingClassDefinitions[tupleStyleWithCSSSelector.selectorText] === "undefined")< //console.log("Adding " + tupleStyleWithCSSSelector.styleDefinition); cssString+= tupleStyleWithCSSSelector.styleDefinition; existingClassDefinitions[tupleStyleWithCSSSelector.selectorText] = true; >else < //console.log("Already added " + tupleStyleWithCSSSelector.styleDefinition); >> > > > //push all child elments to stack if(currentElement.children().length>0) < arStackElements= arStackElements.concat(currentElement.children().toArray()); >> console.log("Found " + Object.keys(existingClassDefinitions).length + " CSS class definitions"); return cssString; > 

Note that if a class is defined several times with the same selector, the above function will only pick up the first. Note that the example uses jQuery (but cab relatively easily be rewritten to not use it)

Источник

Access CSS file contents via JavaScript

I’m not really into getting all the CSS rules via document.styleSheets, is there another way? Update: There is the ajax option of course, I appreciate the answers given. But it seems rather unnecessary to reload a file using ajax that is already loaded in the browser. So if anyone knows another way to extract the text contents of a present CSS file (NOT the CSS rules), please post!

@Diodeus it’s not a dup, as stated I’m not interested in parsing CSS values from a stylesheet, I’d like to extract the entire text contents.

7 Answers 7

With that specific example (where the CSS is on the same origin as the page), you could read the file as text via ajax :

If you want to access the information in a more structured way, document.styleSheets is an array of the style sheets associated with the document. Each style sheet has a property called cssRules (or just rules on some browsers), which is an array of the text of each rule in the style sheet. Each rule has a cssText property. So you could loop through those, e.g.:

$.each(document.styleSheets, function(sheetIndex, sheet) < console.log("Looking at styleSheet[" + sheetIndex + "]:"); $.each(sheet.cssRules || sheet.rules, function(ruleIndex, rule) < console.log("rule[" + ruleIndex + "]: " + rule.cssText); >); >); 

Live example — That example has one stylesheet with two rules.

The document.styleSheet thing is nice, but not what I need. I need the EXACT text contents, not an array of rules to loop though. Perhaps I wasn’t clear on this.

@David: Then you’ll have to do the extra GET. Once the CSS text is loaded and parsed, as far as I’m aware the browser doesn’t retain the original source of it. (This is true of HTML pages as well, which is why you see «view source» do a request to get the source text.)

it would be possible load the content of css file via ajax and then create a

@David: No, when you access the innerHTML property, the browser creates an HTML string representing the current state of the DOM tree for the element (in that case, the whole document) you access it on. It’s not at all the same as the source of the page, which may be formatted differently, may have actually been different because DOM manipulation has been done since, could have omitted tags that the browser includes, may have had comments browsers don’t retain, different quoting around attributes, etc., etc.

@SlaterVictoroff — Which part? I’d be surprised at an SOP (not CORS, which is a way to loosen the SOP) violation for something on the same origin.

Источник

JavaScript. Как вытянуть содержимое .css файла?

Доброго времени!
Кто нибудь знает способ как из подключенного .css файла в head
.


.
вытянуть его содержимое средствами .js?

с поправкой: вытянуть без запросов и скачивания, прямо с кеша браузера скажем так.

bingo347

Если стили на нашей странице, то через CSSOM (хорошо гуглится)
Так же можете поисследовать в консольке document.styleSheets
Ну и нужно учитывать, что для кроссдоменных стилей нужен CORS

lazalu68

bingo347

Kovalsky, да, если ресурс с другого домена, то сторонний сервер должен отдавать CORS заголовки, а к тегу link нужно прописать атрибут crossorigin=»anonymous» чтобы CSSOM данного styleSheet был доступен

Xuxicheta

Еще можно получить ссылку на элемент и прочитать у него $0.sheet.cssRules
Но тоже самое, если стили с другого домена, то в js они будут недоступны.

Uncaught DOMException: Failed to read the 'rules' property from 'CSSStyleSheet'

bingo347

Антон Швец, document.styleSheets это на самом деле что-то вроде агрегации всех стилей на странице, все равно что Вы сделаете

const styleSheets = [. document.querySelector('style, link[rel=stylesheet]')].map(s => s.sheet)

Дмитрий Беляев, необходимо получить не значение/объект, а содержимое стилей в виде строки (без запросов XMLHttpRequest, fetch и т.п.)

вытянуть с браузера, после загрузки страницы
с какой стороны вообще можно подойти?

Xuxicheta

bingo347

const allAvailableStylesText = [. document.styleSheets].flatMap(sheet => < try < return [. sheet.cssRules]; >catch < return []; >>).map(rule => rule.cssText).join(''); console.log(allAvailableStylesText);

Войдите, чтобы написать ответ

Почему JS выдает синтаксическую ошибку на JSX?

Источник

Get a CSS value with JavaScript

But, can I get a current specific style value? I’ve read where I can get the entire style for the element, but I don’t want to have to parse the whole string if I don’t have to.

Your question lends to believe you want something like var top = document.getElementById(‘image_1’).style.top; May want to rephrase it if that’s not what you want

Thx All, both methods work perfectly, just what I needed. The Jquery method is a bit more compact, so I’ll probably use that.

8 Answers 8

var element = document.getElementById('image_1'), style = window.getComputedStyle(element), top = style.getPropertyValue('top'); console.log(top);

If you want to change background color of a div for example, be careful to NOT USE «backgroundColor» instead of «backgroung-color» 😉

Somewhat off topic: some (all?) shorthand css properties are not accessible in JavaScript. E.g. you can get padding-left but not padding. JSFiddle

@DavidWiniecki i dont really believe webdevs should still consider IE8 a mainstream browser. considering it is no longer supported by microsoft

The element.style property lets you know only the CSS properties that were defined as inline in that element (programmatically, or defined in the style attribute of the element), you should get the computed style.

Is not so easy to do it in a cross-browser way, IE has its own way, through the element.currentStyle property, and the DOM Level 2 standard way, implemented by other browsers is through the document.defaultView.getComputedStyle method.

The two ways have differences, for example, the IE element.currentStyle property expect that you access the CSS property names composed of two or more words in camelCase (e.g. maxHeight, fontSize, backgroundColor, etc), the standard way expects the properties with the words separated with dashes (e.g. max-height, font-size, background-color, etc). .

function getStyle(el, styleProp) < var value, defaultView = (el.ownerDocument || document).defaultView; // W3C standard way: if (defaultView && defaultView.getComputedStyle) < // sanitize property name to css notation // (hyphen separated words eg. font-Size) styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase(); return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp); >else if (el.currentStyle) < // IE // sanitize property name to camelCase styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) < return letter.toUpperCase(); >); value = el.currentStyle[styleProp]; // convert other units to pixels on IE if (/^\d+(em|pt|%|ex)?$/i.test(value)) < return (function(value) < var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left; el.runtimeStyle.left = el.currentStyle.left; el.style.left = value || 0; value = el.style.pixelLeft + "px"; el.style.left = oldLeft; el.runtimeStyle.left = oldRsLeft; return value; >)(value); > return value; > > 

Источник

Оцените статью