I know I can set a CSS value through JavaScript such as:
document.getElementById('image_1').style.top = '100px';
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.
You can use getComputedStyle().
var element = document.getElementById('image_1'),
style = window.getComputedStyle(element),
top = style.getPropertyValue('top');
console.log(top);
<img id="image_1">
jsFiddle.
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;
}
}
Main reference stackoverflow
Use the following. It helped me.
document.getElementById('image_1').offsetTop
See also Get Styles.
Cross-browser solution to checking CSS values without DOM manipulation:
function get_style_rule_value(selector, style)
{
for (var i = 0; i < document.styleSheets.length; i++)
{
var mysheet = document.styleSheets[i];
var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (var j = 0; j < myrules.length; j++)
{
if (myrules[j].selectorText && myrules[j].selectorText.toLowerCase() === selector)
{
return myrules[j].style[style];
}
}
}
};
Usage:
get_style_rule_value('.chart-color', 'backgroundColor')
Sanitized version (forces selector input to lowercase, and allows for use case without leading ".")
function get_style_rule_value(selector, style)
{
var selector_compare=selector.toLowerCase();
var selector_compare2= selector_compare.substr(0,1)==='.' ? selector_compare.substr(1) : '.'+selector_compare;
for (var i = 0; i < document.styleSheets.length; i++)
{
var mysheet = document.styleSheets[i];
var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (var j = 0; j < myrules.length; j++)
{
if (myrules[j].selectorText)
{
var check = myrules[j].selectorText.toLowerCase();
switch (check)
{
case selector_compare :
case selector_compare2 : return myrules[j].style[style];
}
}
}
}
}
If you set it programmatically you can just call it like a variable (i.e. document.getElementById('image_1').style.top). Otherwise, you can always use jQuery:
<html>
<body>
<div id="test" style="height: 100px;">Test</div>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
alert($("#test").css("height"));
</script>
</body>
</html>
In 2021
check before use
You can use computedStyleMap()
The answer is valid but sometimes you need to check what unit it returns, you can get that without any slice() or substring() string.
var element = document.querySelector('.js-header-rep');
element.computedStyleMap().get('padding-left');
var element = document.querySelector('.jsCSS');
var con = element.computedStyleMap().get('padding-left');
console.log(con);
.jsCSS {
width: 10rem;
height: 10rem;
background-color: skyblue;
padding-left: 10px;
}
<div class="jsCSS"></div>
As a matter of safety, you may wish to check that the element exists before you attempt to read from it. If it doesn't exist, your code will throw an exception, which will stop execution on the rest of your JavaScript and potentially display an error message to the user -- not good. You want to be able to fail gracefully.
var height, width, top, margin, item;
item = document.getElementById( "image_1" );
if( item ) {
height = item.style.height;
width = item.style.width;
top = item.style.top;
margin = item.style.margin;
} else {
// Fail gracefully here
}
The cross-browser solution without DOM manipulation given above does not work because it gives the first matching rule, not the last. The last matching rule is the one which applies. Here is a working version:
function getStyleRuleValue(style, selector) {
let value = null;
for (let i = 0; i < document.styleSheets.length; i++) {
const mysheet = document.styleSheets[i];
const myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (let j = 0; j < myrules.length; j++) {
if (myrules[j].selectorText &&
myrules[j].selectorText.toLowerCase() === selector) {
value = myrules[j].style[style];
}
}
}
return value;
}
However, this simple search will not work in case of complex selectors.
Related
Is there a way to determine whether or not a css class exists using JavaScript?
This should be possible to do using the document.styleSheets[].rules[].selectorText and document.styleSheets[].imports[].rules[].selectorText properties. Refer to MDN documentation.
function getAllSelectors() {
var ret = [];
for(var i = 0; i < document.styleSheets.length; i++) {
var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
for(var x in rules) {
if(typeof rules[x].selectorText == 'string') ret.push(rules[x].selectorText);
}
}
return ret;
}
function selectorExists(selector) {
var selectors = getAllSelectors();
for(var i = 0; i < selectors.length; i++) {
if(selectors[i] == selector) return true;
}
return false;
}
Based on the answer, I created a javascript function for searching for a CSS class in the browser's memory -
var searchForCss = function (searchClassName) {
for (let i = 0; i < document.styleSheets.length; i++) {
let styleSheet = document.styleSheets[i];
try {
for (let j = 0; j < styleSheet.cssRules.length; j++) {
let rule = styleSheet.cssRules[j];
// console.log(rule.selectorText)
if (rule.selectorText && rule.selectorText.includes(searchClassName)) {
console.log('found - ', rule.selectorText, ' ', i, '-', j);
}
}
if (styleSheet.imports) {
for (let k = 0; k < styleSheet.imports.length; k++) {
let imp = styleSheet.imports[k];
for (let l = 0; l < imp.cssRules.length; l++) {
let rule = imp.cssRules[l];
if (
rule.selectorText &&
rule.selectorText.includes(searchClassName)
) {
console.log('found - ',rule.selectorText,' ',i,'-',k,'-',l);
}
}
}
}
} catch (err) {}
}
};
searchForCss('my-class-name');
This will print a line for each occurrence of the class name in any of the rules in any of the stylesheets.
Ref - Search for a CSS class in the browser memory
Here is my solution to this. I'm essentially just looping through document.styleSheets[].rules[].selectorText as #helen suggested.
/**
* This function searches for the existence of a specified CSS selector in a given stylesheet.
*
* #param (string) styleSheetName - This is the name of the stylesheet you'd like to search
* #param (string) selector - This is the name of the selector you'd like to find
* #return (bool) - Returns true if the selector is found, false if it's not found
* #example - console.log(selectorInStyleSheet ('myStyleSheet.css', '.myClass'));
*/
function selectorInStyleSheet(styleSheetName, selector) {
/*
* Get the index of 'styleSheetName' from the document.styleSheets object
*/
for (var i = 0; i < document.styleSheets.length; i++) {
var thisStyleSheet = document.styleSheets[i].href ? document.styleSheets[i].href.replace(/^.*[\\\/]/, '') : '';
if (thisStyleSheet == styleSheetName) { var idx = i; break; }
}
if (!idx) return false; // We can't find the specified stylesheet
/*
* Check the stylesheet for the specified selector
*/
var styleSheet = document.styleSheets[idx];
var cssRules = styleSheet.rules ? styleSheet.rules : styleSheet.cssRules;
for (var i = 0; i < cssRules.length; ++i) {
if(cssRules[i].selectorText == selector) return true;
}
return false;
}
This function offers a speed improvement over other solutions in that we are only searching the stylesheet passed to the function. The other solutions loop through all the stylesheets which is in many cases unnecessary.
/*
You can loop through every stylesheet currently loaded and return an array of all the defined rules for any selector text you specify, from tag names to class names or identifiers.
Don't include the '#' or '.' prefix for an id or class name.
Safari used to skip disabled stylesheets, and there may be other gotchas out there, but reading the rules generally works better across browsers than writing new ones.
*/
function getDefinedCss(s){
if(!document.styleSheets) return '';
if(typeof s== 'string') s= RegExp('\\b'+s+'\\b','i'); // IE capitalizes html selectors
var A, S, DS= document.styleSheets, n= DS.length, SA= [];
while(n){
S= DS[--n];
A= (S.rules)? S.rules: S.cssRules;
for(var i= 0, L= A.length; i<L; i++){
tem= A[i].selectorText? [A[i].selectorText, A[i].style.cssText]: [A[i]+''];
if(s.test(tem[0])) SA[SA.length]= tem;
}
}
return SA.join('\n\n');
}
getDefinedCss('p')//substitute a classname or id if you like
the latest item in the cascade is listed first.
Add this Condition Above
if (!document.getElementsByClassName('className').length){
//class not there
}
else{
//class there
}
If want to check on a element Just use
element.hasClassName( className );
also you can use on a ID
document.getElementById("myDIV").classList.contains('className');
Good Luck !!!
Building on Helen's answer, I came up with this:
//**************************************************************************
//** hasStyleRule
//**************************************************************************
/** Returns true if there is a style rule defined for a given selector.
* #param selector CSS selector (e.g. ".deleteIcon", "h2", "#mid")
*/
var hasStyleRule = function(selector) {
var hasRule = function(selector, rules){
if (!rules) return false;
for (var i=0; i<rules.length; i++) {
var rule = rules[i];
if (rule.selectorText){
var arr = rule.selectorText.split(',');
for (var j=0; j<arr.length; j++){
if (arr[j].indexOf(selector) !== -1){
var txt = trim(arr[j]);
if (txt===selector){
return true;
}
else{
var colIdx = txt.indexOf(":");
if (colIdx !== -1){
txt = trim(txt.substring(0, colIdx));
if (txt===selector){
return true;
}
}
}
}
}
}
}
return false;
};
var trim = function(str){
return str.replace(/^\s*/, "").replace(/\s*$/, "");
};
for (var i=0; i<document.styleSheets.length; i++){
var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
if (hasRule(selector, rules)){
return true;
}
var imports = document.styleSheets[i].imports;
if (imports){
for (var j=0; j<imports.length; j++){
rules = imports[j].rules || imports[j].cssRules;
if (hasRule(selector, rules)) return true;
}
}
}
return false;
};
You could check and see if an object of the style your are looking for already exists. If it does then the css class must exist because an object is using it. For example if you wanted to make sure that distinctly named svg objects each have their own style:
function getClassName(name) {
//Are there any elements which use a style named 'name' ?
if (document.getElementsByClassName(name).length === 0){
//There are none yest, let's make a new style and add it
var style = document.createElement('style');
style.type = 'text/css';
//Where you might provide your own hash function or rnd color
style.innerHTML = '.'+name+' { fill: #' + getHashColor(name) + '; background: #F495A3; }';
//Add the style to the document
document.getElementsByTagName('head')[0].appendChild(style);
}
return name;
}
Note that this is NOT a good approach if you are looking for a style which isn't necessarily used in your document.
if ($(".class-name").length > 0) {
}
That is a nice way to check the class in HTML by using javascript
Oneliner:
[].slice.call(document.styleSheets)
.reduce( (prev, styleSheet) => [].slice.call(styleSheet.cssRules))
.reduce( (prev, cssRule) => prev + cssRule.cssText)
.includes(".someClass")
function getAllSelectors() {
var ret = {};
for(var i=0;i<document.styleSheets.length;i++){
try {
var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
for(var x in rules) {
if(typeof rules[x].selectorText === 'string'){
if(ret[rules[x].selectorText] === undefined){
ret[rules[x].selectorText] = rules[x].style.cssText;
}
else {
ret[rules[x].selectorText] = ret[rules[x].selectorText] + ' ' + rules[x].style.cssText;
}
}
}
}
catch(error){
console.log(document.styleSheets[i]);
}
}
return ret;
}
function selectorExists(selector) {
var selectors = getAllSelectors();
if(selectors[selector] !== undefined){
return true;
}
return false;
}
// var allSelectors = getAllSelectors();
I know I can set a CSS value through JavaScript such as:
document.getElementById('image_1').style.top = '100px';
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.
You can use getComputedStyle().
var element = document.getElementById('image_1'),
style = window.getComputedStyle(element),
top = style.getPropertyValue('top');
console.log(top);
<img id="image_1">
jsFiddle.
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;
}
}
Main reference stackoverflow
Use the following. It helped me.
document.getElementById('image_1').offsetTop
See also Get Styles.
Cross-browser solution to checking CSS values without DOM manipulation:
function get_style_rule_value(selector, style)
{
for (var i = 0; i < document.styleSheets.length; i++)
{
var mysheet = document.styleSheets[i];
var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (var j = 0; j < myrules.length; j++)
{
if (myrules[j].selectorText && myrules[j].selectorText.toLowerCase() === selector)
{
return myrules[j].style[style];
}
}
}
};
Usage:
get_style_rule_value('.chart-color', 'backgroundColor')
Sanitized version (forces selector input to lowercase, and allows for use case without leading ".")
function get_style_rule_value(selector, style)
{
var selector_compare=selector.toLowerCase();
var selector_compare2= selector_compare.substr(0,1)==='.' ? selector_compare.substr(1) : '.'+selector_compare;
for (var i = 0; i < document.styleSheets.length; i++)
{
var mysheet = document.styleSheets[i];
var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (var j = 0; j < myrules.length; j++)
{
if (myrules[j].selectorText)
{
var check = myrules[j].selectorText.toLowerCase();
switch (check)
{
case selector_compare :
case selector_compare2 : return myrules[j].style[style];
}
}
}
}
}
If you set it programmatically you can just call it like a variable (i.e. document.getElementById('image_1').style.top). Otherwise, you can always use jQuery:
<html>
<body>
<div id="test" style="height: 100px;">Test</div>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
alert($("#test").css("height"));
</script>
</body>
</html>
In 2021
check before use
You can use computedStyleMap()
The answer is valid but sometimes you need to check what unit it returns, you can get that without any slice() or substring() string.
var element = document.querySelector('.js-header-rep');
element.computedStyleMap().get('padding-left');
var element = document.querySelector('.jsCSS');
var con = element.computedStyleMap().get('padding-left');
console.log(con);
.jsCSS {
width: 10rem;
height: 10rem;
background-color: skyblue;
padding-left: 10px;
}
<div class="jsCSS"></div>
As a matter of safety, you may wish to check that the element exists before you attempt to read from it. If it doesn't exist, your code will throw an exception, which will stop execution on the rest of your JavaScript and potentially display an error message to the user -- not good. You want to be able to fail gracefully.
var height, width, top, margin, item;
item = document.getElementById( "image_1" );
if( item ) {
height = item.style.height;
width = item.style.width;
top = item.style.top;
margin = item.style.margin;
} else {
// Fail gracefully here
}
The cross-browser solution without DOM manipulation given above does not work because it gives the first matching rule, not the last. The last matching rule is the one which applies. Here is a working version:
function getStyleRuleValue(style, selector) {
let value = null;
for (let i = 0; i < document.styleSheets.length; i++) {
const mysheet = document.styleSheets[i];
const myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
for (let j = 0; j < myrules.length; j++) {
if (myrules[j].selectorText &&
myrules[j].selectorText.toLowerCase() === selector) {
value = myrules[j].style[style];
}
}
}
return value;
}
However, this simple search will not work in case of complex selectors.
I have text on a page, its in a <h3> tag, which has a class ms-standardheader, but there are other texts on the page with the same class in its own <h3> tag. I also know the text I want to hide is 'Session'.
With this how can I write a javascript function to hide only this text?
Here is an image of the developtools from IE.
I'd suggest, if you're restricted (as your tags suggest) to non-library plain JavaScript, the following:
var h3s = document.getElementsByTagName('h3'),
classedH3 = [];
for (var i = 0, len = h3s.length; i < len; i++) {
if (h3s[i].className.indexOf('ms-standardheader') > -1) {
classedH3.push(h3s[i]);
}
}
for (var i = 0, len = classedH3.length; i < len; i++) {
if (classedH3[i].firstChild.nodeValue == 'the text to hide'){
classedH3[i].style.display = 'none';
}
}
JS Fiddle demo.
References:
push().
document.getElementsByTagName().
element.className.
node.nodeValue.
indexOf().
Can't you give the target element an ID? That would make things much more simple. Otherwise, you have to go through all <h3> elements until you find the one you want to hide:
var headings = document.getElementsByTagName("h3");
for(var i=0; i<headings.length; i++) {
var contentElement = headings[i].getElementsByTagName('nobr');
var content = "";
if(contentElement.length) {
content = contentElement[0].textContent ? contentElement[0].textContent : contentElement[0].innerText;
}
var content = contentElement.length ? contentElement[0].childNodes[0].nodeValue : '';
if(headings[i].className == 'ms-standardheader' && content == 'Session') {
headings[i].style.display = 'none';
}
}
you should try this :
window.onload = function()
{
getElementByClass('ms-standardheader');
}
window.getElementByClass = function(theClass){
var allHTMLTags=document.getElementsByTagName('*');
for (i=0; i<allHTMLTags.length; i++) {
if (allHTMLTags[i].className==theClass) {
var content = allHTMLTags[i].innerHTML;
var search = /session/;
if (search.test(content))
{
alert(search);
allHTMLTags[i].style.display='none';
}
}
}
}
See Demo : http://jsfiddle.net/3ETpf/18/
Always favour a unique Id where possible. If not possible then you have to manually traverse the DOM to find the elements you are looking for. Here's an example using getElementsByTagName().
var i, header, headers = document.getElementsByTagName('h3');
for (i = 0; i < headers.length; i += 1) {
header = headers[i];
if (header.className === 'ms-standardheader' &&
(header.textContent || header.innerText) === 'Session') {
header.style.display = 'none';
}
}
see: http://jsfiddle.net/whP5z/
If you have jquery you may type this :
$("h3.ms-standardheader:contains('Session')").hide();
I want to find the complete css information of applied class in details by clicking on it. Like
<div class="class1 class2">This is my div</div>
Suppose I've written css in xyz.css file
.class1{
background-color:#999999;
width:auto;
overflow:hidden;
}
.class2{
background-color:#856241;
width:500px;
overflow:hidden;
}
After clicking on the div I want to display all the css information which is applied to the div.
jQuery solution will be preferred.
As per first few answers I'm getting all the computed style but I'm interested in my only applied class style details.
You can get the current style of an element with this:
var elem = ...;
var css = document.defaultView ? document.defaultView.getComputedStyle(elem, null) : elem.currentStyle;
if ('length' in css) {
// iterate over all property names
for (var i = 0, l = css.length; i < l; ++i) {
var propertyName = css[i];
// get property value
var value = css[propertyName];
if (value != void 0) {
console.log(propertyName+': '+value);
}
}
} else {
// IE
for (var propertyName in css) {
// get property value
var value = css[propertyName];
if (value != void 0) {
console.log(propertyName+': '+value);
}
}
}
Try this here: http://jsfiddle.net/P5WYC/2/
You may also whant to try with document.styleSheets ( see http://www.quirksmode.org/dom/w3c_css.html )
You could do:
<div class="class1 class2" id='myId'>This is my div</div>
elem = document.getElementById('myId');
var cssRules = (getComputedStyle || currentStyle)(elem);
var properties = {};
for (var i = 0, l = cssRules.length; i < l; ++i) {
var propertyName = cssRules[i];
var value = cssRules.getPropertyValue(propertyName);
properties[propertyName] = value;
}
And properties is an object that has all the css properties of your div
I have a long table with many many columns and it looks really ugly for the users. What I wanted to do was create a simple button that would act as a switch, to turn on and off some of the columns.
Some of the columns are not needed, so what I did was add a class to every that wasn't needed, eg: ....
Now, what I thought I could do was this:
var hidden = 1;
function toggleTable(){
element_array = document.getElementsByClassName('disabled');
for(i = 0; i < element_array.length; i++){
if(hidden == 1){
element_array[i].style.display = 'none';
}else{
element_array[i].style.display = '';
}
}
if(hidden == 1) hidden = 0;
else hidden = 1;
}
This works for the most part in Firefox, but some quick tests in IE(7+8) and I get the following:
Message: Object doesn't support this property or method
Obviously indicating that IE doesn't want to let me simply change "display: none;" for something like table columns/rows.
I can't think of any workarounds. Ideally I'd like a fully cross-compatible solution to toggling the display of certain table columns,but if it's not compatible in the older browsers (eg: IE6) then that would also be OK.
The error that you're getting is not because IE doesn't want to set the display property, it's because the getElementsByClassName method isn't implemented in IE. If you want an implementation of that methods you can use this one which was written by Dustin Diaz.
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
Then you would re-write your method as follows.
var hidden = 1;
function toggleTable(){
var element_array = getElementsByClass('foo');
for(i = 0; i < element_array.length; i++){
if(hidden == 1){
element_array[i].style.display = 'none';
}else{
element_array[i].style.display = '';
}
}
if(hidden == 1) hidden = 0;
else hidden = 1;
}
toggleTable();
And what about jQuery.toggle()?
$(".disabled").toggle();