how to get a CSSStyleSheet object from a HTMLStyleElement element - javascript

Is it possible to get the CSSStyleSheet object (document.styleSheets[0]) from a HTMLStyleElement (document.createElement('style')) ?
I would like to dynamically add css rules to a not-inserted-in-the-document-yet <style> element.

It is possible to get a CSSStyleSheet object from a <style> element.
var style = document.createElement('style');
document.head.appendChild(style);
var styleSheet = style.sheet // Will give you the associated CSSStyleSheet
This will only work after the <style> element has been appended to the document.
Not exceptionally well documented and very difficult to find by poking around in console.

You can add rules before you add the style element to the document.
A couple notes-
Older IE browsers cannot add child nodes to a style element, so assign to the element's styleSheet.csstext property for them.
Make sure you append the new element to the head of the document.
function addStyle(css, media1, title1){
var el= document.createElement('style');
el.type= 'text/css';
if(media1) el.media= media1;
if(title1) el.title= title1;
if(el.styleSheet) el.styleSheet.cssText= css;//IE
else{
el.appendChild(document.createTextNode(css));
}
//return el without the next line if you want to append it later
return document.getElementsByTagName('head')[0].appendChild(el);
}
var cs1= [
'#yw_psq, #yw_psq h2{background-color: green; color: white;}',
'#yw_psq_div{margin: 1ex; position: relative; text-align: center;}',
'#ps_counter{color: white; margin: 1ex 0 0 0; text-align: center;}',
'#pzsq_grid button{cursor: pointer; font-size: 1.2em; width: 100%;}',
'#delaySpan{font-weight: bold; margin-left: 1em;}'
]
addStyle(cs1.join('\n'),'screen','yw_psq');

If you have access to the element to-be-inserted, you can add style info to it just like any other element. Once the element is inserted, the browser will re-flow the page and will pick up on any relevant CSS rules that apply. You don't need access to the stylesheet to style an element, you just need access to the element.

Related

Styling the HTML tags that are created in javascript

If i use HTML tags inside javascript file, how can i select them and use them in a css file?
for example:
javascript:
<li id="id"> name </li>
how can i select and use id in the stylesheet?
I tried it this way but it didnt work
#id li { background: red;}
I would avoid using ids as they have to be unique (no more than one per page). If you have to target specific list items use data attributes.
ul li[data-type="name"] { color: red; }
<ul>
<li data-type="name">Bobby</li>
<li data-type="age">26</li>
</ul
either you can use the JS also add style to the Element.
document.getElementById(id).style.property = new style
Add inline style using Javascript
Or you need to load the script before the style.
If you assign a id to any tag or element you don't need to use element or tag name to style it. Directly use id. by #id li { background: red; } it means inside the element(which has id) it search for another li element.
Try
#id {
background: red;
}
if your creating element dynamically it's better to apple style that time
for example
var el = document.createElement('div');
el.setAttribute(
'style',
'background-color: red; color: white; width: 150px; height: 150px; border: 1px red solid');
var container = document.getElementById('container-id');
container.appendChild(el);
I would avoid using ids as they have to be unique
.bgred { background: red;color:#fff }
.bggreen { background: green;color:#fff }
<ul>
<li class="bgred">Bobby</li>
<li class="bggreen">26</li>
</ul>

How do you remove CSS style inside a style element?

Example:
<style>
.className {
left: 0;
color: blue;
}
</style>
I want to remove the left: 0; aspect using javascript/jquery or whatever method I have to use to do this. I don't have the option of opening the document to edit or delete. Any Ideas? Note that this class has other styles within it and I just want to remove the left:0; aspect ONLY leaving the rest intact.
An element's style attribute can override its CSS class properties. left: auto will also reset the left property of an element to the default value.
An element's style can be set like this in Javascript:
Element.style.[CSS property] = [value]
<span id="someId">Span</span>
<script>
document.getElementById("someId").style.color = "#aeb";
</script>
Its jQuery equivalent is (for one CSS property):
$([selector]).css([CSS property], [value]);
$('#someId').css("color", "#aeb");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="someId">Span</span>
For many CSS properties:
$([selector]).css({[CSS property]: [value], [CSS property]: [value]});
$('#someId').css({"color":"red", "font-size":"1.5em", "position":"absolute", "top": "25%", "left": "25%"});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="someId">Span</span>
<style>
.className {
left: 0;
position: absolute;
}
</style>
<span class="className">Span.className</span><br/>
<span class="className">Span.className</span><br/>
<span class="className">Span.className</span><br/>
<span class="className">Span.className</span><br/>
<span class="className">Span.className</span><br/>
<span style="left: 0; position: absolute;">Span with left:0 and position:absolute</span>
<script>
var elems = document.getElementsByClassName("className");
for(let i = 0; i < elems.length; i++){
elems[i].style.left = "50px";
}
</script>
To overwrite all previous set CSS properties of an element, you can use all: initial, setting all CSS properties to its initial value.
<style>
.someClass{
position: fixed;
color: red;
background-color: dodgerblue;
font-size: 3em;
margin: 20px;
}
</style>
<span class="someClass">Span.someClass</span>
<span class="someClass" style="all: initial;">Span.someClass all:initial</span>
left:auto;
Auto will reset the left attribute to the browser's default for the page :)
possible / similar duplicate:
How to remove Left property when position: absolute?
Using jquery you should be able to simply do this:
$('.className').css({'left': 'auto'});
Or, if the class isn't really all that important anyways, you could just remove it like this:
$('.className').removeClass('className');
You could override it with another value either in CSS, or using the same jQuery thing mentioned in the first part of my answer.
Here are two different approaches.
1. Replace/Remove the class
If that is the only style attribute in that class, you could remove the class from all elements that use it.
Example with jQuery:
$(".className").removeClass("className").addClass("anotherClass");
2. Override the attribute
The default value for left in CSS is auto, so you could override the CSS for all of those elements.
Example with jQuery:
$(".className").css("left", "auto");
Try like this:
$('.className').remove();
Since it has a value, making the value blank will make it so it doesn't count as any value and the css attribute will be skipped/ignored.
Solution:
$('.className').css('left',' ');
If the attribute still gets read as 0 then you will have to apply the !important to the .css(); to override it.

Retrieve CSS value, not inline-style value

In Javascript, can I retrieve the CSS values of an element without taking account of its inline style?
example:
body { font-size: 15px; }
<body style="font-size: 20px;">
Is there a way I can retrieve "15px" and not "20px"?
Yes, of course! Just get rid of the style attribute, use getComputedStyle(), and add the style attribute back:
//Get the body's style attribute:
var bodyStyle = document.body.getAttribute("style");
//Now, get rid of it:
document.body.removeAttribute("style");
//Now use getComputedStyle() to compute the font size of the body and output it to the screen:
document.write( getComputedStyle(document.body).fontSize );
//Now add the style attribute back:
document.body.setAttribute("style", bodyStyle);
body { font-size: 15px; }
<body style="font-size: 20px;">
</body>
var a = document.getElementsByTagName('body');
console.log (a[0].attributes.style); // returns the current inline style
a[0].setAttribute('style','font-size : 15px'); // change it as required

Apply JQuery to div's clicked

I am working on making a number list with each number on its individual div. So far I am able to remove the div with Javascript (on click), but I would like to enable JQuery so that I am able to add a class to a div and then remove all divs of that class with a button or something like that.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=203">
<title>Lista Mundial</title>
<style>
.divContainer {
width: 35px;
height: 25px;
border: solid 1px #c0c0c0;
background-color: #e1e1e1;
font-family: verdana;
float: left;
}
.text {
font-size: 15px;
font-family: verdana;
color: black;
margin-top: 4px;
}
h4 {
font-family: Verdana;
color: black;
text-decoration: none;
}
</style>
</head>
<body>
<h4>Double click para borrar un numero</h4>
<script type="text/javascript">
for(var i = 1; i <= 639; i++){
var divTag = document.createElement("div");
divTag.id = i;
divTag.className = "divContainer";
document.body.appendChild(divTag);
divTag.ondblclick = function(){this.parentNode.removeChild(this)};
var pTg = document.createElement("p");
pTg.setAttribute("align", "center");
pTg.className = "text";
pTg.innerHTML = (i);
document.getElementById(i).appendChild(pTg);
}
</script>
</body>
</html>
http://jsfiddle.net/ramonfabrega/AZSy8/
For simplicity, I just tried hiding the div's clicked, but JQuery does not seem to work. So something must be off.
Two issues:
1) jQuery wasn't loaded.
2) You were trying to bind the click event on an invalid selector (divTag instead of div)
Here's an updated fiddle: http://jsfiddle.net/LFC3A/2/
Regarding #2 - jQuery allows you to select an element multiple ways. The most common is to use a selector. The majority of selectors jQuery supports are from CSS 1 - 3, though jQuery supports some of its own custom selectors (such as div:eq, div:gt, and so on...) Check out the selectors page here: http://api.jquery.com/category/selectors/
Now, if your markup was:
<body>
<divTag>My Custom Div Tag</divTag>
<div>My regular DIV</div>
</body>
Then your original fiddle would have worked. In fact, here's an updated fiddle demonstrating that: http://jsfiddle.net/FpMAw/ (I updated your createElement to return a custom element, divTag)
The other way of accessing jQuery is by passing it a DOM element. Something like:
var $body = $(document.body) is equivalent to var $body = $('body')
If you reference that, you now have a jQuery object with a bunch of useful helper methods. So, in our previous example, we can now do:
$body.css('color', 'red')
Hopefully this helps explain a bit more why it didn't work. If you have any other questions, feel free to ask :)
Fiddle Demo
you are not including jQuery library in the fiddle
change $('divTag') to $('div')
Read $( "element" )
$(document).ready(function () {
$('div').click(function () {
$(this).hide();
});
});
Start Learning
jQuery API Documentation
This will create and add a click handler at the same time.
$('<div>').click(function(e){ this.addClass('active');})

The CSS input[value=whatever] selector doesn't seem to match against input.value. What am I missing?

N.B.: I should note that the proper solution to this is to just use the 'placeholder' attribute of an input, but the question still stands.
Another N.B.: Since, as Quentin explains below, the "value" attribute stores the default value, and the input.value IDL attribute stores the current value, the JavaScript I used to "fix" the problem in my below example is non-conforming, as it uses the (non-IDL) value attribute to store current, rather than default, values. Besides, it involves DOM access on every key press, so it was always just a flawed demo of the problem I was having. It's actually quite terrible code and shouldn't be used ever.
CSS selectors made me think that I could make an input with a label that acts as a preview without any JS. I absolutely position the input at 0,0 inside the label (which is displayed as an inline-block) and give it a background of "none", but only if it's got a value of "" and isn't focussed, otherwise it has a background colour, which obscures the label text.
The HTML5 spec says that input.value reflects the current value of an input, but even though input.value updates as you type into an input, CSS using the input[value=somestring] selector applies based only on what was explicitly typed into the document, or set in the DOM by the JavaScript setAttribute method (and perhaps by other DOM-altering means).
I made a jsFiddle representing this.
Just in case that is down, here is an HTML document containing the relevant code:
<!doctype html>
<head>
<meta charset="utf-8" />
<title>The CSS Attribute selector behaves all funny</title>
<style>
label {
display: inline-block;
height: 25px;
line-height: 25px;
position: relative;
text-indent: 5px;
min-width: 120px;
}
label input[value=""] {
background: none;
}
label input, label input:focus {
background: #fff;
border: 1px solid #666;
height: 23px;
left: 0px;
padding: 0px;
position: absolute;
text-indent: 5px;
width: 100%;
}
</style>
</head>
<body>
<form method="post">
<p><label>name <input required value=""></label></p>
</form>
<p><button id="js-fixThis">JS PLEASE MAKE IT BETTER</button></p>
<script>
var inputs = document.getElementsByTagName('input');
var jsFixOn = false;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].parentNode.tagName == 'LABEL') { //only inputs inside a label counts as preview inputs according to my CSS
var input = inputs[i];
inputs[i].onkeyup= function () {
if (jsFixOn) input.setAttribute('value', input.value);
};
}
}
document.getElementById('js-fixThis').onclick = function () {
if (jsFixOn) {
this.innerHTML = 'JS PLEASE MAKE IT BETTER';
jsFixOn = false;
} else {
this.innerHTML = 'No, actually, break it again for a moment.';
jsFixOn = true;
}
};
</script>
</body>
</html>
I could be missing something, but I don't know what.
The value attribute sets the default value for the field.
The value property sets the current value for the field. Typing in the field also sets the current value.
Updating the current value does not change the value attribute.
Attribute selectors only match on attribute values.
There are new pseudo classes for matching a number of properties of an input element
:valid
:invalid
:in-range
:out-of-range
:required
A required element with no value set to it will match against :invalid. If you insist on using the value instead of placeholder, you could simply add a pattern or a customValidity function to force your initial value to be counted as invalid.

Categories

Resources