I'm using Cufon to replace the font used for multiple elements. The syntax I have is this:
<script type="text/javascript">
Cufon.replace('h1.elementClassName, h2.newElementClassName, div#confirmationElementClassNameAndMore, h5.otherClassBlaBlaBla');
</script>
Apparently, it needs to be all on 1 line, otherwise it just doesn't work. But it becomes difficult to read as I add more elements to the list.
I've also seen the syntax below somewhere, but I was not sure, if declaring the REPLACE multiple times would slow down the loading:
<script type="text/javascript">
Cufon.replace('h1.elementClassName');
Cufon.replace('h2.newElementClassName');
Cufon.replace('div#confirmationElementClassNameAndMore');
Cufon.replace('h5.otherClassBlaBlaBla');
</script>
Will it affect speed or is it safe to use.?
Or is there another syntax that helps with visibility.?
There is no need to use cufon now, most of the browsers are able to render custom fonts using CSS only. Take a look here http://www.fontsquirrel.com/fontface/generator. Fontsquirrel can convert you font for all browsers and will generate CSS for you.
Font-face is inconsistent across browsers - you have to tweak margins to get a consistent result. Some fonts, when in small size, may also render really wrong.
This is the syntax to select more than one element with Cufon:
<script type="text/javascript">
Cufon.replace('h1, h2, h3', {fontFamily: 'FontName'});
</script>
Related
I'm using the CSS content attribute to pass some values from my LESS stylesheet to JavaScript (to use some colors defined in LESS in Canvas elements).
To make my life easier I decided to place these values in a easy way to parse them in JavaScript.
LESS code:
div#colorChart-critical {
content:'#{critical-highest},#{critical-veryhigh},#{critical-high},#{critical-low},#{critical-medium},#{critical-verylow}';
}
which when compiled brings the following CSS:
div#colorChart-critical6 {
content: '#ff0000,#ff7200,#fffc00,#0000ff,#a200ff,#00ff00';
}
Then I try to read them using jQuery:
$("div#colorChart-critical").css("content").split(",");
The problem is that in IE9 calling $("div#colorChart-critical").css("content") is returning the string "normal" for some reason. Opera, Firefox, Safari and Chrome works fine.
Why does this happen in IE9?
Any work-around this issue on IE9? If not any other CSS atribute I can put random texts in?
I could use something like:
background: url(#ff0000,#ff7200,#fffc00,#0000ff,#a200ff,#00ff00);
But this would generate errors on the console.
It's because content as defined in CSS2.1 doesn't work on elements, only on the :before and :after pseudo-elements. IE9 is simply following the CSS2.1 spec here, which mandates that content on elements be computed to normal, always.
I don't know why other browsers would return the value you have defined, especially considering that .css() makes use of getComputedStyle() on those browsers. If they're implementing CSS2.1 content, then they're violating CSS2.1 by not computing the value to normal. If they're preparing for a late CSS3 implementation, whatever that may be, then it would make sense that they implement it on actual elements somehow... shame on them either way.
Which brings me to another point: if you're not actually trying to use CSS to modify the content of an element, don't use content, even if the fact that it's not defined for use with elements is the reason you're making use of this technique in the first place. You can try assigning those colors to certain classes, creating a hidden element and querying that element's color styles instead.
BoltClock answer shows the cause of my problems. I found a work-around by using the font-family instead of the content CSS property.
My LESS code:
div#colorChart-maincolors {
font-family: '#{colorChart1},#{colorChart2},#{colorChart3},#{colorChart4},#{colorChart5},#{colorChart6}';
}
Which compiled into CSS gives:
div#colorChart-maincolors {
font-family: '#c0392b,#2980b9,#2ecc71,#f1c40f,#ecf0f1,#34495e';
}
The string can be acquired using:
removeQuotes= function(string) {
return string.replace(/^['"]+|\s+|\\|(;\s?})+|['"]$/g, '');
};
removeQuotes($("#colorChart-maincolors").css("font-family")); //add a .split(',') to get the colors as an array
The function removeQuotes is necessary because each browser adds a different kind of quotes into the return of getComputedStyle (and by extension the jQuery .css() method). IE9 adds a double quote, Webkit adds a single quote.
See this post on CSS tricks: http://css-tricks.com/making-sass-talk-to-javascript-with-json/ for more information.
you can use replace(/["']/g, "") to remove extra quotation from string
""string"" will be change to "string"
I would like to say
<html>
<body>
<mytag foo="bar">blah</mytag>
</body>
</html>
And define somewhere else how a <mytag> should behave. But for older browsers that do not play nicely with custom tags, I would like to just load a js library in the browser and have it automatically rewrite the above code as say
<html>
<body>
<div data-mytag data-foo="bar">blah</div>
</body>
</html>
Obviously this functionality could be hacked together in an hour, but I would prefer to use a tiny library that someone has written, for the sake of convention and possibly handy features. Do you know of one? Note: please don't reply about why I shouldn't use custom tags.
For the first part, maybe something like
<mytag>yo</mytag>
<script>
var map = {
MYTAG: function(s){
// surround content with stars
return '**'+s+'**';
}
}
Array.prototype.slice.call(document.getElementsByTagName('*')).forEach(function(tag){
// note on some IE versions you cant set innerHTML directly
if(map[tag.tagName]) tag.innerHTML = map[tag.tagName](tag.innerHTML);
})
</script>
For changing element tags at runtime, I can't recall if that's possible. People may cringe, but I'd maybe take the entire document.body.innerHTML replace it using regexes and reset it. If I knew I was the only creator of the HTML content that may take care of it..
We've got a little tool that I built where you can edit a jQuery template in one field and JSON data in another and then hit a button to see the results immediately within the browser.
I really need to expand this though so the designer can edit a full CSS stylesheet within another field and when we render the template, it will have the CSS applied to it. The idea being that once we've got good results we can take the contents of these three fields, put them in files and use them in our project.
I found the jQuery.cssRule plugin but it looks like it's basically abandoned (all the links go nowhere and there's been no development in three years). Is there something better or is it the only game in town?
Note: We're looking for something where someone types traditional CSS stylesheet data in here and that is used immediately for rendering within the page and that can be edited and changed at will with the old rules going away and new ones used in their stead. I'm not looking for something where the designer has to learn jQuery syntax and enter in individual .css("attribute", "value") type calls to jQuery.
Sure, just append a style tag to the head:
$("head").append("<style>p { color: blue; }</style>");
See it in action here.
You can replace the text in a dynamically added style tag using something like this:
$("head").append("<style id='dynamicStylesheet'></style>");
$("#dynamicStylesheet").text(newStyleTextGoesHere);
See this in action here.
The cleanest way to achieve this is by sandboxing your user-generated content into an <iframe>. This way, changes to the CSS won't affect the editor. (For example, input { display:none; } can't break your page.)
Just render out your HTML (including the CSS in the document's <head>, and write it into the <iframe>.
Example:
<iframe id="preview" src="about:blank">
var i = $('#preview')[0];
var doc = i.contentWindow || i.contentDocument;
if (doc.document) doc = doc.document;
doc.open('text/html',true);
doc.write('<!DOCTYPE html><html>...</html>');
doc.close();
If the user should be able to edit a whole stylesheet, not only single style attributes, then you can store the entered stylesheet in a temporary file and load it into your html document using
$('head').append('<link rel="stylesheet" href="temp.css" type="text/css" />');
sounds like you want to write an interpreter for the css? if it is entered by hand in text, then using it later would be as simple as copy and pasting it into a css file.
so if you have a textarea on your page to type in css and want to apply those rules when you press the button, you could use something like this (only pseudocode, needs work):
//for each css id in the text area
$.each($('textarea[name=cssTextArea]').html().split('#'), function({
//now get each property
$.each($(this).split(';'), function(){
$(elem).css({property:value});
});
});
then you could write something to go through each element that your designer typed in, and get the current css rules for it (including those that you applied using some code like the snippet above) and create a css string from that which could then be output or saved in a db. It's a pain and much faffing around with substrings but unfortunately I don't know of a faster or more efficient way.
Hope this atleast gives you some ideas
I have a two part question.
First, the scenario:
Due to some bizarre issues we've run into in regards to mobile browser support for NOSCRIPT, I'm tasked with coming up with an alternative solution to 'detect' JS. The solution logic is to have two DIVs on the page. One is an error stating you do not have JS and his shown by default. If one has JS, we then want to add a new STYLE block to the HEAD that over-rides the previous CSS and hides the error and instead shows the content.
The sample HTML:
<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
This is the JS I started with:
var styleNode = document.createElement('style');
styleNode.setAttribute("type", "text/css");
styleNode.innerHTML = "#div1 {display: block;} #div2 {display: none;}";
headTag.appendChild(styleNode);
But, I was having problems. Some googling resulting in this description of a security issue that IE can have if you try to insert innerHTML into a created element before placing it in the DOM:
http://karma.nucleuscms.org/item/101
So, I modified the script as such:
var styleNode = document.createElement('style');
styleNode.setAttribute("type", "text/css");
var headTag = document.getElementsByTagName("head")[0];
headTag.appendChild(styleNode);
var aStyleTags = headTag.getElementsByTagName("style");
var justAddedStyleTag = aStyleTags[aStyleTags.length-1];
justAddedStyleTag.innerHTML = "#div1 {display: block;} #div2 {display: none;}";
question 1: is that a valid workaround for the IE issue? Is there a more efficient solution?
question 2: even with the adjustment, the script still does not work in IE. It works fine in Firefox, but in IE 7 I get an "unknown runtime error".
I have a sample of this code up on JSBIN:
http://jsbin.com/ucesi4/4
Anyone know what's going on with IE?
UPDATE:
I stumbled upon this link via google. Note the last comment:
http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
That said, you really should put all
style rules in the HEAD for strict
compliance with XHTML. Doing this can
also be a little tricky because you
cannot use innerHTML to inject into
the HEAD or STYLE element directly.
(Both of these tags are READ ONLY.)
Eep! True? Is FireFox just being overly forgiving? Or is this just a very odd IE quirk?
UPDATE 2:
A bit more background on what we're trying to solve here. We're dealing with mobile devices and some of the antiquated devices a) don't support NOSCRIPT and b) have slow JS engines.
Since they don't support NOSCRIPT, we are by default showing an error, then hiding it via JS if they have it, and presenting them with the proper content. Because of the slow JS engines on these, people see the 'flicker' of the DIV's showing/hiding. This was the proposed solution to handle that, as it would load the CSS before the DIVs were even rendered.
Since it appears to be invalid, the solution will be that on these old devices, we'll use this method (as it seems to work, even if not in IE) and then all other proper browsers will do as suggested...we'll just update the DISPLAY CSS property via inline JS after each DIV is loaded in the DOM.
All that said, I'm still curious as to whether this issue is an IE bug, or if IE is actually adhering to the proper standards by making STYLE a read-only element.
In IE you can use style.styleSheet.cssText:
var style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) { // IE
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(style);
Try this here: http://jsfiddle.net/QqF77/
See the answer on this question: How to create a <style> tag with Javascript
Don't use innerHTML, use document.createTextNode() and your life will become infinitely better ;)
var styleNode = document.createElement('style');
styleNode.setAttribute("type", "text/css");
var textNode = document.createTextNode("#div1 {display: block;} #div2 {display: none;}");
styleNode.appendChild(textNode);
headTag.appendChild(styleNode);
EDIT:
Since this solution doesn't seem to work for you, I'd abandon it. Instead go for a solution where styles are already defined and where you just disabled/enable styles via javascript if available.
You can do it this way:
<head>
<style>
.jsenabled #div2, #div1 { display: none;}
.jsenabled #div1, #div2 { display: block;}
</style>
<script>
//i know you don't use jQuery, but the solution should still be valid as a concept
//bind to DOM-ready, then set the class jsenabled on the body tag
$(function() {
$(document.body).addClass('jsenabled');
});
</script>
</head>
<body>
<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
</body>
EDIT 2:
If it has to be done prior to DOM ready, you could do something kinda ugly like this:
<head>
<style>
#div2, .show { display: block;}
#div1, .hide { display: none;}
</style>
</head>
<body>
<div class="hide">
<script>document.write('</div><div id="div1">');</script>
div 1 (should be shown if JS enabled)
</div>
<script>document.write('<div class="hide">');</script>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
<script>document.write('</div>');</script>
</body>
Or to keep things simple, you could just do
<head>
<script>document.write('<style>#div1 {display: block;} #div2 {display: none;}</style>');
</head>
<body>
<div id="div1">div 1 (should be shown if JS enabled)</div>
<div id="div2">div 2 (should be hidden if JS enabled)</div>
</body>
Best practice is to put all the <link for CSS into the <head, and most <script at tne very end of the <body (except short fragments of <script that should execute ASAP should go in the <head). Both the standard and browsers allow you to do silly things, but just because it's acceptable doesn't mean it's a good idea.
Rather than go through all the rigamarole of creating a Style node and of manipulating the DOM (which just provide more opportunities for something to go wrong), I recommend a much simpler solution. Hard code as much as you can into your document (and style sheet?) in advance once (rather than creating things on the fly every time). Here's a rough example:
<body ...
...
<div id="warning" style="display: block;">
JS is required for this site, but isn't available ...
</div>
<div id="message" style="display: none;">
JS is available
</div>
...
<script ...
var warningEl = document.getElementById('warning');
warningEl.style.display = 'none';
var messageEl = document.getElementById('message');
messageEl.style.display = 'block';
</script ...
This should work reasonably well most of the time (it will certainly work in more browsers than what you tried to do initially). However, any attempt to change the DOM in any way before the page is initially displayed to the user is not guaranteed to work (in other words neither your way nor the example above will always work in all cases). The earlier you run your Javascript, the more likely DOM operations (including getElementById) may fail. And the later you run your Javascript, the more likely the user will notice a perceptible "flicker" of their display. So you're presented with a tradeoff choice between wide compatibility and noticeable flicker.
You can wait until the DOM is guaranteed to be fully ready before you run your Javascript ("ready" in jQuery, or addEventListener 'domcontextloaded', or even addEventListener 'load'). This is guaranteed to function correctly in all cases. But it will flicker (perhaps quite badly) in many cases.
The only way I know (but I hope somebody else knows more:-) to avoid entirely the possibility of flicker is to put in the <head a fragment of Javascript that changes window.location but does nothing else. (No references to the DOM, which are usually made obvious by the word "document" somewhere in the code.) The net effect if JS is available will be an immediate reload of a different page before much of anything is shown to the user. The initial page can contain your warning, and the new page the real stuff with no warning.
Even this method has some disadvantages though: First, the double download takes extra bandwidth and delays user visibility a little. This won't matter on typical desktops. But on handhelds it may not be acceptable. And second, it will raise havoc with SEO. The second page -that's supposed to be invisible and only accessed from the first page- may show up independently in webdexes so users can easily access it directly (you may be able to "fix" this with clever use of "canonical" and/or "meta...robots"). And the SERP of the initial page may fall precipitously when its only content is the warning message.
I tried some plugins but they all come with their own styling which takes quite some time to get rid of. Is there any plugin with minimal styling (or a really simple way) to apply custom background to select element? I just need something very simple.
Thanks
I found this one. It even degrades automatically if JavaScript is disabled.
http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/
With jQuery am using lines like this in my dom ready function :
$(".overlay").css("top","300px");
Goes like this in the header:
<script type="text/javascript">
jQuery(document).ready(function(){
$(".overlay").css("backgroundColor": "#0f0");
});
</script>
.overlay is the class of the div i wanna change and then comes the css property and its value.
Hope this helps.