Load different CSS stylesheet using JavaScript reading from URL variable - javascript

I am trying to have two different stylesheets on my wordpress blog, so that one stylesheet is used when the page is accessed via the web, and the other stylesheet is used when the blog content is accessed via our iOS app. Right now we are appending ?app=true to URL requests from our iOS app in hopes that in our blog we could search for this string and load a different stylesheet. We are using a JSON API plugin so that our iOS app can programmatically pull our blog posts and display them in a web view in the iOS App.
In my wordpress blog I am using JavaScript that looks for ?app=true in the URL, and if so, load a different stylesheet.
<script language="javascript" type="text/javascript">
var currentLocation = window.location.href;
if(currentLocation.indexOf('/?app=true') > -1) {
document.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"appstyle.css\" />");
}
</script>
You can take a look at http://blog.meetcody.com and view the page source. You will see this code snippet in-between the tags.
The issue that I'm having is that the above code doesn't actually load the appstyle.css stylesheet. If you take a look at http://blog.meetcody.com/wp-content/themes/standard/appstyle.css?ver=3.4.2 you can see that I'm testing this by setting the background: black in the body {} tag
body {
background: black;
}
Whereas, in style.css at http://blog.meetcody.com/wp-content/themes/standard/style.css?ver=3.4.2 the body background color is #F2F0EB; in the body {} tag
body {
background: #F2F0EB;
}
How can I pass a URL variable such as ?app=true and when that is passed, I load a different stylesheet?

I believe that the best way to approach your problem is to employ Responsive Web Design techniques. These allow you to address different resolutions appropriately.
The basic CSS looks something like the following...
#media screen and (min-width: 480px) {
// CSS for iPhone
}
#media screen and (min-width: 768px) {
// CSS for iPad
}
#media screen and (min-width: 900x) {
// CSS for desktop
}
The take-away is that you won't need to load different stylesheets for different platforms. You'll have one stylesheet that works in every situation. It can even work for platforms you haven't specifically targeted.
The team the built the new Boston Globe site were my introduction to RWD. Here's a breakdown of what they did.

I tried some things with the Firebug console on your site. So, what actually worked was the following code:
<script type="text/javascript">
if(window.location.href.indexOf('/?app=true') > -1) {
var fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", "http://blog.meetcody.com/wp-content/themes/standard/appstyle.css");
document.getElementsByTagName("head")[0].appendChild(fileref);
}
</script>
(This code was adapted from Dynamically loading an external JavaScript or CSS file).
Since your are loading other stylesheets and I guess you overwrite their rules, you have to load this stylesheet AFTER all the others. So put this code at the end of your document or in a window.onload event.

You could also sniff out the user-agent string. This way you wouldn't have to pass anything. In most cases I wouldn't recommend it usually but with such a specific case you can safely do it without a ton of code.
// Define what "webview" is
var is_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
// See if this user is coming from it
if (is_uiwebview = true) {
// Your code to make the <link> with a proper href
// Raul's would work perfectly
};
Again, as everyone else said make sure it loads things after your web-only stylesheet.
Also not entirely sure the = true is needed.

Related

How to run vbscript code at certain browser width

I'm turning a clients website into a responsive site and they have lots of vbscript in the content of their home page. At mobile widths they've stripped out a lot of content which means there's lots of code that's being executed but not displayed thanks to display:none
Is there a way to run vbscript code when you hit a minimum width of 768px?
I thought about using javascript to get the screen width and store it as a cookie and use vbscript to get the cookie to obtain the screen width:
<SCRIPT LANGUAGE="javascript">
var width = screen.width;
document.cookie = 'YourDomain=ScreenWidthB='+width;
</SCRIPT>
<%Dim ScreenWidth%>
<%ScreenWidth=request.cookies("YourDomain")("ScreenWidthB")%>
but I feel there may be a better solution out there. Also the code above gives me the width of my monitor I believe, not the width of the browser
This isn't something you would do with any server side language.
You can either use Bootstrap Grid System for this, which has a built-in grid system to handle responsive sizing.
or you can simply use CSS to define your styles for elements with-in a certain viewport size, using the CSS #media tag:
Your CSS would look like this example:
div {width:100px;}
#media (min-width:768px) {
div { width: 50px; }
}
What this does is makes all div's at 100px width, but when the browser is 768px or larger it changes the div sizing to 50px, as defined with-in the #media tag.
Therefore, you can use VBScript to generate the CSS script in the page, without having to write any javascript code. But Bootstrap may be your best bet to help build a responsive design easily/seamlessly. You may want to check it out.
EDIT: Since OP has clarified not to even load the content
You can make a cookie in javascript, and read it in your VBScript to check the viewport.
You can use jQuery for this:
$(window).resize(function(e){
var w = $(this).width();
if(w>768) document.cookie = "viewport=768;";
else document.cookie = "viewport=;";
});
This will bind an event listener on any time the user resizes the window, to check it's size, and if above 768px, it will write the cookie or empty if not.
Then check for the viewport cookie using Request.Cookies("viewport")
Or better yet since you're concerned about performance, you can use Ajax to build your page when a certain viewport size is hit.
Again, you can use jQuery for this and bind to the window resize event.
contentloaded = false;
$(window).resize(function(e){
var w = $(this).width();
if(w>768 && !contentloaded) {
$.get(url,function(data){
$("div").html(data);
contentloaded = true;
});
}
});
I would use ajax to do this, since I'd want to show the content without the user having to refresh the screen as you would have to by using the cookie solution.

What is the simplest method to preload CSS without applying it?

Problem
I have made a Bootstrap 3.2.0 site with multiple different pages. Every different page has it's own, whole bodywide backgrond image. I have now gone the simplest route by making different CSS-file bodycssforthispage.css for every page. bodycssforthispage.css only contains the following code, and by then overwrites Bootstraps original body definitions:
html,body {
height:100%;
background-color: #333;
background-image: url(../img/bg-image.jpg);
background-repeat:no-repeat;
background-size:cover;
background-position:center;
background-attachment: fixed;
}
Now what I want to do here, is to preload all other site related CSS-files, so that when I go for example from index.html to page1.html, all the are needed files (CSS-file for background and images) are already preloaded to browsers cache, and the transition to the next page is smooth. It is important to notice, that I want to preload the whole CSS-file(s) and it's contents.
Solution 1: preload all images and use different .css for each page
I could preload all images needed with JavaScript by placing this simple code to the bottom of my index page:
<script type="text/javascript">
if (document.images) {
img1 = new Image();
img1.src = "img/bg1.jpg";
img2 = new Image();
img2.src = "img/bg2.jpg";
}
</script>
</body>
</html>
and then just create bgforthisandthatpage.css for each different page, only containing:
html,body {
height:100%;
background-color: #777;
background-image: url(../img/bg-imageforthispage.jpg);
background-repeat:no-repeat;
background-size:cover;
background-position:center;
background-attachment: fixed;
}
Problems using this way
This would be the simple solution, but it includes many many different .css-files. Preloading 5-10 CSS-files should be done at the bottom of the page so, that the page itself loads smoothly (just like in Bootstrap with many other scripts).
It is come to my knowledge (correct if I'm wrong) that preloading whole CSS-files (i.e via JavaScript) may cause cascade styles to overwrite each other, so that the page would then use the most bottom CSS-file(s) data (bg-image ect. in my case).
In my opinion preloading many different CSS-files just for the changing background image is not quite convenient.
Solution 2: give every html/body element it's own class with different bg-image
Giving each page it's own class like this:
<html class="contactpage-bg-image">
and then create own class for each page into the original css-file like this:
html.contactpage-bg-image {
/* styling */
}
html.indexpage-bg-image {
/* styling */
}
Problems using this way
If images are big-sized and there are a lot of them, it impacts dramatically to the index.html loading time, because it will fist load all images mentioned in .css file (as you know, the code to the .css is located at the top of the page between and tags).
Questions
What is the best way to:
a) Change the background image for different pages using some funky preload function (note that bg-image has to be in the body, because some fadeloader.js stuff in my site), and;
b) Is there any better way to do this then by making thispagesbg-image.css file for every single site and;
c) Feel free to come up with your own ideas to do this!
Solution would prefered to be done compleatly in Javascript, jQuery or some mixature with css (or what ever suits to do this task most efficiently).
After 2 hours of comprehensice Googling, I only came up with nothing. I found this Pre-loading external files (CSS, JavaScript) for other pages, but I think that this loads everything before my page is loaded.
EDIT: Temporarely fix
I have now created class for each page's <html> on mypagesCustomCSS.css (and copying it as much as needed):
html.page1ClassH, html.page1ClassHere body {
background-image:url(../img/bg-for-page1.jpg);
}
html.page2ClassHere, html.page2ClassHere body {
background-image:url(../img/bg-for-page2.jpg);
}
and then I have placed following image preload JavaScript to the bottom of my index.html just before </body> tag:
<script>
$(window).on('load', function() {
if (document.images) {
img1 = new Image();
img1.src = "img/bg-for-page1.jpg";
img2 = new Image();
img2.src = "img/bg-for-page2.jpg";
}
});
</script>
This does the trick for now! As I mentioned earlier, I am using this page through iPhone 4 and slow 3G connection, so the preloading is vital.
I am still experiencing some problems with my site, as it lag's a lot. Perhaps I should resize those super-sized images and try again. Have a try at: http://www.kolumbus.fi/~g636221/jano/index.html
Solution 2 looks good to me as you don't need to create multiple css files + will be cached on the first request. One clarification though, only the images for the css classes used on the page will be downloaded here.
So now, the only task remains is to pre-load resources for other pages user is about to browse. For this you can create a javascript file or jQuery code which downloads resources after the current page has been loaded completely.
jQuery File (Code)
var pages = ["class1", "class2", "class3"]; //Declare all pages here
window.onload = windowloaded();
function windowloaded()
{
for(i=0; i < pages.length; i++)
{
$("div#preloader").append("<div class='" + pages[i] + "'></div>"); //This will load all other resources automatically as css classes are already present on the current page.
}
}
HTML Code (Add to all pages, anywhere on page. This remains invisible and is responsible for pre loading resources for other pages.)
<div id="preloader"></div>
CSS Modification (Single CSS for all pages)
div#preloader { display : none; }
Replace this :
html.contactpage-bg-image {
/* styling */
}
with :
.contactpage-bg-image {
/* styling */
}
removing html will make the class applicable for div which is used for preloading the image.
You could place all your separate CSS backgrounds into a single CSS file that is used across your site.
Give each background a class selector. Something like:
CSS
html.backgroundOne, html.backgroundOne body {
/*styles*/
}
html.backgroundTwo, html.backgroundTwo body {
/*styles*/
}
Then give each page a corresponding class on the opening <html>:
HTML
<html class="backgroundOne">
This way your CSS is already cached ready for use.

<HTML> is automatically setting inline-style that I think is set by Google's JSAPI

So, I bought the Roker theme from themeforest.net and created my website. It works fine and looks great but when I try to open my website on a Windows touch device - Surface Pro (IE and Firefox) or Windows Phone, I cannot scroll with my finger i.e. touch is not working.
When I look at the HTML code, the rendered page’s tag is adding this style
-ms-overflow-x: hidden; -ms-overflow-y: hidden; -ms-touch-action: auto !important;
And the overflow is set as an inline style.
This seems to get set automatically when I include the Google's JSAPI, because when I comment the <script type="text/javascript" src="http://www.google.com/jsapi"></script>, then everything works fine.
Any suggestions on how can I overcome this? I can share the link of my website if you want to see what is happening yourself.
Ideally you would want to track down the js file and find out why it is adding those inline styles.
I have a feeling it may have to do with the 'no-touch' class. You may want to use something like the following JS:
$(document).ready(function(){
detectMsTouch();
function detectMsTouch() {
var touchPoints = window.navigator.msMaxTouchPoints;
if (touchPoints) {
$('html').removeClass('no-touch').addClass('touch');
}
else {
return;
}
}
});
Another thing that may work is forcing the style with a CSS override.
ms-overflow-y: visible !important;
Hope it works for you.

jquery remove images from page before they get loaded

My problem is simmilar to this but I can't do it server side, since I only want to remove the images if the browser width is less than 850px.
I am currently using this:
$(function () {
if($(document).width() < 850) {
$('.thumb').remove();
}
});
The images get removed, but as you can see here, the browser loads them anyway.
Do anyone have a solution for this?
Thanks
Solution (it works now!:
Instead of always loading the images, never load them, unless the browser is greater than 850
HTML:
<?php
if(file_exists($sites[$i].'/thumb.png')) { ?>
<img class="thumb" data="/experiments/<?=$sites[$i]?>/thumb.png" />
<?php
}
?>
JS:
$('.thumb').each(function(index, element) {
$(this).attr('src', $(this).attr('data'));
});
I think you have to turn it the other way around: Meaning that you'll only load images if the doc. width is wider then 850. As far as I know the images will be requested / loaded before the script runs if they're "hard coded" in the HTML document.
Of course.
Remove() first loads them, then removes them from the DOM.
The only way to remove them so that the browser never loads them is with a server-side language. In the server side language, you could detect if the picture is on the page and if it is, you could remove them. And therefore the image is never sent to the browser.
As for your case, "if($(document).width() < 850)" is used, so you can't do all of it server side.
Why don't you just interchange between server-side and browser-side? Like PHP and JavaScript?
For example, you could, with JavaScript detect if the document width is less then 850. If it is, it loads an iframe with the parameter (remove=true). The iframe page would have all the .thumb and images and all the content, and you could use PHP on the page to detect if the "remove=true" parameter was present (use $_GET[remove]). If it was, it would not display the .thumb and never send it to the browser.
KG Christensen's and your idea of setting the image's src attribute is good.
Another idea which could work is to have the images with a display: none; style, and change it to display: inline; only if your condition is met. The browsers shouldn't load the images if they're hidden.
Something along the lines of:
<style type="text/css">
.thumb {
display: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
if ($(document).width() >= 850)
$('.thumb').show();
});
</script>

How to serve up different javascript files by browser width

So I want certain Javascript files for certain browser widths. I know that #media serves up specific CSS per browser width and some devices.
How would I do something similar for Javascript files, WITHOUT using server side calls?
Is is possible with Javascript to call other Javascript files based on browser width?
If so, How?
Thanks in advance.
var scriptSrc = 'js/defaults.js';
if (screen.width <= 800)
scriptSrc = 'js/defaults-800.js';
else if (screen.width <= 1024)
scriptSrc = 'js/defaults-1024.js';
var script = document.createElement('script');
script.src = scriptSrc;
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
Perhaps? Dynamic-load them based on screen resolution. Could also use document size, browser size, etc. Though I'm not positive you really want to be doing this. Ideally though you should be dealing with relative metrics (like % or em) in your design and avoid this.
While I'm unsure on why, you can always import JavaScript files through JS Script.
The following links give some information on this.
http://www.kevinleary.net/loadexternal-javascript-jquery-getscript/
http://www.stackoverflow.com/questions/1140402/how-to-add-jquery-in-js-file
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
ON a side note - Why are you looking at doing this? Surely you can get the resolution of the screen and then adjust calculations / content based on those variables without the need to change JS files. There are so many different resolutions (mobile devises, multiple monitors, wide screen, projectors etc.). A user can also re-size the browsers effectively making this not worth it.
Try this:
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
if (window.document.body.clientWidth == XXX) {
fileref.setAttribute("src", "script1.js")
} else {
fileref.setAttribute("src", "script2.js")
}
Media queries are a good solution for providing alternative styles for different window widths. Unfortunately, there is no media attribute for the <script> element to proceed similarly.
You can, however, provide a script-loading script which will load desired .js file depending on the style sheet selected by the browser on the basis of your media query. I don't know how to do this in a direct, elegant way but there is a nice hack for that. You have to "mark" each .css with a unique declaration (dummy, unimportant or different by design) and check it from within JS after the page has loaded to determine which style sheet has been applied by the browser.
The HTML could look like this:
<style media="handheld, screen and (max-width:1023px)">
body { margin-top: 0px }
</style>
<style media="screen and (min-width:1024px)">
body { margin-top: 1px }
</style>
And the accompanying JS as follows:
function onLoad() {
var head = document.getElementsByTagName('head')[0];
var body = document.getElementsByTagName('body')[0];
var mark = window.getComputedStyle(body).getPropertyValue('margin-top');
var script = document.createElement('script');
script.setAttribute('src', mark=='0px' ? 'handheld.js' : 'screen.js');
head.appendChild(script);
}
This does the job, but only on a per-load basis. To get a responsive reaction to resizing the browser's window by the user, you should keep track on the widow's width and reload the page when necessary.
Since 2011 the world has shifted into the mobile era.
You might wanna try with: document.documentElement.clientWidth, as it will tell you the visible area of your page - it reacts to zoom but not to pitch.

Categories

Resources