JS - how to get content of internal style element (<style>...</style) - javascript

by internal style I mean
<style>
#div
{color:red;}
</style>
document.getElementsByTagName('style').innerHTML is not working... document.styleSheets either.

document.getElementsByTagName returns Array of Elements
so you need to access it with index
document.getElementsByTagName('style')[0].innerHTML
document.styleSheets is much useful if you want to get specific selector or modify something from style sheet
Example
var styleSheet = document.styleSheets[1];
// assuming second one is embedded style,
// since document.styleSheets also shows linked style sheets (like <link heref=".. >)
for (var i = 0; i < styleSheet.rules.length; i++) {
// if you are looking for selector '.main'
if (styleSheet.rules[i].selectorText === '.main') {
// get background color
var oldBg = styleSheet.rules[i].style.backgroundColor;
// set background color
styleSheet.rules[i].style.backgroundColor = '#ddd';
}
}

document.styleSheets is an array , for each of the style definition in your page .
Iterate for each of the style elements and find the rules defined.
document.styleSheets[0].rules
This is again an array. so iterate . The rule text for each of the rules can be extracted as follows
document.styleSheets[indexofstyleelement].rules[indexofrule].cssText
document.styleSheets[0].rules[0].cssText gives rule text for first of the rules defined inside first style element

<!DOCTYPE html>
<html>
<head>
<style>
#div {
color: red;
}
</style>
</head>
<body>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
var x = document.getElementsByTagName("STYLE")[1];
document.getElementById("demo").innerHTML = x.innerHTML;
}
</script>
</body>
</html>
https://jsfiddle.net/mediaguru/xt9mkncx/

using jquery use this
var x = $('style').html();
using javascript
var x=document.getElementById("home");
var y = x.firstChild.innerHTML;

Ahh I'm so stupid..
for (var i = 0; i < styles_length; i++)
{// I had:
// styles.innerHTML;
// not correct:
styles[i].innerHTML;
}
All answers by #Jag, #ABHIJITH GM, #mediaguru, #hardik are correct.
Thank you guys! And sorry for this newbie question... all day codding, my eyes are hurting, coffee time.

Related

Adding/changing properties in all the tags of a type (odd results)

I am looking for a way to add/change some properties in all tags of a certain type after the page is loaded.
I found two ways. But for some reason that I don't understand, the results are different.
Method 1 - adding a style tag as the last child of <html>.
var style = document.createElement( "style" );
style.innerHTML = `
div {
background-color: black;
color: white;
}
`;
document.documentElement.appendChild( style );
Result of style tag as last HTML child method
Method 2 - Getting all the tags of that type and painfully having it change them one.
var elems = document.body.getElementsByTagName("div");
for( let i = 0; i < elems.length; i++ ){
elems[i].style.backgroundColor = "black";
elems[i].style.color = "white";
}
Result of loop/in-line method
So I was wondering why the results between the two methods are different, and I'm also happy to learn about other methods of changing all tags of a type of course.
the first method it creates a <style> tag and sets its attributes like you would write the css in the <style> tag or enter it via <link>
the 2nd method uses the style attribute of each tag which is also W3C standard but scoped to just that tag and has syntactic limitations (cannot use selectors like :hover , :focus...)
the 2nd method is faster than 1 and has higher precedence and no error about scoped it is preferred in javascript
Here, Method 1 adding a new style tag to the document and applying CSS styles using the innerHTML. All tags on the page that match with the selector div will have the styles using this technique. However, depending on how much styling is required, this technique may result in a slower page load.
Then,another method which is selecting the background and color properties of each div element on the page by looping through all of them. This approach is quicker because it doesn't need to wait for new styles to load.
So, another method you can use just by changing a bit in your second method is:
var elems = document.querySelectorAll("div");
for( let i = 0; i < elems.length; i++ ){
elems[i].style.backgroundColor = "black";
elems[i].style.color = "white";
}
Nevertheless, you can also use Jquery for shortcut execution :
$("div").css({
"background-color": "black",
"color": "white"
});
The difference was priority. The same inline results of method 2 (loop/inline), were achieved with method 1 (<style> as last child) by adding the !important rule due to the increased priority. Like so:
div {
background-color: black !important;
color: white !important;
}
Simple example demoing how to easily and fully revert all changes, and be left back with the original HTML:
<!DOCTYPE html>
<html>
<head>
<style>
p {
background-color: red;
}
</style>
</head>
<body>
<p>Text sample.</p>
<p style="background-color: grey">Text sample.</p>
<button onclick="test1()">Remove temporary changes</button>
</body>
<script>
function test1() {
document.getElementById("tempChanges").remove();
}
</script>
<style id="tempChanges">
p {
background-color: green !important;
}
</style>
</html>

How to change / add p tag style using DOM?

I want a variable font-size in my P tag using the DOM but I can't seem to find a way to access it to change the styles. I tried this,
document.body.p.style.font-size = ""+p_var+"px";
along with trying several ways using setAttribute with no luck. Can anyone please show me how to change it if it is possible.
Try following code:
var s=document.getElementsByTagName('p');
for(i=0;i<s.length;i++)
{
s[i].setAttribute("style","font-size:"+p_var+"px");
}
Demo Fiddle
Try something like this,
<p id="myP">This is a paragraph.</p>
JS
document.getElementById("myP").style.fontSize = ""+p_var+"px";
else if you want to set style for all the <p> tags try the below
var node;
node = document.getElementsByTagName('p');
for (var i = node.length-1; i>=0; i--) {
node[i].style.fontSize = ""+p_var+"px";
}
Also if you need to have same class name for <p> tags as below,
<p class="myP">This is a paragraph.</p>
<p class="myP">This is a paragraph.</p>
try this,
var node;
node = document.getElementsByClassName('myP');
for (var i = node.length-1; i>=0; i--) {
node[i].style.fontSize = ""+p_var+"px";
}
Using jquery it can be done as
$("p").css({"font-size":"30px"});
First, prepair a css class for example
.font30 {
font-size: 30px;
}
Then do with jquery
$("p").addClass("font30");
It's good practice to work with class instead of inline css :)

IE9 get hover color javascript [duplicate]

I made a function that overwrite the the :hover of some elements on a page. It fades between the normal and the :hover effect. That for i had to create a .hover class in my CSS file. I think this is a little unclean. How could i read the the :hover pseudo class contents?
Using getComputedStyle as on the accepted answer won't work, because:
The computed style for the hover state is only available when the element is actually on that state.
The second parameter to getComputedStyle should be empty or a pseudo-element. It doesn't work with :hover because it's a pseudo-class.
Here is an alternative solution:
function getCssPropertyForRule(rule, prop) {
var sheets = document.styleSheets;
var slen = sheets.length;
for(var i=0; i<slen; i++) {
var rules = document.styleSheets[i].cssRules;
var rlen = rules.length;
for(var j=0; j<rlen; j++) {
if(rules[j].selectorText == rule) {
return rules[j].style[prop];
}
}
}
}
// Get the "color" value defined on a "div:hover" rule,
// and output it to the console
console.log(getCssPropertyForRule('div:hover', 'color'));
Demo
You could access document.styleSheets and look for a rule that is applied on that specific element. But that’s not any cleaner than using a simple additional class.
UPDATE: I somehow got this wrong. The below example doesn't work. See #bfavaretto's comment for an explanation.
In Firefox, Opera and Chrome or any other browser that correctly implements window.getComputedStyle is very simple. You just have to pass "hover" as the second argument:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
div {
display: block;
width: 200px;
height: 200px;
background: red;
}
div:hover {
background: green;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript">
window.onload = function () {
var div = document.getElementsByTagName("div")[0];
var style = window.getComputedStyle(div, "hover");
alert(style.backgroundColor);
};
</script>
</body>
</html>
But I don't believe there's yet a solution for Internet Explorer, except for using document.styleSheets as Gumbo suggested. But there will be differences. So, having a .hover class is the best solution so far. Not unclean at all.
If there are any people here who use the questions accepted answer but it won't work, here's a nice function that might:
function getPseudoStyle(id, style) {
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
var targetrule = "";
if (all[i].id === id) {
if(all[i].selectorText.toLowerCase()== id + ":" + style) { //example. find "a:hover" rule
targetrule=myrules[i]
}
}
return targetrule;
}
}
There is an alterantive way to get :hover pseudo class with javascript. You can write your styles of hover pseudo class in a content property.
p::before,
p::after{
content: 'background-color: blue; color:blue; font-size: 14px;';
}
then read from it via getComputedStyle() method:
console.log(getComputedStyle(document.querySelector('p'),':before').getPropertyValue('content'));

Javascript get CSS style for ID

I would like to be able to get the style from a CSS element which is not used on the webpage. For example, this is the page:
<html>
<head>
<style type="text/css">
#custom{
background-color: #000;
}
</style>
</head>
<body>
<p>Hello world</p>
</body>
</html>
as you can see the ID 'custom' has a value but is not used within the document. I would like to get all the values for 'custom' without using it in the page. The closest I have come is:
el = document.getElementById('custom');
var result;
var styleProp = 'background-color';
if(el.currentStyle){
result = el.currentStyle[styleProp];
}else if (window.getComputedStyle){
result = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
}else{
result = "unknown";
}
Create a new element with given ID and append it to the document. Then just read the value and remove the element.
Example:
var result,
el = document.body.appendChild(document.createElement("div")),
styleProp = 'background-color',
style;
el.id = 'custom';
style = el.currentStyle || window.getComputedStyle(el, null);
result = style[styleProp] || "unknown";
// Remove the element
document.body.removeChild(el);
I don't think the answer was a very good one as it requires adding elements to the DOM which may disrupt what you are trying to do or create visual glitches.
Using document.styleSheets I think you can get a less invasive solution. (see here)
try something like:
var result;
var SS = document.styleSheets;
for(var i=0; i<SS.length; i++) {
for(var j=0; j<SS[i].cssRules.length; j++) {
if(SS[i].cssRules[j].selectorText == "#custom") {
result = SS[i].cssRules[j].style;
}
}
}
This should give you an object which will contain all of the styles as the keys. keep in mind you may need a little more complex algorithm if the style is redeclared within the stylesheets.

Need Regexp for classname replace

I have following HTML code:
Its look like
<html>
<head>
</head>
<style id="styletag">
.class3{
}
.sec2{
}
.this3{
}
</style>
<body>
<div class="class1 class2 class3">content</div>
<div class="sec1 sec2 sec3">content2</div>
<div class="this1 this2 this3">content2</div>
</body>
</html>
I am having the values class3, sec2 and this3 in array.
I want to replace this class3,sec2 and this3 from the HTML code.
And I also want to remove the style tag entirely (its having the id name 'styletag').
How do i use the regexp?
Sorry if I misunderstood what you ask for.
for(var index=0; index<document.getElementsTagName("div").length; index++) {
if( document.getElementsTagName("div")[index].style.className.indexOf("class3")
|| document.getElementsTagName("div")[index].style.className.indexOf("sec2")
|| document.getElementsTagName("div")[index].style.className.indexOf("this3")
)
// assign a new css
document.getElementsTagName("div")[index].style.className = 'newCss';
// or clear style
// document.getElementsTagName("div")[index].style.className = '';
// or add up another style
// document.getElementsTagName("div")[index].style.className += ' newCSS';
}
And regarding removal of Style tag:
document.getElementById("styletag").parentNode.removeChild(document.getElementById("styletag"));
Forget regex. You can't use regex to parse HTML in any way reliably. And if you're running from JavaScript regex means reading and writing the entire document's innerHTML, which you should avoid.
Here's a JS version that's a bit more rigorous about detecting full and not just partial class names:
function Element_setClass(element, classname, active) {
var classes= element.className.split(' ');
var ix= classes.indexOf(classname);
if ((ix!==-1)===active)
return;
if (active)
classes.push(classname);
else
classes.splice(ix, 1);
element.className= classes.join(' ');
}
var els= document.getElentsByTagName('div');
for (var i= els.length; i-->0;) {
Element_setClass(els[i], 'class3', false);
Element_setClass(els[i], 'sec2', false);
Element_setClass(els[i], 'this3', false);
}
var el= document.getElementById('styletag');
el.parentNode.removeChild(el);
And though I'm loathe to drag in frameworks to a plain JavaScript question, I have to admit jQuery makes this very easy to spell:
$('.class3').removeClass('class3');
$('.sec2').removeClass('sec2');
$('.this3').removeClass('this3');
$('#styletag').remove();
Removing the classes works by replacing this:
(<div[^>]+class="[^"]*)\b(class3|this3|sec2)\b([^"]*")
with this:
$1$3
The style tag can be removed by replacing the following with a blank string:
<style id="styleTag">[^<]*<\/style>
Another good way to achieve the same would be using jQuery.

Categories

Resources