Skip to content

Instantly share code, notes, and snippets.

@millermedeiros
Forked from karlwestin/gist:2690501
Created May 13, 2012 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save millermedeiros/2690836 to your computer and use it in GitHub Desktop.
Save millermedeiros/2690836 to your computer and use it in GitHub Desktop.
Refactoring JS for testing part 5 – refactor
/*
* Karl Westin
* Part of the "refactoring javascript for unit testing" blog post
* ---
* Quick refactor by Miller Medeiros (http://blog.millermedeiros.com)
* Didn't tested the code during/after changes, might contain errors.
*/
function Lightbox(parent) {
// `parent` can be a selector or element or jquery collection
// removed content from constructor so can use same instance to show
// multiple messages
this._parent = parent || 'body';
// defer the elements creation and event binding until needed
// constructors usually shouldn't have side-effects
}
Lightbox.prototype = {
_setup: function() {
this.$overlay = $("<div class='js-overlay'></div>").appendTo(this._parent);
var $dialog = $("<div class='js-dialog'>" +
"<a href='#' class='js-close'>Close</a>" +
"<div class='js-content'></div>" +
"</div>");
//by using appendTo you can pass a selector if needed
$dialog.appendTo(this._parent);
this.$dialog = $dialog;
this.$closeBtn = $dialog.find('.js-close');
this.$content = $dialog.find('.js-content');
this._bindEvents();
},
_autoSize: function() {
var width = this.$content.width(),
height = this.$content.height();
// batch css changes
this.$dialog.css({
width : width,
height : height,
marginLeft : -width/2,
marginTop : -height/2
});
},
_bindEvents: function() {
//bind context to avoid scope issues
this.closeOnClick = $.proxy(this.closeOnClick, this);
this.$closeBtn
.add(this.$overlay)
.bind("click", this.closeOnClick);
},
_unbindEvents : function() {
this.$closeBtn.unbind("click");
this.$overlay.unbind("click");
},
setContent : function(content){
//not inside the _setup() code so we can call it individually
//if needed
this.$content.html(content);
this._autoSize();
},
open : function(content){
if (this.$dialog) {
//already opened, just replace content
this.setContent(content);
return;
}
this._setup();
this.setContent(content);
this.$overlay.stop(true).fadeOut(0).fadeIn(500);
},
close: function() {
if (! this.$dialog) {
//already disposed
return;
}
var self = this;
// stop() to safeguard against multiple animations
this.$overlay.stop(true).fadeOut(500, function(){
self.dispose();
});
this.$dialog.stop(true).hide();
},
// kill all the references and remove elements from the document
// even if you still have a reference to the LightBox instance these
// object/elements will be marked for garbage collection
dispose : function() {
if (! this.$dialog) {
//already disposed
return;
}
this._unbindEvents();
this.$overlay.remove();
this.$dialog.remove();
delete this.$overlay;
delete this.$dialog;
delete this.$closeBtn;
delete this.$content;
},
closeOnClick : function(evt){
evt.preventDefault();
this.close();
}
};
$(document).ready(function() {
var lbox = new Lightbox();
$("#boxlink").bind("click", function(e) {
e.preventDefault();
var content = "<img height='331' width='500' src='img/spaceshuttle.jpg' title='Space shuttle on a Plane!'>" +
"<br>Gorgeous photo of the space shuttle by <a href='http://www.flickr.com/photos/deg_io/5702042693/'>flickr user deg_io</a>";
// by adding a show method we can store a single reference and avoid
// creating multiple objects without need
// constructors shouldn't have side-effects
// in fact if you are sure you can only have a single lightbox each
// time you could convert it into a static object (code would be the
// same)
lbox.show(content);
});
});
@millermedeiros
Copy link
Author

quick refactor just to exemplify how it could be split even further and how you could make it open/close multiple times and reuse same instance.

may contain errors (didn't tested it).

Original code is from: http://karlwestin.posterous.com/refactoring-frontend-javascript-for-unit-test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment