var constrainBoundaries = function(el) {
var pos = el.position();
var parentHeight = el.parent().height();
var parentWidth= el.parent().width();
if(pos.top > 0) {
el.css("top",0);
} else if(pos.top < -1*(el.height()- parentHeight)) {
el.css("top",-1*(el.height()-parentHeight));
}
if(pos.left> 0) {
el.css("left",0);
} else if(pos.left < -1 *(el.width()- parentWidth)) {
el.css("left", -1 * (el.width()-parentWidth));
}
};
var calculateCrop = function(el) {
var pos = el.position();
var parentHeight = el.parent().height();
var parentWidth= el.parent().width();
var cropBoundary = {
"x1":-1 * pos.left,
"y1":-1 * pos.top,
"x2":(-1 * pos.left)+parentWidth,
"y2":(-1 * pos.top)+parentHeight,
}
el.data("crop", cropBoundary);
};
function sumAndSquare(a, b){
}
function testSum(){
equal(sumAndSquare(1,2), 9);
equal(sumAndSquare(9,4), 169);
equal(sumAndSquare(100,32), 17424);
}
testSum();
function arrayLength(arr){
}
function testArrayLength(){
equal(arrayLength([1]), 1);
equal(arrayLength([1, 2, 3]), 3);
equal(arrayLength(Array(100)), 100);
}
testArrayLength();
function testjQueryActsAsAdvertised(){
var $div = $(document.createElement('div'));
$div.addClass('test');
equal($div.get(0).className, 'test');
$div.appendTo(document.body);
equal($('.test').length, 1);
}
testjQueryActsAsAdvertised();
$('.accordion').click(function(){
$(this).find('ul').show();
});
$(window).scroll(function(event){
var offset = $(this.element).offset();
if( $('window').scrollTop() > offset.top ||
$('window').scrollLeft() > offset.left){
$(this.element).addClass('scrolledOff');
}
else{
$(this.element).removeClass('scrolledOff');
}
});
don't write code like that
it does too much, in one place
plugins need organization
learn patterns and best practices
function Plugin( element, options ) {
this.$element = $(element);
this.$sections = this.$element.find('ul').hide();
this.init();
}
Plugin.prototype.init = function () {
var self = this;
this.$element.click(function(){
self.handleAccordionClick();
});
};
Plugin.prototype.handleAccordionClick = function () {
this.$sections.show();
};
$.fn['accordionPlugin'] = function ( options ) {
return this.each(function () {
$.data(this, 'accordionPlugin', new Plugin( this, options ))
});
}
var clicked = false;
var $ul = $(document.createElement('ul'));
$ul.accordionPlugin();
$ul.data('accordionPlugin')
.handleAccordionClick = function(){clicked = true;}
$ul.trigger('click');
equal(clicked, true);
SinonJS makes this much easier
var $ul = $(document.createElement('ul'));
$ul.accordionPlugin();
var plugin = $ul.data('accordionPlugin');
plugin.handleAccordionClick = sinon.spy();
$ul.trigger('click');
ok(plugin.handleAccordionClick.called,'spy was called');
var $ul = $(document.createElement('ul'));
var $innerUl = $(document.createElement('ul'));
$ul.appendTo(document.body).append($innerUl);
$innerUl.hide().wrap(document.createElement('li'));
equal($innerUl.css('display'), 'none');
$ul.accordionPlugin();
$ul.data('accordionPlugin').handleAccordionClick();
equal($innerUl.css('display'), 'block');
Using fixtures/jQuery's DOM builder makes this easier
Plugin.prototype.init = function(){
var self = this,
offset = $(this.element).offset();
$(window).scroll(function(event){
if(elementIsOutsideViewport(event.target, offset)){
self.elementScrolledOff();
}
else{
self.elementScrolledOn();
}
});
}
function elementIsOutsideViewport(viewport,offset){
var $viewport = $(viewport);
return $viewport.scrollTop() > offset.top ||
$viewport.scrollLeft() > offset.left;
}
var $el = $(document.createElement('div'));
$el.stickyScroll();
var plugin = $.data($el.get(0), "plugin_stickyScroll");
plugin.elementScrolledOff = sinon.spy();
plugin.elementScrolledOn = sinon.spy();
var event = jQuery.Event("scroll");
event.target = $({scrollTop:101});
$(window).trigger(event);
equal(plugin.elementScrolledOff.called, true, 'off works');
equal(plugin.elementScrolledOn.called, false, 'on works');
Plugin.prototype.init = function(){
var self = this;
this.getData().done(function(data){
self.$element.text(data.message);
});
}
Plugin.prototype.getData = function(){ return $.get('/data');}
var xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
xhr.onCreate = function (newXhr) {
requests.push(newXhr);
};
var $el = $(document.createElement('div')).ajaxPlugin();
requests[0].respond(200,
{ "Content-Type": "application/json" },
'{"message":"hey!"}')
equal($el.text(), "hey!");
var pluginName = "ajaxSomething",
defaults = {
}
function Plugin( element, options ) {
this.element = element;
this.$element = $(element);
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this.init();
}
Plugin.prototype.init = function(){
}
$.fn.ajaxPlugin = function(options){
return this.each(function(){
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new Plugin( this, options ));
}
});
}
var pluginName = "stickyScroll",
defaults = {
"class":"scrolled-off"
}
function Plugin( element, options ) {
this.element = element;
this.$element = $(element);
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this.init();
}
Plugin.prototype.init = function(){
var self = this,
offset = $(this.element).offset();
$(window).scroll(function(event){
if(elementIsOutsideViewport(event.target, offset)){
self.elementScrolledOff();
}
else{
self.elementScrolledOn();
}
});
}
Plugin.prototype.elementScrolledOn = function(){
$(this.element).removeClass(this.options["class"]);
}
Plugin.prototype.elementScrolledOff = function(){
$(this.element).addClass(this.options["class"]);
}
$.fn.stickyScroll = function(options){
return this.each(function(){
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new Plugin( this, options ));
}
});
}
function elementIsOutsideViewport(viewport,offset){
var $viewport = $(viewport);
return $viewport.scrollTop() > offset.top || $viewport.scrollLeft() > offset.left;
}