I am loading the below function in a empty HTML document ::
setTimeout(function() {
(function test(){
var elem = document.createElement('div');
body = document.body;
body.appendChild(elem);
var
rule = "lalalalallalaallllllllllllllaaaaaaaaaaaaaaa" ,
mod = 'Alex-z',
style = ['','<style id="s', mod, '">', rule, '</style>'].join('');
console.log(style);
elem.innerHTML += style;
})();
}, 2500);
Now I have a question, no matter how big rule is, I never see any text in the browser, why ? Can somebody explain, a very similar snippet is used in a JS feature detection library, called modenizer, so I would really be interested in knowing why nothing is showing up in my browser?
Because <style></style> is by default hidden in the browser and it is set display:none if you inspect element. It's because you wouldn't want your declared styles being showed in the browsers right?
I really don't know what you're going to do, but if you want to see your styles generated on that JS then use :
div style {
display: block;
}
You don't see any text in the browser because your output is:
"
<style id="sAlex-z">lalalalallalaallllllllllllllaaaaaaaaaaaaaaa</style>"
is the soft hyphen symbol and will be converted into the HTML name, which is and the result is not visible (http://www.ascii.cl/htmlcodes.htm)
The rest is just a <style> element, used only to set CSS rules and by default browser set style { display: none; }, so it's not visible.
a very similar sinppet is used in a JS feature detection library
called Modernizr
Yes, Modernizr use this kind of snippets to detect some features, because in most cases needs to create an empty element and try to set the property we are trying to test. Eg:
tests['textshadow'] = function() {
return document.createElement('div').style.textShadow === '';
}
Related
I have an HTML document with a link tag in its head to a particular CSS stylesheet:
<link rel="stylesheet" href="style.css" type="text/css">
This .css file contains a particular class, like so:
.mystyle {
color: #00c;
}
What I'm trying to do is to grab that class's color field, so that I can use it dynamically in another part of the page (for another element's background-color). Is there any way in a JavaScript program to access that information, by the name of the class? Something like this:
var myColor = document.getStyle(".mystyle").color;
Some caveats:
There may or may not be other stylesheets that are also linked from this HTML document.
There may or may not be any particular elements on the page that are styled with this particular class.
I've already tried setting a temporary element to have the given class, and then grabbing its color field. That didn't work: the color field contains the empty string.
Thanks.
You can get all stylesheet information using the StyleSheetList and related objects.
In the example below, I aggregate all the document's styles (i.e., inline styles, an external bootstrap stylesheet and the stylesheet provided by Stackoverflow), and retrieve the color information for the .mystyle class:
const sheets = [...document.styleSheets];
const rules = sheets.reduce((a, v) => [...a, ...v.cssRules || []], []);
const rule = rules.find(r => r.selectorText === '.mystyle');
console.log(rule.style.color);
.mystyle {
color: #00c;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
It's possible to use JavaScript to read the actual CSS files themselves by scraping the DOM and extracting the relevant information. While possible, it's clunky, and I'd advise against that unless absolutely necessary. If it's required, this answer covers it pretty well.
As an alternative to scraping the header information, you could use HTMLElement.style and grab the color value, though note that this will only work for inline styles:
var span1 = document.getElementsByTagName('span')[0];
var span2 = document.getElementsByTagName('span')[1];
// Empty
console.log(span1.style.color);
// Blue
console.log(span2.style.color);
.mystyle {
color: #00c;
}
<span class="mystyle">Text</span>
<span style="color: #00c;">Text</span>
However, a much better solution would be making use of what are known as CSS variables. These are defined in :root with a double hyphen prefix, and can be referenced with var(). This allows you to only set a colour once, and re-use it for both a color property and a background-color property, as can be seen in the following:
:root {
--colour: #00c;
}
.a {
color: var(--colour);
}
.b {
background-color: var(--colour);
}
<span class="a">Text</span>
<span class="b">Text</span>
Hope this helps! :)
Try window.getComputedStyle in combination with getPropertyValue.
var elem = document.getElementsByClassName("mystyle");
var theCSSprop = window.getComputedStyle(elem,null).getPropertyValue("color");
More: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
For any who might come after me:
One can indeed use window.getComputedStyle(element) on an element. However, creating your own element first (if one doesn't exist) comes with an important caveat. Firefox will properly calculate the computed style. However, Chrome (and possibly Safari too) won't calculate the style of an orphaned element that isn't part of the DOM tree. So if you go that route, be sure to add it to the tree somewhere, possibly as a hidden element.
I want to change the design of my site by changing the CSS file attached. I have tried with script when the link is with id "link"
var x = document.getElementByID ("link")
X.href = style2
It didn't work.
The other thing I tried was to hide the <link> tag which had class "linkclass"
<style>
link.linkclass {
visibility:hidden;
}
</style>
But it didn't work either.
Can someone help.
Sorry if the code is bad formatted but I can't get how to format code in stack overflow
Three things wrong with this:
javascript is case sensitive. That means X is a different variable than x
style2 is not a valid URL. You have to use an URL to an existing .css file
<link> is not a visible element. Hiding an element that isn't visible in the first place accomplishes nothing.
This works:
var x = document.getElementByID("link");
x.href = "http://url/to/your/style2.css";
// ^ notice the lowercase x
If you wanna hide element (I got that impression from your examples), your javascript code should look like this:
var x = document.getElementById("link");
x.style.display = 'none';
Also take care with following:
-uppercase letters getElementbyId
-you're missing semicolon (;) after first expression
-your variable "x" is uppercase in second row("X").
In most cases this should be enough to disable element with CSS, just add this class (linkclass) to element which you want to hide:
<style>
.linkclass {
display: none;
}
</style>
You could do
$("#link").disabled = true;
This may also work.
document.getElementByID("link").disabled = true;
There is also another Stack question that addresses this here. Removing or Replacing a Stykesheet
update
You say you are trying to change the stylesheet. You could create a function to do it like this.
function styleSheetSwitcher( newFile ){
$("#link").prop("href", newFile);
}
styleSheetSwitcher("myNewCss.css");
I have been long battling this, and I would like to know if any others have feedback. I am about to make a customized library for building web apps quickly, and I want to make sure I use the right approach. I WANT to use this method:
$.fn.someSlider = function(){
var coreStyle = '.slider ul { white-space: nowrap; } .slider ul li {display: inline-block}', coreStyleTemplate = '<style><\/style>';
}
But I feel like hard coding the base CSS into the widget is always frowned upon - instead I see SO users recommending the use of CSS style rules instead of this option. I really really really want that 'it just works' feel, and having to force my users to use a separate style sheet just to get my plugins working... well is annoying!
Just to clarify: I would like to include all base style rules needed for the widgets proper/base functionality to be included inside the script. The user would easily modify the base look of the widget by writing a style rule in their own style sheet.
Example:
Instead of having to look through all the base styles trying to find the font color like this... .slider {display: inline-block; color: #000; someotherconfusingrule : blahblah; }
The user simply starts a new rule with the classes name/selector being used - and then just write the changes to make to the default script styles
They would just write
.slider {color: #000};
Thanks for the help in advance SO!
Nice question! Although I'm not sure what the preferred solution to this would be, I was thinking of the following approach:
Use a IIFE to define your jQuery plugin and enable you to define some private, global variables and functions.
$.fn.pluginName = (function() {
return function() {
...your regular plugins code...
};
}();
Define your plugins CSS as a list of style rules in your plugins code
var rules = [
'.box {' +
' width: 100px;' +
' background-color: #f99;' +
' margin: 10px;' +
' padding: 10px;' +
' font-family: Helvetica, Arial;' +
' text-align: center;' +
'}'
];
Create a private variable that remembers if your stylesheet has already been added to the document
var styleSheetExists = false;
Create a private function that creates a stylesheet using the style rules above and that adds it as the first <style> element in the <head> allowing the user to override styles in their own CSS. See http://davidwalsh.name/add-rules-stylesheets for a good tutorial on how to do this properly
var createStyleSheet = function() {
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
$('head').prepend(style);
for (var i = 0; i < rules.length; i++) {
style.sheet.insertRule(rules[i], i);
}
};
The first time your plugin is applied to an element check if the stylesheet has already been created and if not create the stylesheet.
var $elements = $(this);
if (!styleSheetExists) {
createStyleSheet();
styleSheetExists = true;
}
$elements.each(function() {
$(this).addClass('box');
});
return $elements;
See http://codepen.io/ckuijjer/pen/FkgsJ for this example. It creates a jQuery plugin called box which simply adds the class box to an element. The class box has a default pink background color defined in its stylesheet which gets overridden by a user defined blue background color.
But please do make this configurable in your jQuery plugin. You want to enable developers to bundle all their css, including your plugins, to optimize resource delivery to the client. Plus injecting stylesheets might be a small performance hit.
It may seem annoying but separating the model, view, and controller is the correct way. You're using jQuery so why not consider how jQuery would approach the situation: a jQuery UI widget like the Accordion comes with several stylesheets, the most important being the base stylesheet and a separate 'theme' stylesheet that (if done correctly) is nondestructive and can be modified without risking the integrity of the widget. You may also want to consider how your favorite plugins are authored and what makes them appeal to you. It's my personal opinion CSS should never be present in JavaScript files however if you've made up your mind, the solution #ckuijjer provided is sound. Hope this helps!
I'm not sure why, but I can't seem to get this to work.
Here is my function to enlarge my font.
<script type="text/javascript">
function growText() {
var text = document.getElementById("t_left_text");
text.font-size=22px;
</script>
And here is where I call it
<div id="t_left" onclick="growText()">
<br />
<p id="t_left_text">Mountains are beautiful land structures <br /> that are a result of plate tectonics.</p>
<br />
</div>
Try:
text.style.fontSize = "22px";
DEMO: http://jsfiddle.net/C2MWN/
When you want to change an element's CSS, you need to use the style property. To determine the name of the specific style property, the CSS name is converted to camel case - "font-size" becomes "fontSize", so that the identifier is valid in JavaScript.
While setting the style properties definitely works, and although this is a very simple example, it might be easier to deal with adding and removing a class. This is especially useful when setting multiple CSS properties. The class could be defined as:
.enlarged-font {
font-size: 22px;
}
And you would manipulate the text.className property (and/or the classList property).
Depending on the browser you're using, you could have easily provided a better description (as obvious as it was for some of us) of the problem by using the JavaScript console in the browser. In Firefox, you could use Firebug. In Internet Explorer and Chrome, you could use Developer Tools. If installed/enabled, these can usually be brought up by pressing the F12 on your keyboard.
Also, don't forget to close your function with a }.
Reference:
style property: https://developer.mozilla.org/en-US/docs/DOM/element.style
classList property: https://developer.mozilla.org/en-US/docs/DOM/element.classList
Use below code
function growText() {
var text = document.getElementById("t_left_text");
text.style.fontSize ="22px";
}
Working example http://jsfiddle.net/D2anZ/
Here's a version that uses CSS to accomplish what you want. That way if you want to do this to different sets of text at the same time, and want to change that font size, there's only one place you need to make the change. (Or if you also want to add other css properties (color, etc.)
Fiddle
JavaScript
function growText() {
var text = document.getElementById("t_left_text");
text.className = 'large-font';
}
CSS
.large-font {
font-size: 22px;
}
I have a form in which I want to edit a HTML template. It has 2 textareas, one for the HTML and another one for the CSS.
I'd like to use either TinyMCE or CKEditor for the HTML textarea.
Is there any way to change the content CSS in either of them to match the CSS in the CSS textarea on the run, so when I change the CSS it is automatically loaded into the editor?
Thanks.
I have no experience with CKEditor, but i know that it is possible with TinyMce. What you need to do is to write an own plugin which will provide the necessary functionality.
OnNodeChange in the 2nd textarea (the one with your css) you need to update the head of the first editors iframe. This code snippet to be executed on a special action (for example onNodeChange) should point you into the right direction:
var DEBUG = false;
var css_code = tinymce.editors[1].getContent(); // get content of 2nd editorinstance on page (your css)
iframe_id = tinymce.editors[0].id+'_ifr';
with(document.getElementById(iframe_id).contentWindow){
var h=document.getElementsByTagName("head");
if (!h.length) {
if (DEBUG) console.log('length of h is null');
return;
}
var newStyleSheet=document.createElement("style");
newStyleSheet.type="text/css";
h[0].appendChild(newStyleSheet);
try{
if (typeof newStyleSheet.styleSheet !== "undefined") {
newStyleSheet.styleSheet.cssText = css_code;
}
else {
newStyleSheet.appendChild(document.createTextNode(css_code));
newStyleSheet.innerHTML=css_code;
}
}
Be aware that this code will add a new style sheet everytime it is called - yielding in increasing the editor iframes head. So i think best practice is to clean up the last inserted style before appliing the new one. Removing the last Node of the head shozld be sufficient.