-
-
Save millermedeiros/2690836 to your computer and use it in GitHub Desktop.
Refactoring JS for testing part 5 – refactor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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