type
LR
Takeshi Takatsudo (takazudo@gmail.com)
jQuery便利
あんなことや
こんなことも簡単
プラグイン最高
でもプラグインの
書き方バラバラ
主にプラグインの中の話
jQueryプラグインの
書き方を解説します
難しい部分もあるので
真似て書いてみるのを
オススメします
10ステップあります
<div class="item"> <div class="label">A</div> <h2 class="title">itemA</h2> <p class="main">text text text text</p> <p class="showMore">more</p> <p class="more">more more more more</p> <p class="hideMore">hide</p> </div> <div class="item"> <div class="label">B</div> <h2 class="title">itemB</h2> <p class="main">text text text text</p> <p class="showMore">more</p> <p class="more">more more more more</p> <p class="hideMore">hide</p> </div> <div class="item"> <div class="label">C</div> <h2 class="title">itemC</h2> <p class="main">text text text text</p> <p class="showMore">more</p> <p class="more">more more more more</p> <p class="hideMore">hide</p> </div>
$(function(){
$('.more').css('display','none');
$('.showMore')
.css('display','block')
.click(function(){
$(this)
.slideUp()
.next()
.slideDown(function(){
$(this)
.siblings('.hideMore')
.slideDown()
.one('click', function(){
$(this)
.slideUp()
.prev()
.slideUp(function(){
$(this)
.prev()
.slideDown();
})
})
});
});
});
$(function(){
$('.item').each(function(){
// prepare elements
var $item = $(this);
var $showMore = $('.showMore', $item);
var $more = $('.more', $item);
var $hideMore = $('.hideMore', $item);
// hide more first
$showMore.css('display','block');
$more.css('display','none');
// bind events
$showMore.click(function(){
$showMore.slideUp();
$more.slideDown(function(){
$hideMore.slideDown();
});
});
$hideMore.click(function(){
$hideMore.slideUp();
$more.slideUp(function(){
$showMore.slideDown();
});
});
});
});
$(function(){
$('.item').each(function(){
// prepare elements
var $item = $(this);
var $showMore = $('.showMore', $item);
var $more = $('.more', $item);
var $hideMore = $('.hideMore', $item);
// hide more first
function init(){
$showMore.css('display','block');
$more.css('display','none');
}
// open
function open(){
$showMore.slideUp();
$more.slideDown(function(){
$hideMore.slideDown();
});
}
// close
function close(){
$hideMore.slideUp();
$more.slideUp(function(){
$showMore.slideDown();
});
}
init();
$showMore.click(open);
$hideMore.click(close);
});
});
/* moreTogglable plugin */
$.fn.moreTogglable = function(){
return this.each(function(){
// prepare elements
var $item = $(this);
var $showMore = $('.showMore', $item);
var $more = $('.more', $item);
var $hideMore = $('.hideMore', $item);
// hide more first
function init(){
$showMore.css('display','block');
$more.css('display','none');
}
// open
function open(){
$showMore.slideUp();
$more.slideDown(function(){
$hideMore.slideDown();
});
}
// close
function close(){
$hideMore.slideUp();
$more.slideUp(function(){
$showMore.slideDown();
});
}
init();
$showMore.click(open);
$hideMore.click(close);
});
};
/* let's do it */
$(function(){
$('.item').moreTogglable();
});
/* moreTogglable plugin */
$.fn.moreTogglable = function(options){
var options = $.extend({
speed: 400,
selector_showMore: '.showMore',
selector_more: '.more',
selector_hideMore: '.hideMore'
}, options);
return this.each(function(){
// prepare elements
var $item = $(this);
var $showMore = $(options.selector_showMore, $item);
var $more = $(options.selector_more, $item);
var $hideMore = $(options.selector_hideMore, $item);
// hide more first
function init(){
$showMore.css('display','block');
$more.css('display','none');
}
// open
function open(){
$showMore.slideUp(options.speed);
$more.slideDown(options.speed, function(){
$hideMore.slideDown(options.speed);
});
}
// close
function close(){
$hideMore.slideUp(options.speed);
$more.slideUp(options.speed, function(){
$showMore.slideDown(options.speed);
});
}
init();
$showMore.click(open);
$hideMore.click(close);
});
};
/* let's do it */
$(function(){
$('.item').moreTogglable({
speed: 200
});
});
大体ここまでで
事足りることが多い
/* MoreTogglable class */
$.MoreTogglable = function(element, options){
this.options = $.extend({}, this.options, options);
this.$element = $(element);
this._setupElements();
this._eventify();
this._init();
};
$.MoreTogglable.prototype = {
options: {
speed: 400,
selector_showMore: '.showMore',
selector_more: '.more',
selector_hideMore: '.hideMore'
},
/* elements */
$element: null,
$showMore: null,
$more: null,
$hideMore: null,
/* private methods */
_setupElements: function(){
var $el = this.$element;
var o = this.options;
this.$showMore = $(o.selector_showMore, $el);
this.$more = $(o.selector_more, $el);
this.$hideMore = $(o.selector_hideMore, $el);
},
_eventify: function(){
this.$showMore.click( $.proxy(this.open, this) );
this.$hideMore.click( $.proxy(this.close, this) );
},
_init: function(){
this.$showMore.css('display','block');
this.$more.css('display','none');
},
/* public methods */
open: function(){
var s = this.options.speed;
var self = this;
self.$showMore.slideUp(s);
self.$more.slideDown(s, function(){
self.$hideMore.slideDown(s);
});
},
close: function(){
var s = this.options.speed;
var self = this;
self.$hideMore.slideUp(s);
self.$more.slideUp(s, function(){
self.$showMore.slideDown(s);
});
}
};
/* bridge */
$.fn.moreTogglable = function(options){
return this.each(function(){
new $.MoreTogglable(this, options);
});
};
/* let's do it */
$(function(){
$('.item').moreTogglable({
speed: 1000
});
});
/* MoreTogglable class */
$.MoreTogglable = function(element, options){
this.options = $.extend({}, this.options, options);
this.$element = $(element);
this._setupElements();
this._eventify();
this._init();
};
$.MoreTogglable.prototype = {
/* options */
options: {
speed: 400,
selector_showMore: '.showMore',
selector_more: '.more',
selector_hideMore: '.hideMore'
},
/* elements */
$element: null,
$showMore: null,
$more: null,
$hideMore: null,
/* misc */
_isOpen: false,
/* private methods */
_setupElements: function(){
var $el = this.$element;
var o = this.options;
this.$showMore = $(o.selector_showMore, $el);
this.$more = $(o.selector_more, $el);
this.$hideMore = $(o.selector_hideMore, $el);
},
_eventify: function(){
this.$showMore.click( $.proxy(this.open, this) );
this.$hideMore.click( $.proxy(this.close, this) );
},
_init: function(){
this.$showMore.css('display','block');
this.$more.css('display','none');
},
/* public methods */
open: function(){
if(this._isOpen){
return;
}
this._isOpen = true;
var s = this.options.speed;
var self = this;
self.$showMore.slideUp(s);
self.$more.slideDown(s, function(){
self.$hideMore.slideDown(s);
});
},
close: function(){
if(!this._isOpen){
return;
}
this._isOpen = false;
var s = this.options.speed;
var self = this;
self.$hideMore.slideUp(s);
self.$more.slideUp(s, function(){
self.$showMore.slideDown(s);
});
},
toggle: function(){
if(this._isOpen){
this.close();
}else{
this.open();
}
},
getSpeed: function(){
return this.options.speed;
}
};
/* bridge */
$.fn.moreTogglable = function(){
/* convert arguments to array */
var args = Array.prototype.slice.call(arguments);
/* detect method call, if no, arguments[0] must be options */
var isMethodCall = (args.length > 0) && ($.type(args[0]) === 'string');
var method = isMethodCall ? args[0] : undefined;
var options = isMethodCall ? undefined: args[0];
/* jQuery's methods return jQueryObject right? */
var returnValue = this;
if(isMethodCall){
/* bridge to class */
this.each(function(){
var $el = $(this);
var instance = $el.data('moreTogglable');
var res = instance[method].apply(instance, args.slice(1));
if( (res !== instance) && (res !== undefined) ){
returnValue = res;
}
});
}else{
/* normally */
this.each(function(){
var $el = $(this);
var instance = new $.MoreTogglable($el, options)
$el.data('moreTogglable', instance);
});
}
return returnValue;
};
/* let's do it */
$(function(){
$('.item').moreTogglable();
$('#b1').click(function(){
$('.item').moreTogglable('open');
});
$('#b2').click(function(){
$('.item').eq(0).moreTogglable('open');
});
$('#b3').click(function(){
$('.item').moreTogglable('close');
});
$('#b4').click(function(){
$('.item').eq(0).moreTogglable('close');
});
$('#b5').click(function(){
$('.item').moreTogglable('toggle');
});
$('#b6').click(function(){
alert($('.item').eq(0).moreTogglable('getSpeed'));
});
});
/* MoreTogglable class */
$.MoreTogglable = function(element, options){
this.options = $.extend({}, this.options, options);
this.$element = $(element);
this._setupElements();
this._eventify();
this._init();
};
$.MoreTogglable.prototype = {
/* options */
options: {
speed: 400,
selector_showMore: '.showMore',
selector_more: '.more',
selector_hideMore: '.hideMore'
},
/* elements */
$element: null,
$showMore: null,
$more: null,
$hideMore: null,
/* misc */
_isOpen: false,
/* private methods */
_setupElements: function(){
var $el = this.$element;
var o = this.options;
this.$showMore = $(o.selector_showMore, $el);
this.$more = $(o.selector_more, $el);
this.$hideMore = $(o.selector_hideMore, $el);
},
_eventify: function(){
this.$showMore.click( $.proxy(this.open, this) );
this.$hideMore.click( $.proxy(this.close, this) );
},
_init: function(){
this.$showMore.css('display','block');
this.$more.css('display','none');
},
/* public methods */
open: function(){
if(this._isOpen){
return;
}
this._isOpen = true;
var s = this.options.speed;
var self = this;
self.$showMore.slideUp(s);
self.$more.slideDown(s, function(){
self.$hideMore.slideDown(s);
});
},
close: function(){
if(!this._isOpen){
return;
}
this._isOpen = false;
var s = this.options.speed;
var self = this;
self.$hideMore.slideUp(s);
self.$more.slideUp(s, function(){
self.$showMore.slideDown(s);
});
},
toggle: function(){
if(this._isOpen){
this.close();
}else{
this.open();
}
},
getSpeed: function(){
return this.options.speed;
}
};
/* define custome selector */
$.expr[':'].moreTogglable = function(element){
return Boolean($.data(element, 'moreTogglable'));
};
/* bridge */
$.fn.moreTogglable = function(){
/* convert arguments to array */
var args = Array.prototype.slice.call(arguments);
/* detect method call, if no, arguments[0] must be options */
var isMethodCall = (args.length > 0) && ($.type(args[0]) === 'string');
var method = isMethodCall ? args[0] : undefined;
var options = isMethodCall ? undefined: args[0];
/* jQuery's methods return jQueryObject right? */
var returnValue = this;
if(isMethodCall){
/* bridge to class */
this.each(function(){
var $el = $(this);
var instance = $el.data('moreTogglable');
var res = instance[method].apply(instance, args.slice(1));
if( (res !== instance) && (res !== undefined) ){
returnValue = res;
}
});
}else{
/* normally */
this.each(function(){
var $el = $(this);
var instance = new $.MoreTogglable($el, options)
$el.data('moreTogglable', instance);
});
}
return returnValue;
};
/* let's do it */
$(function(){
$('.item').moreTogglable();
$('#b1').click(function(){
$(':moreTogglable').moreTogglable('open');
});
$('#b2').click(function(){
$(':moreTogglable').eq(0).moreTogglable('open');
});
$('#b3').click(function(){
$(':moreTogglable').moreTogglable('close');
});
$('#b4').click(function(){
$(':moreTogglable').eq(0).moreTogglable('close');
});
$('#b5').click(function(){
$(':moreTogglable').moreTogglable('toggle');
});
$('#b6').click(function(){
alert($(':moreTogglable').eq(0).moreTogglable('getSpeed'));
});
});
/* MoreTogglable class */
$.MoreTogglable = function(element, options){
this.options = $.extend({}, this.options, options);
this.$element = $(element);
this._setupElements();
this._eventify();
this._init();
};
$.MoreTogglable.prototype = {
/* options */
options: {
speed: 400,
selector_showMore: '.showMore',
selector_more: '.more',
selector_hideMore: '.hideMore'
},
/* elements */
$element: null,
$showMore: null,
$more: null,
$hideMore: null,
/* misc */
_isOpen: false,
/* private methods */
_setupElements: function(){
var $el = this.$element;
var o = this.options;
this.$showMore = $(o.selector_showMore, $el);
this.$more = $(o.selector_more, $el);
this.$hideMore = $(o.selector_hideMore, $el);
},
_eventify: function(){
this.$showMore.click( $.proxy(this.open, this) );
this.$hideMore.click( $.proxy(this.close, this) );
},
_init: function(){
this.$showMore.css('display','block');
this.$more.css('display','none');
},
/* public methods */
open: function(){
if(this._isOpen){
return;
}
this._isOpen = true;
var s = this.options.speed;
var self = this;
self.$showMore.slideUp(s);
self.$more.slideDown(s, function(){
self.$hideMore.slideDown(s, function(){
self.$element.trigger('moreopen');
});
});
},
close: function(){
if(!this._isOpen){
return;
}
this._isOpen = false;
var s = this.options.speed;
var self = this;
self.$hideMore.slideUp(s);
self.$more.slideUp(s, function(){
self.$showMore.slideDown(s, function(){
self.$element.trigger('moreclose');
});
});
},
toggle: function(){
if(this._isOpen){
this.close();
}else{
this.open();
}
},
getSpeed: function(){
return this.options.speed;
}
};
/* define custome selector */
$.expr[':'].moreTogglable = function(element){
return Boolean($.data(element, 'moreTogglable'));
};
/* bridge */
$.fn.moreTogglable = function(){
/* convert arguments to array */
var args = Array.prototype.slice.call(arguments);
/* detect method call, if no, arguments[0] must be options */
var isMethodCall = (args.length > 0) && ($.type(args[0]) === 'string');
var method = isMethodCall ? args[0] : undefined;
var options = isMethodCall ? undefined: args[0];
/* jQuery's methods return jQueryObject right? */
var returnValue = this;
if(isMethodCall){
/* bridge to class */
this.each(function(){
var $el = $(this);
var instance = $el.data('moreTogglable');
var res = instance[method].apply(instance, args.slice(1));
if( (res !== instance) && (res !== undefined) ){
returnValue = res;
}
});
}else{
/* normally */
this.each(function(){
var $el = $(this);
var instance = new $.MoreTogglable($el, options)
$el.data('moreTogglable', instance);
});
}
return returnValue;
};
/* let's do it */
$(function(){
$('.item')
.moreTogglable()
.bind('moreopen', function(){
$.fixedConsole.log('opend!');
})
.bind('moreclose', function(){
$.fixedConsole.log('closed!');
});
});
/* $.ui.moreTogglable */
$.widget('ui.moreTogglable', {
/* options */
options: {
speed: 400,
selector_showMore: '.ui-moreTogglable-showMore',
selector_more: '.ui-moreTogglable-more',
selector_hideMore: '.ui-moreTogglable-hideMore'
},
/* elements */
$showMore: null,
$more: null,
$hideMore: null,
/* misc */
_isOpen: false,
/* initializers */
_create: function(){
this.widgetEventPrefix = 'more.';
this._setupElements();
this._eventify();
return this;
},
_init: function(){
this.$showMore.css('display','block');
this.$more.css('display','none');
return this;
},
/* private methods */
_setupElements: function(){
var $el = this.element;
var o = this.options;
this.$showMore = $(o.selector_showMore, $el);
this.$more = $(o.selector_more, $el);
this.$hideMore = $(o.selector_hideMore, $el);
return this;
},
_eventify: function(){
this.$showMore.click( $.proxy(this.open, this) );
this.$hideMore.click( $.proxy(this.close, this) );
return this;
},
/* public methods */
open: function(){
if(this._isOpen){
return this;
}
this._isOpen = true;
var s = this.options.speed;
var self = this;
self.$showMore.slideUp(s);
self.$more.slideDown(s, function(){
self.$hideMore.slideDown(s, function(){
self._trigger('open');
});
});
return this;
},
close: function(){
if(!this._isOpen){
return this;
}
this._isOpen = false;
var s = this.options.speed;
var self = this;
self.$hideMore.slideUp(s);
self.$more.slideUp(s, function(){
self.$showMore.slideDown(s, function(){
self._trigger('close');
});
});
return this;
},
toggle: function(){
if(this._isOpen){
this.close();
}else{
this.open();
}
return this;
},
getSpeed: function(){
return this.options.speed;
}
});
/* let's do it */
$(function(){
$(':ui-moreTogglable').live('more.create', function(){
$.fixedConsole.log('moreTogglable attached.');
});
$('.ui-moreTogglable')
.moreTogglable()
.bind('more.open', function(){
$.fixedConsole.log('opend!');
})
.bind('more.close', function(){
$.fixedConsole.log('closed!');
});
});
私見ですが・・・
印象としては、DOM→jQueryオブジェクトで基本立ち回るものの、複雑なことすることもあるので裏でこそっとクラスインスタンスが立ち回る感じ。step7,8,9はやらんでいいかも。
<button id="start">START</button> <button id="reset">RESET</button> <button id="clearlog">CLEAR LOG</button> <div class="ui-indicator"><div class="bar"></div></div> <div class="ui-tiles"></div> <ul class="ui-console"></ul>
$(function(){
var $indicator = $('.ui-indicator').indicator();
var $console = $('.ui-console').console();
var $tiles = $('.ui-tiles')
.tiles()
.bind('tiles.start', function(){
$console.console('log', 'tiles started');
})
.bind('tiles.add', function(){
var percentage = $tiles.tiles('getPercentage');
$console.console('log', percentage + '%');
$indicator.indicator('update', percentage);
})
.bind('tiles.filled', function(){
$console.console('log', 'Filled!');
});
$('#start').bind('click', function(){
$tiles.tiles('start');
});
$('#reset').bind('click', function(){
$tiles.tiles('reset');
$indicator.indicator('reset');
});
$('#clearlog').bind('click', function(){
$console.console('clear');
});
});
各widgetには
その役割しかさせない
終わり
0 / 0