I already have the following for the JS files:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">!window.jQuery && document.write(unescape("%3Cscript src='/app_shared/script/jquery-1.6.1.min.js' type='text/javascript'%3E%3C/script%3E"))</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js"></script>
<script type="text/javascript">!window.jQuery.ui && document.write(unescape("%3Cscript src='/app_shared/script/jquery-ui.min.js' type='text/javascript'%3E%3C/script%3E"))</script>
How can I go for something similar for a theme?
I can download it from the cdn like this:
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
But how can I detect if the file was downloaded, to reference a local copy on failure?
I know how to add the local copy programatically with jQuery, but I don't know how to check whether the CSS download succeded. Also, are <link> tag downloads blocking, or are they async? That'd be a problem, too.
You could do a style check where a font should be a particular family and then check against that family name. If the name is not what you expect then load the local copy.
You can also try something like Get a CSS value from external style sheet with Javascript/jQuery
<style>
p {color: blue}
</style>
$(document).ready(function() {
var $p = $("<p></p>").hide().appendTo("body");
alert($p.css("color"));
$p.remove();
});
Related
This question already has answers here:
Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail
(23 answers)
Closed 8 years ago.
I’m using a CDN for the following javascript:
https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js
http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js
http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js
For each one, how can I revert to using local copy in the instance where it may be blocked/unavailable?
To confirm that cdn script loaded you can check for existence any variable/function this script defines, if it is undefined - then cdn failed and you need to load local script copy.
On this principle are based solutions like that:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>
(if there is no window.jQuery property defined cdn script didn't loaded).
You may build your own solutions using this method. For instance, jquery tooltip plugin creates $.tooltip() function so we can check it with code like this:
<script>
if (typeof $.tooltip === 'undefined') {
document.write('<script src="js/libs/jquery.tooltip.min.js">\x3C/script>');
}
</script>
I would have looked into a plugin like yepnopejs
yepnope([{
load: 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('local/jquery.min.js');
}
}
}]);
Takes an array of object to check for, check the documentation at the site
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'))</script>
Taken from HTML5 Boilerplate.
I use http://fallback.io/
fallback.load({
// Include your stylesheets, this can be an array of stylesheets or a string!
page_css: 'index.css',
// JavaScript library. THE KEY MUST BE THE LIBARIES WINDOW VARIABLE!
JSON: '//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.min.js',
// Here goes a failover example. The first will fail, therefore Fallback JS will load the second!
jQuery: [
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.FAIL_ON_PURPOSE.min.js',
'//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js'
], .......
first thing - shouldn't you include them in different order?
something like this should work:
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js"></script>
<script>jQuery.fn.validate || document.write('<script src="js/jquery.validate.min.js">\x3C/script><script src="js/jquery.validate.unobtrusive.min.js">\x3C/script>'</script>
what I'm doing here is simply checking if the first plugin (jQ validate) has been loaded. by checking for a static validate function on jQuery.fn object. I can't check the second script same way, because it's not adding anything anywhere, just proxying existing methods, so it's easier to assume that if the first one works, the second one will work too - after all, they are provided by the same CDN.
You need to know, how you can make sure that a lib was loaded successfully. For instance:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery.min.js">\x3C/script>'</script>
So this trys to load jQuery (1.5.1) from the google CDN. Since <script> tags do block the overall render & execution process (if not explicitly told different), we can check right after that if the jQuery object is found within window. If not, just fallback by writing another <script> tag into the document, referencing a local copy.
The following solution passes validation for both HTML5, XHTML 1.0 Transitional and other HTML flavors. Place the following after each of your external JQuery call. Be sure to replace jquery.min.js with the path to your local copy of the JQuery script.
<script type="application/javascript">window.jQuery ||
document.write(unescape('%3Cscript src="jquery.min.js"%3E%3C/script%3E'))</script>
If you don't use unescape, you'll have errors when validating with http://validator.w3.org since "%" is not allowed in an attribute specification list.
The HTML5 Boilerplate example also has validation errors when used with older HTML:
required attribute "type" not specified
character "&" is the first character of a delimiter but occurred as data
You'll be fine with the HTML5 Boilerplate solution if you are developing only for HTML5 and future HTML flavors, but since you may find yourself inserting portions of your code into legacy HTML, play it safe with this one-size-fits-all approach.
You'll need to specify a different function for each externally hosted script. For instance, the JQuery Tooltip plugin creates the $.tooltip() function, so you can check it with the following:
<script type="application/javascript">typeof ($.tooltip()) !== 'undefined' ||
document.write(unescape('%3Cscript src="jquery.tooltip.min.js"%3E%3C/script%3E'))</script>
I answered a similar questions at jquery ui - how to use google CDN
You can make the call using
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" media="all" />
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js" type="text/javascript"></script>
You can also link to other Ui themes by changes the name of the theme. In This case change the name base to any other theme name /base/jquery-ui.css to any other theme.
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" media="all" />
Check out the jQuery UI Blog for a link of all CDN links http://blog.jqueryui.com/
If you want to revert back to your host in case Google failed, you can do
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined')
{
document.write(unescape("%3Cscript src='/jquery.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js" type="text/javascript"></script>
<script type="text/javascript">
if(typeof jQval == 'undefined')
{
document.write(unescape("%3Cscript src='/Scripts/jquery.validate.unobtrusive.min.js' type='text/javascript'%3E%3C/script%3E"));
document.write(unescape("%3Cscript src='/Scripts/jquery.validate.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
Taken from this article
Best to do all this script loading with your own Javascript code.
First try to load the CDN file by inserting a new SCRIPT element into the DOM. Then check that it has loaded by looking for an object that it defines. If the object does not appear, then insert another SCRIPT element to load the local copy. Probably best to clean up the DOM and remove SCRIPTs which failed to load as well.
Don't forget to account for timing issues, i.e. load is not instant.
I was wondering if its possible to provide an alternate link if the CDN cannot be reached. For instance for bootstrap provide the tags to download from the CDN and if that cannot be reached provide the locally stored bootstrap:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- if cannot be downloaded -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/bootstrap.min.js"></script>
I would like to use this model because browsers cache CDN files so that speed could be improved by using this (also their download times are probably better than my servers). Though on the off chance that someone is connecting via the local network but not connected to the internet and does not have one of these cached versions I would like an alternative. Is this possible?
http://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/
That link answers both parts of the question.
For your example, with fallback.js:
HTML:
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
JS:
cfg({
"libs": {
'css$bootstrap': {
'exports': '.col-xs-12',
'urls': 'css/bootstrap.min.css'
},
'bootstrapjs': {
'urls': [
'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js',
'js/bootstrap.min.js'
]
}
}
});
req(function(css$bootstrap, bootstrapjs){ //Everything is loaded });
It appears the article above is a bit outdated on the fallback.js API, so I've included the example based on current state. https://github.com/dolox/fallback/blob/master/README.md
I just used this for a site i've been building lately, let me know if this is what you had in mind:
<script type="text/javascript" async src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="/path/to/file"><\/script>')
</script>
Perhaps you can use something similar for your bootstrap loading, i'll look more into it in the men time, let me know if it helps.
Edit:
Also found this thread question someone else made, could be of use:
how to fallback twitter-bootstrap cdn to local copy
For the css part, see the answer here: How to implement a CDN failsafe for css files?
For the js part, see: Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail
TL;DR:
<link rel="stylesheet" type="text/css" href="cdnurl/styles.css" onload="alert('loaded')" onerror="javascript:loadCSSBackup()" />
<script type="text/javascript>
function loadCSSBackup(){
var css = document.createElement("link")
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", 'backup/styles.css');
document.getElementsByTagName("head")[0].appendChild(css);
}
</script>
For loading a fallback JS, you can use (taken from the answer above):
<script type="text/javascript" async src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="/path/to/file"><\/script>')
</script>
So I'm trying to use a chrome:// URI in my add-on and I want to use a page-worker on it using the scripting trusted content method, however it seems to not work when I hard code the URI in, the chrome://<package name>/<part>/<file>; however, it works when I use the self.data.url('filename'). I want to use the chrome:// URI is because I use a GUID instead of the email style as the add-on's ID and also I don't want to use the resource:// URI.
Content Script
addon.port.emit('hi');
HTML
<html>
<head>
<meta charset="UTF-8">
<title>Gaia Utils Settings</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/dropdown.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/settings.dev.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/test.dev.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="css/settings.css" rel="stylesheet" type="text/css">
<link href="css/poststyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<nav id="navbar_header" class="navbar navbar-blue navbar-static-top"></nav>
<div id="content_wrapper" class="container">
<div id="content_padding" class="container"></div>
</div>
<footer class="footer"></footer>
</body>
</html>
main.js
var PageWorker = require("sdk/page-worker");
PageWorker.Page({
contentURL: "chrome://gaiautils/content/settings.dev.html",
onMessage: function(message) {
console.log(message);
}
});
I know I can use a page-mod and attach the scripts to it with that, but I'd rather call the scripts from within the file and be able to communicate with the main add-on code. So is there a way so that I can have my cake and eat it too - using the hard coded chrome:// URI in conjunction with calling the scripts from within the HTML file while being able to have those scripts communicate back to the main.js file?
How can I have it so that I can use the addon.port.emit() in the content scripts that are called directly in the HTML file so that I don't have to use the self.data.url('htmlFile'), because I don't want to use the resource://pageckage-GUID-at-jetpack/path/to/file
The SDK only considers pages "trusted" if the URL you're loading is part of the add-on assets (data/). chrome:// URIs are not. Hence you'll need to use regular content scripts via the contentScriptFile: [...] option in your PageWorker definition.
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
Don't ever load remote scripts for security reasons (and performance reasons to a far lesser extent)! Ship a local copy of jQuery if you want to use it.
I'm having some issues with prettyPhoto on one of my clients website. Here is the link for reference: http://www.browardmicrofilm.com/pages/kodak-vizit-essential.html
I've used prettyPhoto on multiple other websites without issue. However for some reason, this website just doesn't want to perform the script properly. Instead of opening an image in the lightbox clone, it simply opens it in a new page. Perhaps it has something to do with the hosting but either way, wanted to see what professionals like you think!
I'm using Firefox 26 (Mac version) and I used Firebug to determine the error:
TypeError: $ is not a function
$(document).ready(function(){
I've tried numerous solutions, including one that made me change "$" to "window.jQuery and then for some reason the next line in the code creates the same error.
Here's the my code for those of you that wish to skip the entire page source code:
In my header:
<link href="../prettyPhoto.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../Scripts/jquery.prettyPhoto.js"></script>
<script type="text/javascript" src="../Scripts/jquery-1.6.1.min.js"></script>
The final script just before the closing body tag:
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("a[rel^='prettyPhoto']").prettyPhoto({
theme: 'light_rounded',
});
});
</script>
I know my links are good, which is why I'm not including them.
Vanilla jquery needs to be declared before any library built on top of it
<!--first, jquery-->
<script type="text/javascript" src="../Scripts/jquery-1.6.1.min.js"></script>
<!--then the rest-->
<script type="text/javascript" src="../Scripts/jquery.prettyPhoto.js"></script>
Error below is saying that jQuery is not loaded.
TypeError: $ is not a function
$(document).ready(function(){
Check your resources, my guess is that your paths are case sensitive and libraries are not being properly loaded.
<script type="text/javascript" src="../Scripts/jquery.prettyPhoto.js"></script>
<script type="text/javascript" src="../Scripts/jquery-1.6.1.min.js"></script>
Check your resources.
Make sure that jQuery is loaded before the plugin is loaded.
<script type="text/javascript" src="../Scripts/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="../Scripts/jquery.prettyPhoto.js"></script>
Ultimately I abandoned the prettyPhoto javascript and went with an alternative. Lightbox 2.0:
http://lokeshdhakar.com/projects/lightbox2/
It works just as I'd like and no problems.
I am using uniformjs to style some html element but when i try to update an element such as a check box using
$.uniform.update('input[type=checkbox]');
I get the error
$.uniform is undefined
any one else have an idea how to solve this?
I have both jQuery and the uniform.js added to the page.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.uniform.min.js" type="text/javascript" charset="utf-8"></script>
What's weird is this worked when it was a regular HTML page and stopped working when i made it into a ASP.NET page and added custom form validators. Perhaps there is some clash?
Reason for this error is browser cant identify $.uniform which can be because of following two reasons:
You have not included uniform.js file to your page, check if a similar looking lines is present in your markup.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script src="jquery.uniform.js"></script>
You are referencing it before its been loaded (have you included it at the end of the page, after the markup?)
You have to load all your dependencies and the current library itself to make it work.
For your css:
<link rel="stylesheet" href="uniform.default.css" media="screen" />
For your javascript:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script src="jquery.uniform.js"></script>
Please, check this JSFiddle that I've build for you, showing uniformjs working.