jQueryプラグイン作成のための勉強でフレーム内でコンテンツをスライド表示させるプラグインを作ってみました。ulリストタグで括られたコンテンツをスライド表示させるプラグイン作成でのプロセスメモ書きです。
前回のポストjQueryメモ jQueryプラグイン勉強 attached json作成に続いて、今度はフレームスライドプラグインを作ってみました。フレームタイプのスライドプラグインといえば、
などを取り上げることができます。今回はいくつかのフレーム内でのスライドプラグインのソースを読んでみた中でAccessible News Slider: A jQuery Plugin がlocationアドレスにも影響与えないものでしたので、そちらをベースに自分なりに思ってみたものを作成。最終的には、再びYungSangの助けを受けて完成という形になりました。
以下が出来上がったプラグインで表示させたものです。インデックスページなどで、画像はじめ最新記事、特定カテゴリの記事などをスライド形式で表示させることができます。もちろんリスト形式タグのものをスライド表示させます。
追記:6月8日 23:30 読者の方からバグのご指摘があり、コード修正しました。settings部分を移動。psychedesire thx.
Please Note:お使いのブラウザでJavaScriptの設定が無効になっていると、サービス内の機能が限定されたり、サービスそのものが利用できなかったりする場合があります。 Yahoo! JAPANのページ全般 ヘルプ - JavaScriptの設定方法を読んでjavascriptの設定を有効にしてください。
Please Note: You may have disabled JavaScript and/or CSS. Although this news content will be accessible, certain functionality is unavailable.
前回と同じく、忘れないようにメモ残しておきます。
まずは基本HTMLから
<div class="frameslider" id="example_1">
<p class="javascript_css">
<strong>Please Note:</strong>お使いのブラウザでJavaScriptの設定が無効になっていると、サービス内の機能が限定されたり、サービスそのものが利用できなかったりする場合があります。 <a href='http://help.yahoo.co.jp/help/jp/common/sys/sys-07.html' title='Yahoo! JAPANのページ全般 ヘルプ - JavaScriptの設定方法'>Yahoo! JAPANのページ全般 ヘルプ - JavaScriptの設定方法</a>を読んでjavascriptの設定を有効にしてください。
</p>
<ul>
<li>
<p>contents</p>
</li>
</ul>
<span class="prev"><a href="#" rel="prev">back</a></span>
<span class="next"><a href="#" rel="next">next</a></span>
</div>
まず、最初に自分で作ったソースが以下。safari,IEにてクリックイベントの伝達がされないというバグがあるもので2日ほどいろいろと考えた挙句、YungSangに質問。
(function($){
var defaults = {
headline : "Top Stories",
speed : 1500,
slideBy : 2
};
// Our plugin implementation code goes here.
$.fn.extend({
slideframe : function(settings) {
// Extend our default options with those provided.
options = $.extend(defaults, settings);
return this.each(function() {
var $frame = this;
$( ".javascript_css", $frame ).css( "display", "none" );
initialize(settings, $frame);
});
}
});
initialize = function (settings,$frame) {
var $ul = $("ul:eq(0)",$frame).addClass("frame");
var $li = $ul.children();
var $lisize = $li.size();
var $liwidth = $li.width();
var $liheight = $li.height();
if( $lisize > settings.slideBy ) {
var $wrapper = $("<div/>").addClass("framewrapper").appendTo($frame).append($ul);
$wrapper.css({width: $liwidth * settings.slideBy});
$(".prev",$frame).css({top: $liheight/2});
$(".next",$frame).css({top: $liheight/2});
$ul.css("width", ( $liwidth * $lisize ) );
$(".next a",$frame).click(function() {
slideleft = parseInt($ul.css("left") ) - ( $liwidth * settings.slideBy );
if ( slideleft + $ul.width() > 0 ) {
$("ul.frame",$frame).animate({
left: slideleft
}, settings.speed );
$(".prev a",$frame).css("display", "block");
} else {
$ul.animate({
left: 0
}, settings.speed );
}
return false;
});
$(".prev a",$frame).click(function() {
slideright = parseInt( $ul.css("left") ) + ( $liwidth * settings.slideBy );
if ( slideright + $ul.width() <= $ul.width() || 0 ) {
$ul.animate({
left: slideright
}, settings.speed );
} else {
$ul.animate({
left : - ( slideright * ( parseInt( $lisize / settings.slideBy ) ) )
}, settings.speed );
}
return false;
});
}
};
})(jQuery);
YungSangに質問し、すぐに返事を頂きました。ulのleftに初期値が設定されていないために、初回のスライドさせるスパンがブラウザ側に伝えることができなかったとのこと。初期値設定することでバグ解消。というか、レスポンススピードが速くてびっくりしました。再び、好意で修正ソースまでも作っていただき、それが以下。
今回のソースを見て、javascriptの書き方やjQuery特有のクロスチェーンや各オブジェクトに対しての関数の振る舞い・使い方について勉強することができました。上記のソースと以下のソースを比べるみるとわかるとおもいます。同じような振る舞いをさせる関数であっても、シチュエーションに合せて意味あるものを使うというか、もっとjQuery関数を覚えないとと実感しました。
(function($){
// Our plugin implementation code goes here.
$.fn.extend({
slideframe : function(settings) {
var defaults = {
headline : 'Top Stories',
speed : 1500,
slideBy : 2
};
// Extend our default options with those provided.
settings = $.extend(defaults, settings);
return this.each(function() {
initialize(settings, $(this));
});
}
});
var initialize = function (settings, $frame) {
$('.javascript_css', this).hide();
var $ul = $('ul:eq(0)', $frame).addClass('frame').css('left', 0);
var $li = $('li', $ul);
var liSize = $li.size();
var liWidth = $li.width();
var liHeight = $li.height();
if (liSize <= settings.slideBy) return;
var $wrapper = $('<div/>').addClass('framewrapper').appendTo($frame).append($ul);
$wrapper.css({width: (liWidth * settings.slideBy) + 'px'});
$ul.css('width', (liWidth * liSize) + 'px');
$('.next a', $frame).css({top: liHeight/2 + 'px'}).click(function() {
var slideLeft = parseInt($ul.css('left')) - (liWidth * settings.slideBy);
//console.log(slideLeft);
if ((slideLeft + $ul.width()) > 0) {
$('ul.frame', $frame).animate({
left: slideLeft + 'px'
}, settings.speed);
$('.prev a', $frame).show();
} else {
$ul.animate({
left: 0
}, settings.speed);
}
return false;
});
$('.prev a', $frame).css({top: liHeight/2 + 'px'}).click(function() {
var slideRight = parseInt($ul.css('left')) + (liWidth * settings.slideBy);
//console.log(slideRight);
if (slideRight <= 0) {
$ul.animate({
left: slideRight + 'px'
}, settings.speed);
} else {
$ul.animate({
left : (-1 * slideRight * Math.floor(liSize / settings.slideBy)) + 'px'
}, settings.speed);
}
return false;
});
};
})(jQuery);
YungSang、今回も大変勉強になる修正コードありがとうございました。
上記の修正コードにリンクを生成するようにコードを追加し、リンクに対してのCSSの設定の部分を編集したものが以下となります。最初は、テキストリンクをHTMLの中に埋め込んでいましたが、結局、コードの中で生成するように変更しました。
追記:6月8日 23:30 読者の方からバグのご指摘があり、コード修正しました。settings(defaults)部分を移動。psychedesire thx.
(function($){
// Our plugin implementation code goes here.
$.fn.extend({
slideframe : function(settings) {
var defaults = {
headline : 'Top Stories',
speed : 1500,
slideBy : 2
};
// Extend our default options with those provided.
settings = $.extend(defaults, settings);
return this.each(function() {
initialize(settings, $(this));
});
}
});
var initialize = function (settings, $frame) {
$('.javascript_css', $frame).hide();
var $ul = $('ul:eq(0)', $frame).addClass('frame').css('left', 0);
var $li = $('li', $ul);
var liSize = $li.size();
var liWidth = $li.width();
var liHeight = $li.height();
if (liSize <= settings.slideBy) return;
var $wrapper = $('<div/>').addClass('framewrapper').appendTo($frame).append($ul);
$wrapper.css({width: (liWidth * settings.slideBy) + 'px'});
$wrapper.after($('<span/>').addClass('next').append($('<a/>').attr({href:'#',rel:'next'}).text('next≫')));
$wrapper.after($('<span/>').addClass('prev').append($('<a/>').attr({href:'#',rel:'prev'}).addClass('off').text('≪back')));
$ul.css('width', (liWidth * liSize) + 'px');
$('.next a', $frame).css({top: liHeight/2 + 'px'}).click(function() {
var slideLeft = parseInt($ul.css('left')) - (liWidth * settings.slideBy);
//console.log(slideLeft);
if ((slideLeft + $ul.width()) > 0) {
$('ul.frame', $frame).animate({
left: slideLeft + 'px'
}, settings.speed);
$('.prev a', $frame).removeClass('off');
} else {
$ul.animate({
left: 0
}, settings.speed);
}
return false;
});
$('.prev a', $frame).css({top: liHeight/2 + 'px'}).click(function() {
var slideRight = parseInt($ul.css('left')) + (liWidth * settings.slideBy);
//console.log(slideRight);
if (slideRight <= 0) {
$ul.animate({
left: slideRight + 'px'
}, settings.speed);
} else {
$ul.animate({
left : (-1 * slideRight * Math.floor(liSize / settings.slideBy)) + 'px'
}, settings.speed);
}
return false;
});
};
})(jQuery);
基本HTMLは以下のようになります。
<div class="frameslider" id="example_1">
<p class="javascript_css">
<strong>Please Note:</strong>お使いのブラウザでJavaScriptの設定が無効になっていると、サービス内の機能が限定されたり、サービスそのものが利用できなかったりする場合があります。 <a href='http://help.yahoo.co.jp/help/jp/common/sys/sys-07.html' title='Yahoo! JAPANのページ全般 ヘルプ - JavaScriptの設定方法'>Yahoo! JAPANのページ全般 ヘルプ - JavaScriptの設定方法</a>を読んでjavascriptの設定を有効にしてください。
</p>
<ul>
<li>
<p>contents</p>
</li>
</ul>
</div>
header内での記述が以下となります。
<script type="text/javascript">
$(document).ready(function(){
$( "#example_1" ).slideframe({
speed : "normal",
slideBy : 2
});
$( "#example_2" ).slideframe({
speed : "normal",
slideBy : 3
});
});
</script>
あとは、このプラグインと前回のjQueryメモ jQueryプラグイン勉強 attached json作成プラグインとinnerfadeプラグインを一つのパッケージにしてみようと考えています。もう少しjQueryプラグイン内でのオブジェクトの扱いについて、いろんなソースを読んでからまとめてみようと思います。ゆくゆくは、今使っているjQueryプラグインを一つのパッケージにするという前提もあります。(最近、yslowの記事など読んでて、spliteやjavascriptのコードパッケージについて意識したりしてます。Best Practices for Speeding Up Your Web Site)
jQueryプラグインについては、これでインデックスページ部分はOK。タブ表示に関してもOKで、後はjQuery 1.3.2 日本語リファレンス内でも使われているLive Search with Quicksilver Style // Ordered List // We Make The Web Beautifully Simpleか最近githubに公開されたnakajima's jquery-livesearch at master - GitHubなどのソースを読んでみて、自分で扱いやすいものをこのMTに実装しようと考えています。MTでDBを構築できるのであとは、それらをいかに早く検索・表示できるようにするかなんてことに挑戦してみようかと。
いやぁーそれにしても美しいコードを書くということに対してもっと意識を持たないといけませんね。勉強になりました。
はじめまして~。
FriendFeedでYungSangとのやり取りを眺めてました~。
上のサンプルの最初の方(2個並んでるヤツ)が、
1,2 -> 3,4 -> 5,6 -> 7,8 -> 9,10 ->11
ってならないで、
1,2 -> 4,5 -> 7,8 -> 10,11
ってなります。3と5と9が飛んじゃいます。
Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)
でなりました。
ご報告でした~。
>psychedesire さん
はじめまして、あっ!?そうですね。飛んでます。あれー、二つ重ねて表示させると飛んじゃいますね。これじゃダメですね。ちょっと調べてから追記します。教えていただきありがとうございます。これからもよろしくです。
>psychedesire さん
コメントありがとうございました。ご指摘いただいた点、修正しました。
settingsでのdefaultsのオブジェクトを移動させました。ちょっと理由がわからないのですが、
また理由がわかりましたらご連絡いれます。今回はありがとうございました。