CSS switcher - looking for more seamless implementation - javascript

I'm using a JS CSS switcher to good effect really brilliant. However, I would be delighted if it worked more seamlessly. At the point of opening a new page on the site the default css style often flickers on breifly, before the cookie re-applies the selected CSS style.
e.g. the canvas style is the default style, this opens when first visiting the site, user selects corporate style, they open another page in the site - the canvas style shows for a split second, then the corporate style loads over it. Worse on older computers, but on my main computer this does not often happen on Firefox, although on other browsers, especially Chrome its very noticeable. Does anyone have the expertise to update the workings below with a tweak to say, first check for the cookie, then if no cookie, apply the default style, rather than applying the default style seemingly at the same time?
the code I am using is here below:
in html head:
<script type="text/javascript">
$(function()
{
// Call stylesheet init so that all stylesheet changing functions
// will work.
$.stylesheetInit();
// This code loops through the stylesheets when you click the link with
// an ID of "toggler" below.
$('#toggler').bind(
'click',
function(e)
{
$.switcher();
return false;
}
);
// When one of the styleswitch links is clicked then switch the stylesheet to
// the one matching the value of that links rel attribute.
$('.styleswitch').bind(
'click',
function(e)
{
$.stylesheetSwitch(this.getAttribute('rel'));
return false;
}
);
}
);
</script>
<link rel="stylesheet" type="text/css" href="/css/canvas.css " title="canvas">
<link rel="alternate stylesheet" type="text/css" href="/css/corporate.css " title="corporate">
<link rel="alternate stylesheet" type="text/css" href="/css/earth.css " title="earth">
<link rel="alternate stylesheet" type="text/css" href="/css/space-and-stars.css " title="space-and-stars">
<link rel="alternate stylesheet" type="text/css" href="/css/under-the-sea.css " title="under-the-sea">
<link rel="alternate stylesheet" type="text/css" href="/css/classical.css " title="classical">
<link rel="alternate stylesheet" type="text/css" href="/css/creative.css " title="creative">
the JS
(function($)
{
// Local vars for toggle
var availableStylesheets = [];
var activeStylesheetIndex = 0;
// To loop through available stylesheets
$.switcher = function()
{
activeStylesheetIndex ++;
activeStylesheetIndex %= availableStylesheets.length;
$.stylesheetSwitch(availableStylesheets[activeStylesheetIndex]);
};
// To switch to a specific named stylesheet
$.stylesheetSwitch = function(styleName)
{
$('link[#rel*=style][title]').each(
function(i)
{
this.disabled = true;
if (this.getAttribute('title') == styleName) {
this.disabled = false;
activeStylesheetIndex = i;
}
}
);
createCookie('style', styleName, 365);
};
// To initialise the stylesheet with it's
$.stylesheetInit = function()
{
$('link[rel*=style][title]').each(
function(i)
{
availableStylesheets.push(this.getAttribute('title'));
}
);
var c = readCookie('style');
if (c) {
$.stylesheetSwitch(c);
}
};
}
)(jQuery);
// cookie functions http://www.quirksmode.org/js/cookies.html
function createCookie(name,value,days)
{
if (days)
{
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name)
{
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++)
{
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name)
{
createCookie(name,"",-1);
}
// /cookie functions

I would do it server-side...
Anyway, when you do
$(function()
{
});
jQuery waits until the DOM is fully load to execute the function.
So, you should place the javascript just below the <link />s section, outside $(function(){}); . This will make the script as soon as the browsers parses it, and before the page is fully loaded. (it has to be below the elements because they must be loaded)

I think you might wish to run your code before the DOM is ready. Perhaps you could run it immediately rather than using $(function(){...}), since jQuery waits until the page loads to execute anything in that (hence the flicker).
Also perhaps this might give insight.
http://forum.jquery.com/topic/use-jquery-before-the-dom-is-ready-12-1-2010
Debugging steps for why links are not working:
>>> $('link[#rel*=style][title]') --> seems to show your styles are there
[..., <link rel=​"alternate stylesheet" type=​"text/​css" href=​"/​css/​corporate.css " title=​"corporate">, ...]
>>> $.stylesheetSwitch('corporate') --> seems to work
The only problem is that the links are not having anything bound to the onclick; wait... don't you mean this.getAttribute('title')? as you can see above, rel="alternate stylesheet" which is probably not your intent to use as a unique theme identifier.

Related

Preloading CSS still results in render blocking sources

Im trying to preload some CSS in the following way
Inside the Head Tag:
<link rel="preload" href="css/layout.css" as="style">
Script at the bottom of the Body Tag (Don't think it matters where its placed anyway...)
<script>
var rels = document.querySelectorAll( 'link[rel="preload"]' );
function loadCSS(){
for( var i = 0; i < rels.length; i++ ){
if( rels[i].as !== undefined && rels[i].as === 'style' ){
rels[i].rel = 'stylesheet';
continue;
}
//IE fix
if( rels[i].as === undefined && /(css)/i.test(rels[i].href)) rels[i].rel = 'stylesheet';
}
}
window.onload = function () {
loadCSS();
};
however, if i invoke the onload event in the following way:
<link rel="preload" href="css/layout.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
It's not Render-Blocking, however not supported in IE.
What am i missing?
//On window load
window.onload = function ()
{
//Get the link tag using the ID
var $style = document.getElementById('mycss');
//Now you can add, remove or change its attribute,
$style.rel='stylesheet';
//$style.href='';
};
<html>
<head>
<!-- Put a unique ID to your link tag -->
<link rel="preload" href="css/layout.css" as="style" id="mycss" />
</head>
<body>
</body>
</html>

How to print webpages with iframe and css

I have to print the contents of a dialog. I'm adding a empty iframe then i add contents to it in javascript.
this is my js code where i add html and css as children of iframe
var layoutCSS = new String('<link href="css/ReportPageOne.css" rel="stylesheet" type="text/css">');
var pageOneCSS = new String('<link href="css/ReportLayout.css" rel="stylesheet" type="text/css">');
var pageTwoCSS = new String('<link href="css/ReportPageTwo.css" rel="stylesheet" type="text/css">');
var materialityCSS = new String('<link href="css/MaterialityMatrix.css" rel="stylesheet" type="text/css">');
window.frames.print_frame.document.head.innerHTML = layoutCSS + pageOneCSS + pageTwoCSS + materialityCSS;
window.frames.print_frame.document.body.innerHTML = $('#__dialog1-cont').html();
window.frames.print_frame.window.focus();
window.frames.print_frame.window.print();
opens the print dialog properly but css is not applied quite well.
On print page in options i checked in 'Background graphichs' and i am using google chrome.
You are calling frame.print() before the styles have loaded.
"The load event fires once the stylesheet and all of its imported content has been loaded and parsed, and immediately before the styles start being applied to the content."
Try this:
head.lastChild.addEventListener("load", function (event) {
// In IE, you have to focus() the Iframe prior to printing
// or else the top-level page will print instead
frame.focus();
frame.print();
}, 0);
References
https://github.com/abbotto/teleprint/blob/master/src/components/print.js
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#Stylesheet_load_events

How to load js/css files in custom popup load

In my project i am displaying a custom pop up page like below by javascript which has a form for user to fill,then I need to load some js files when pop up is loaded.
how to load js files,plz help.
<html>
<head>
<script type='text/javascript' src='files/jsfiles/core.js'></script>
</head>
<body>
<!- I need to call javascript function showUsers() from here->
<input type='button' onclick='showUsers();' value='listUsers'>
</body>
</html>
function loadScript(src) {
var script = document.createElement("script");
script.async = false;
script.src = src;
document.head.appendChild(script);
};
function loadStyle(src) {
var style = document.createElement("link");
style.rel = "stylesheet";
style.href = src;
document.head.appendChild(style);
};
function loadFiles() {
var scriptsArray = ['src1url', 'src2url'.., 'scrnurl'];
var csssArray = ['src1url', 'src2url'.., 'scrnurl'];
for (var i = 0; i < scriptsArray.length; i++) {
loadScript(scriptsArray[i]);
}
for (var i = 0; i < csssArray.length; i++) {
loadStyle(csssArray[i]);
}
};
function yoursubmitFcn(callback) {
// your functionality here;
callback();
}
$(document).ready(function () {
// do your stuff
yoursubmitFcn(loadFiles);
});
Also check: Another short form
You can use this library fancybox
Loading jQuery from CDN
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="/fancybox/jquery.fancybox-1.3.4.pack.js"></script>
<link rel="stylesheet" href="/fancybox/jquery.fancybox-1.3.4.css" type="text/css"
media="screen" />
html
Sign in
JS
$('.open_pop').fancybox({
});
function openmsg_sent() {
jQuery(".open_pop").trigger("click");
}
For better and consistent UI, you can use a div which you can display with fixed positioning on click of the button.
I believe Alert wont be able to display css properties if am not wrong.
What you can do is, onclick of the button, in the JS, you can put your popup content into a div which is hidden initially and shown on click.
Hope this helps.

Target link href="" with jQuery

I am trying to target following with jQuery:
<link rel="stylesheet" href="css/test.css">
What I cannot figure out is how to set default path (css folder) ?
<button data-button="test">Just a Test</button>
<script>
var button = $('button'),
link = $('link'),
stylesheet = $(this).data('button');
button.on('click', function() {
console.log(this);
link.attr('href', stylesheet + '.css');
});
</script>
Right now this would change css on button click only if css is in root... So how do I tell him that CSS default path is at "css/".
Trying to find without success.
P.S. One question releated to JS but not to question title.
What is more perferred and correct:
var $something = $('#something');
or
var something = $('#something');
As easy as this
link.attr('href', 'css/' + stylesheet + '.css');
If you want to switch stylesheet, you should use alternate stylesheets instead.
<link rel="alternate stylesheet" href="css/test1.css">
<link rel="alternate stylesheet" href="css/test2.css" disabled>
In jQuery you can then remove/add the disabled property to switch stylesheets:
var links = $("link[rel='alternate stylesheet']");
var button = $("button");
button.on('click', function() {
links.filter(":disabled").prop("disabled", false).siblings().prop("disabled", true);
});
Why don't you simply mention the path css/ in the code itself
link.attr('href', 'css/'+stylesheet + '.css');
To answer to your other question,
var $something and var something are both valid variable names. Your pick.

How to use jQuery (or similar) to extract all of the CSS

Given a web page that has loaded (possibly several) CSS files, and inline styles, through the use of:
<link rel="stylesheet" type="text/css" href="some_file.css" />
<style type="text/css"> /* some css rules */ </style>
<link rel="stylesheet" type="text/css" href="some_other_file.css" />
<style type="text/css"> /* some other css rules */ </style>
<!-- etc -->
How would one go about writing a function (possibly with jQuery) to extract all the net CSS rules in effect?
I am not sure what you want to do with this, but this should get you started:
function getStyles() {
if(!document.styleSheets) return false; // return false if browser sucks
var rules = new Array();
for (var i=0; i < document.styleSheets.length; i++) {
var x = 0;
styleSheet = document.styleSheets[i];
if(styleSheet.cssText) { // if this is IE, get the rules directly
rules.push(styleSheet.cssText);
} else {
// otherwise get them individually
do {
cssRule = styleSheet.cssRules[x];
if(cssRule) rules.push(cssRule.cssText);
x++;
} while (cssRule);
}
}
return rules;
}
When you call this it will return an array of all the rules. Tested in Firefox, IE.

Categories