I use the src.sencha.io service to resize images on the fly according to device width, saving lots of bandwidth on mobiles etc.
Sometimes the service fails randomly with a 503 error, so a fallback is needed. I've written this JS to fallback to "non-sencha" urls, and emit an error event, if the first image requested through sencha fails.
This is my first open-sourced bit of code, so am keen to get feedback on my:
- code correctness
- whether this prototype-based design pattern is appropriate
- alternative better patterns
- comment/code clarity
Even just confirming whether it's good would be helpful, as I don't have any formal programming training to be confident.
jsfiddle with test case prepared for you here.
/** SENCHA SRC IMAGE FALLBACK ***************************************
*
* Author: Josh Harrison (http://www.joshharrison.net/)
* URL: https://github.com/ultrapasty/sencha-src-image-fallback
* Version: 1.0.0
* Requires: jQuery
*
* Tests to see if the src.sencha.io service is down, and if so,
* falls back to local images, by removing the sencha domain
* from the src.
*
* Can be instantiated with `new SenchaSRCFallback().init();`
* Or `var instance = new SenchaSRCFallback().init();`
*
* Emits the event `senchafailure` if sencha fails.
* Listen with `instance.onsenchafailure = func;`
*
*/
;(function(window, $) {
var SenchaSRCFallback = function() {
this.sencha_path_identifier = '.sencha.io/';
this.sencha_path_regex = /http:\/\/src[1-4]?\.sencha\.io\//i;
this.$imgs = null;
};
SenchaSRCFallback.prototype = {
init : function() {
this.$imgs = $("img[src*='" + this.sencha_path_identifier + "']");
if(this.$imgs.length) {
this.test_sencha_availability();
}
return this;
},
test_sencha_availability : function() {
var t = this, img = new Image();
img.onerror = function() {
$(t).trigger("senchafailure");
t.fallback_to_local_srcs();
};
img.src = this.$imgs[0].getAttribute("src");
},
fallback_to_local_srcs : function() {
var t = this;
this.$imgs.each(function() {
this.setAttribute("src", this.getAttribute("src").replace(t.sencha_path_regex, ""));
});
}
};
window.SenchaSRCFallback = SenchaSRCFallback;
})(window, jQuery);
// Example usage:
// Instantiate the fallback
var senchafallback = new SenchaSRCFallback().init();
// Listen for failure like this:
senchafallback.onsenchafailure = function() {
console.log("It failed.");
// log failure event in google analytics, etc
};
Images would be initially routed through src.sencha.io to avoid downloading twice. With the above JS, should sencha fail, these image tags:
<img src="http://src.sencha.io/http://mysite.com/image1.png">
<img src="http://src1.sencha.io/http://mysite.com/image2.png">
<img src="http://src2.sencha.io/http://mysite.com/image3.png">
... would become the following:
<img src="http://mysite.com/image1.png">
<img src="http://mysite.com/image2.png">
<img src="http://mysite.com/image3.png">
1 Answer 1
I like the idea, from a once over:
- Since you use an IIFE I would declare
sencha_path_identifier
andsencha_path_regex
outside of the constructor, then you can access them without specifyingthis.
- I would do either
function SenchaSRCFallback() {
orvar SenchaSRCFallback = function SenchaSRCFallback() {
, anonymous functions are a pain to troubleshoot - Why do you require the caller to call
init()
? In my mind this call should be done within the constructor.
This is something I might borrow at some point.
-
\$\begingroup\$ One thought on your first point – is it better to store this on the object, in order to avoid one extra look up the chain? Also on the third point, I may want to use
var instance = new SenchaImageFallback(); instance.onsenchafailure = func; instance.init()
to bind the fail fallback before it attempts to request the image. Is this a good reason to require the call toinit()
separately? \$\endgroup\$Josh Harrison– Josh Harrison2014年03月06日 10:05:26 +00:00Commented Mar 6, 2014 at 10:05 -
1\$\begingroup\$ 1. I think it makes for cleaner code, performance penalty should be minimal if any. 2. I would actually make
func
an optional parameter of the constructor in that case. \$\endgroup\$konijn– konijn2014年03月06日 11:59:24 +00:00Commented Mar 6, 2014 at 11:59
Explore related questions
See similar questions with these tags.