jQueryプラグインの書き方について勉強してみました。忘れないようにメモ書き。JSONデータを読み込み、タブ形式 でjQueryプラグインinnerfadeを使って表示する他のプラグインを拡張するようなプラグイン的なものを作成しました。
jQueryプラグイン作成の勉強をしました。ちょっとつかめたかなぁーといった感じです。今回は汎用的なプラグインではなく、個でしか扱えないタイプなんですが、以下のようなもの、jsonデータからinnerfadeで表示させる、jQueryプラグインInnerFade with jqueryを拡張するようなものを作って勉強してみました。一応わすれないようにメモ書き。
まずは、javascriptの基本をオライリー本で勉強。
オライリー・ジャパン
売り上げランキング: 9354

JavaScripterに捧げる本
JavaScriptを理解したいのならだまされたと思って読んでください
初心者には難しいです
買って良かった
多少冗長な感じがします
その後、オブジェクトについて下記のサイトで勉強。非常にわかりやすかったです。
- amachang - JavaScript 入門
- http://amachang.art-code.org/usrb.in/amachang/static/gaiax01/
- [ThinkIT] 第1回:Prototype.jsを使う準備 (1/2)
- http://www.thinkit.co.jp/free/article/0702/15/1/
その後、以前YungSangに作ってもらい、公開したjQueryでTwitterブログパーツ iTwitter(iPhone仕様)完成iTwitterのスクリプトを再度勉強し直しました。
jQueryプラグイン作成についての勉強は以下のサイトなどを参考にして、作成のための基本形などを勉強。
- jQuery プラグインを書くときのポイント - Higé au lait
- jQuery 1.3.2 日本語リファレンス
- Building jQuery plugins | webcloud jMar's Blog: Building Your First jQuery Plugin
- A Plugin Development Pattern » Learning jQuery - Tips, Techniques, Tutorials
後は、以下の記事などを読んで、他のプラグインなど作成に挑戦してみようかなと思っています。
Making a jQuery Plugin Truly Customizable » Learning jQuery - Tips, Techniques, Tutorials
まず、最初はオブジェクトにして単体でjsonデータからinnerfade表示させるものを作りました。
var slidegallery = {
var obj = $('div.slide');
var tabs = $('ul.slidetag li a', obj);
var tabContent = $('div.images', obj);
show: function(data) {
var list = '<ul class="gallerylist">';
$.each(data.items, function(i,item){
var title = (item.title) ? item.title : "none";
var url = item.url;
var img = item.thumbnail;
list += '<li><a href="'+url+'" class="highslide" onclick="return hs.expand(this)"><img src="';
list += img+'" alt="Highslide JS" title="Click to enlarge" height="100px" /></a><div class="highslide-caption"><p>';
list += title+'</p><ul class="exif">';
$.each(item.exifinfo, function(key,value){
list+='<li>'+key+':'+ value+'</li>';
});
list+= '</ul></div></li>';
});
list+= '</ul>';
tabContent.height(300).css('overflow','hidden').empty();
tabContent.append(list);
$('ul.gallerylist').innerfade({
speed: 'slow',
timeout: 1500,
type: 'sequence'
});
},
get: function(tag) {
var url = 'http://weblibrary.s224.xrea.com/mt4plugins/asset_'+tag+'.json';
$.getJSON(url, function(data){slidegallery.show(data);});
return false;
}
};
$(function() {
slideglalery.element();
tabs.click(function() {
$(".selected").removeClass();
$(this).parent().addClass("selected");
var tag = $(this).text();
return slidegallery.get(tag);
}).filter(':first').click();
});
次に同一ページ内に複数要素扱えるようにするためのものを作成。以下のようなパターン。すべて違う設定で表示するように設定しています。これで同一ページで同じスクリプトを使って内容が異なるものをタブ型innerfadeで表示できるようになります。
jsonデータを深くネストさせないようにし、生成形式を統一することで同じパターンのものがいくつも作れるようになります。(今回は、jsonデータは同じですが、表示速度・フェード間隔が異なります。)
上記表示のための基本HTMLが以下となります。
<div class="slide"> <ul class="slidetag"> <li><a href="#json"><em>json</em></a></li> <li><a href="#sample"><em>sample</em></a></ll> <li><a href="#wedding"><em>wedding</em></a></li> </ul> <div class="images">gallery here</div> </div> <div class="slide2"> <ul class="slidetag"> <li><a href="#json"><em>json</em></a></li> <li><a href="#sample"><em>sample</em></a></ll> <li><a href="#wedding"><em>wedding</em></a></li> </ul> <div class="images">gallery here</div> </div> <div class="slide3"> <ul class="slidetag"> <li><a href="#json"><em>json</em></a></li> <li><a href="#sample"><em>sample</em></a></ll> <li><a href="#wedding"><em>wedding</em></a></li> </ul> <div class="images">gallery here</div> </div>
以下がhead内に記述するコード。
<link rel="stylesheet" href="<$mt:BlogURL$>css/slidegallery.css" type="text/css" />
<script type="text/javascript" src="<$mt:BlogURL$>js/slidegallery.js"></script>
<script type="text/javascript" src="<$mt:BlogURL$>js/jquery.innerfade.js"></script>
<script type="text/javascript">
$(function(){
$('div.slide').slidergallery({
speed: 'high',
timeout: 4000
});
$('div.slide2').slidergallery({
speed: 'slow',
timeout: 1500
});
$('div.slide3').slidergallery({
speed: 'slow',
timeout: 7000
});
});
</script>
動作がおかしいところがあったので、YungSangにコードをみてもらい、1ヶ所抜けている点の指摘を受け(innerfadeにオブジェクトを渡す所でマッチさせるようにしていなかった)、修正、正常動作するようになったのが以下のコード。
(function($){
$.fn.extend({
slidergallery: function(options) {
var defaults = {
baseurl: 'http://weblibrary.s224.xrea.com/mt4plugins/asset_',
speed: 'slow',
timeout: 1500,
type: 'sequen'
};
// Extend our default options with those provided.
var options = $.extend(defaults, options);
return this.each(function() {
var obj = $(this);
var tabs = $('ul li a', obj);
var tabContent = $('div',obj);
tabs.click(function(){
$('li.selected', obj).removeClass();
$(this, obj).parent().addClass("selected");
var tag = $(this, obj).text();
var images = $('div.images', obj);
var url = options.baseurl+tag+'.json';
$.getJSON(url, function(data){
var list = '<ul class="gallerylist">';
$.each(data.items, function(i,item){
var title = (item.title) ? item.title : "none";
var url = item.url;
var img = item.thumbnail;
list += '<li><a href="'+url+'" class="highslide" onclick="return hs.expand(this)"><img src="';
list += img+'" alt="Highslide JS" title="Click to enlarge" height="100px" /></a><div class="highslide-caption"><p>';
list += title+'</p><ul class="exif">';
$.each(item.exifinfo, function(key,value){
list+='<li>'+key+':'+ value+'</li>';
});
list+= '</ul></div></li>';
});
list+= '</ul>';
tabContent.empty();
tabContent.append(list);
$('ul.gallerylist',tabContent).innerfade({
speed: options.speed,
timeout: options.timeout,
type: 'sequence'
});
});
return false;
}).filter(':first').click();
});
}
});
})(jQuery);
が、「コードが深すぎて読みづらいですね(追いにくい)」というご指摘を受けて(自分でもそう思っていた)、普通の関数を分けて作ってみてはというアドバイスで関数分けて作成したものが以下のコード。
(function($){
$.fn.extend({
slidergallery: function(options) {
var defaults = {
baseurl: 'http://weblibrary.s224.xrea.com/mt4plugins/asset_',
speed: 'slow',
timeout: 1500,
type: 'sequence'
};
var options = $.extend(defaults, options);
return this.each(function() {
var obj = $(this);
var tabs = $('ul li a', obj);
var tabContent = $('div',obj);
tabs.bind('click', onclick).filter(':first').click();
function onclick(tabs){
var tag = $(this).text();
$('li.selected', obj).removeClass();
$(this).parent().addClass('selected');
get_image(tag);
};
function show_image(data){
var list = '<ul class="gallerylist">';
$.each(data.items, function(i,item){
var title = (item.title) ? item.title : "none";
var url = item.url;
var img = item.thumbnail;
list += '<li><a href="'+url+'" class="highslide" onclick="return hs.expand(this)"><img src="';
list += img+'" alt="Highslide JS" title="Click to enlarge" height="100px" /></a>';
list += '<div class="highslide-caption"><p>';
list += title+'</p><ul class="exif">';
$.each(item.exifinfo, function(key,value){
list+='<li>'+key+':'+ value+'</li>';
});
list+= '</ul></div></li>';
});
list+= '</ul>';
tabContent.empty().append(list);
$('ul.gallerylist',tabContent).innerfade({
speed: options.speed,
timeout: options.timeout,
type: options.type
});
};
function get_image(tag){
var url = options.baseurl+tag+'.json';
$.getJSON(url, function(data){show_image(data);});
return false;
};
});
}
});
})(jQuery);
デフォルト設定、設計フローもおかしかったのですが、最終的にはYungSangの好意で簡単な修正コードを作ってもらい今現在それを使っています。いつも助けていただいてばかりで・・・。
オブジェクトを追いやすい、可読しやすいコードで大変勉強になりました。他にも細かい点で質問などいろいろと教えていただき、感謝しています。ありがとうございます。
(function($){
var defaults = {
baseurl: 'http://weblibrary.s224.xrea.com/mt4plugins/asset_',
speed: 'slow',
timeout: 1500,
type: 'sequen'
};
// Our plugin implementation code goes here.
$.fn.extend({
slidergallery : function(options) {
// Extend our default options with those provided.
options = $.extend(defaults, options);
return this.each(function() {
var $slide = $(this);
$('ul.slidetag li a', $slide).bind('click', function() {
onclick.call(this, $slide);
return false;
}).filter(':first').click();
});
function onclick($slide){
$('li.selected', $slide).removeClass('selected');
var $a = $(this).parent().addClass('selected');
get_image($a.text(), $slide);
};
function get_image(tag, $slide) {
var url = options.baseurl + tag + '.json';
$.getJSON(url, function(data){
show_image(data, $slide);
});
};
function show_image(data, $slide) {
var list = '<ul class="gallerylist">';
$.each(data.items, function(i, item){
var title = (item.title) ? item.title : "none";
var url = item.url;
var img = item.thumbnail;
list += '<li>';
list += '<a href="'+url+'" class="highslide" onclick="return hs.expand(this)"><img src="'+img+'" alt="Highslide JS" title="Click to enlarge" height="100px" /></a>';
list += '<div class="highslide-caption"><p>'+title+'</p>';
list += '<ul class="exif">';
$.each(item.exifinfo, function(key, value){
list+='<li>'+key+':'+ value+'</li>';
});
list+= '</ul>';
list+= '</div>';
list+= '</li>';
});
list+= '</ul>';
var $images = $('div.images', $slide).empty().append(list);
$('ul.gallerylist', $images).innerfade({
speed: options.speed,
timeout: options.timeout,
type: 'sequence'
});
};
}
});
})(jQuery);
あとは、これを参考にして、もう一つプラグインを拡張できるようにオブジェクトを追加してみようかとも考えています。このAccessible News Slider: A jQuery Pluginで表示もできるように。jsonからデータ読み込み、innerfadeを適用させるか、AccessibleNewsSliderで表示させれるかを条件分岐させるだけでいいんじゃないかと。それかcodasliderのコードが意外と読みやすいのでそちらを真似してNewsSlider風で表示できるようにしてみようかとも考えています。
今回は、jQueryプラグイン作成の為の基礎的なものとjavascriptコードを書く際の注意などYungSangの助けを受け勉強することができました。またちょっと楽しくなってきました。FriendFeedのiTwitterバージョンを作らないと。FriendFeedだとAPI制限が緩いのでブログパーツも少しは作りやすいです。





コメントする