09 | 2017/10 |  11

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

 

jquery.js のアニメーションコードの活用 ( 3 ) slideToggleEx プラグインの簡便な活用のために(不完全版)

このエントリイで言及し掲載した slideToggleEx プラグインは不完全でした。完全版はエントリイ No. 733 をご覧ください。

slideToggleEx プラグインの簡便な活用方法が必要だ

jquery.js の自作プラグイン slideToggleEx を実際に各エントリイ内で随時利用するためには、簡便な利用方法を作っておく必要があります。こうした自らの需要に基づいて以下の方法をまとめました。

用意するもの・ことは以下の 5 つです。
  1. include 用 slideToggleEx プラグインファイルと include タグ要素
  2. slideToggleEx が適用されるタグ要素
  3. 起終点を右側にする場合には、対象タグ要素に width スタイル属性を設定します。また起終点を下にする場合には height スタイル属性を設定します。そうしないと animate メソッドの中で適正な幅や高さが計測されない場合があるためです。
  4. slideToggleEx を呼び出し、適用させるタグ要素(一般的には button タグでしょう)
  5. その button タグのクラス属性に fireSlideToggleEx-n を追加します。( n は 0 から 8 の整数)

n は起終点を意味し次の通りの意味を持ちます。

0:ボックスの中心、1:左上端、2:右上端、3:右下端、4:左下端、
5:上辺、6:右辺、7:下辺、8:左辺

これだけ設定すれば、トリガーである button をクリックすると、n で指定した位置を起終点として、トリガーボタンの直後に配置された要素が slideToggleEx 適用対象要素となり、隠蔽されたり表示されるようなコード( エントリイ末尾に掲載 )を書きました。

「 これだけ 」と言っても結構たくさんあるため、最初は面倒に感じますが、直ぐに慣れますし、実際に使ってみると決して大変な手間ではありません。

必要な HTML 構造

上の 5 つだけで、slideToggleEx プラグインが簡単に使えるようにするために、もう1つ該当部分の HTML 文を特別な構造にする必要があります。これが 6 つ目にして最後の要件となります。その要件とは起動ボタンの直ぐ後に slideToggleEx 対象要素があるということです。

そうでない場合には 個々に slideToggleEx メソッドを呼び出すコードを書くことになります。

該当部分の HTML を以下のいずれかにする必要があります。(いずれのケースもボックスの左上を起終点とする場合で例示します。)

■ケース 1
<div><button class="fireSlideToggleEx-1">起動ボタン</button></div>
<div>・・・slideToggleEx対象要素・・・</div>

■ケース 2
<button class="fireSlideToggleEx-1" style="display:block;width:120px;">起動ボタン</button>
<div>・・・slideToggleEx対象要素・・・</div>

※ 2 行目の div 要素は別に div でなくてもブロック要素ならば何でも構いません。

ケース 1 は一般的な button タグの使い方の場合です。つまり button タグを inline 要素として配置する場合の HTML 文です。この場合には button タグの親要素の next sibling ブロック要素が slideToggleEx メソッドの適用対象となるようにコードを作りました。

一方ケース 2 は button タグをブロック要素として配置する場合です。この場合には当該のボタンタグの next sibling ブロック要素が slideToggleEx メソッドの適用対象となるようにコードを作りました。

このような当然と思われるHTML文構成にしておけば、運用に当たってどのようにしたかを思い出すのも容易ですし、仮に構造を忘れても直感的に思い出すことが可能となります。

▲ToTop

以上の前提で作った slideToggleEx プラグイン活用コード

プラグインは position 無指定版と指定版の 2 種類を作りました。どちらも全く同様の動きをしますが、後者の方がコード全体のバランスがよいかもしれません。

当初 position 指定版を作成し、アニメ適用対象に position:relative をその都度指定していました。top と left をアニメ対象とするので、アニメ対象要素には static 以外の position 指定が為されていなければならないためです。しかし、slideToggleEx プラグインの運用を重ねるに連れ、その都度指定することが非常に面倒であることに気がつきました。

そこで改めて position 無指定版を作成したのですが、それが完成してから、ふと position 指定をコードで行えばよいことに気がつきました。そして、仮にアニメ対象に position 指定がされていない場合でも、相対指定となるよう、Javascript コードによって強制的に指定することにしました。

結果として、回り道をしてしまったのですが、このようなケアレスミスを犯すこと自体が、まだまだコード開発に不慣れである証明かもしれません。

こうして、今実際に使っている slideToggleEx プラグインメソッドは最初に作った版を改訂した position 指定版となりました。

なお、アニメ継続時間と easing 関数は、初期値を設定する slideToggleEx.opts オブジェクトにおいて、1 秒に設定し、easing は無指定としています。opts オブジェクトを変えれば、自在に継続時間と easing 関数を変更できますが、使う際にその都度 duration と easing 関数を変更する必要はないと考え、(1) 指定するボタンタグと (2) 指定されるブロックタグ及び (3) slideToggleEx-n クラス名を指定するだけで使えればよいと判断しました。

以下のコードリストの表示/隠蔽には当然ながら、slideToggleEx を適用しています。

▲ToTop

▼ver not use "position:relative/absolute" 
/* jQuery plugin : slideToggleEx() Release at 2009.8.21, ver2 at 2009.9.8*/
(function($){
var ver="absolute animation, non position assignment";
$.fn.slideToggleEx = function( type, duration, easing, fn ){
 $target=this;
 var o = $.extend({},$.fn.slideToggleEx.opts);
 // 初めてそのインスタンスから呼ばれたか、インスタンスが変わった場合のみ
 if(!o.target || o.target[0]!==$target[0]) {
  $.extend(o,{
   orig : o, // 当面使わないが念のために $.fn.slideToggleEx.opts をバックアップ
   target : $target, // jQuery インスタンスへの参照を登録する。
   // ボックスを show する時に初期のマージン値を使用するので記録しておく。
   initMTL:{marginTop:$target.css("margin-top"),marginLeft:$target.css("margin-left")},
   /* ボックスのマージン辺までの外枠サイズをゲットする。
    * 但し、jquery.js の 圧縮ファイルでは outerWidth(true) のように引数を指定しても
    * margin 辺までの外寸を取得しない。そこでやむなく引数を付けずに border 辺までの値を
    * 取得してから、それに margin 値を加算して margin 辺までの外寸を取得する。*/
   oH : $target.outerHeight() + parseInt($target.css("margin-top"))
    + parseInt($target.css("margin-bottom")),
   oW : $target.outerWidth() + parseInt($target.css("margin-left"))
    + parseInt($target.css("margin-right")), 
   // プラグイン起動回数が奇数か偶数かを記録するプロパティ
   odd : false
  });
  
  /* メモリ上の opts オブジェクトにこの上で作成したばかりの o オブジェクトを統合
   * して、初期値として保存する。同じインスタンスに対する 2 度目以降のプラグイン
   * 起動時には o オブジェクトに opts オブジェクトが転写され、かつこの if 条件は
   * falseとなるので if ブロックは履行されない。こうして効率的なコード進行となる。
   * また、2 度目以降のプラグイン起動が異なるインスタンスに対して行われた場合には
   * 2 番目の if 条件 o.target[0]!==$target[0] が true となるので、if ブロックが履行される。
   * こうして o オブジェクトも $.fn.slideToggleEx.opts オブジェクトも新しい
   * インスタンスの諸属性値を格納する。*/
  $.fn.slideToggleEx.opts = $.extend($.fn.slideToggleEx.opts,o);
 }
 
 /* 奇数回目か偶数回目か、起動回数を記録する。ここでは $.fn.slideToggleEx.opts
  * オブジェクトを利用して slideToggleEx メソッドの実行が終わった後も
  * odd 値を残しておくことがポイントである。*/
 o.odd = $.fn.slideToggleEx.opts.odd = !$.fn.slideToggleEx.opts.odd;
 o.hidden = $target.is(":hidden"); // アニメ対象が隠れているかどうか
 o.duration = duration || o.duration; // 第 2 引数か opts プロパティの利用
 // 第 3 引数か opts プロパティの利用。duration がオブジェクトの時には空。
 o.easing = typeof duration !=="object" ? (easing || o.easing) : "";
 // 第 4 引数か opts プロパティの利用。duration がオブジェクトの時には空。
 o.complete = typeof duration !=="object" ? ($.isFunction(fn) && fn || o.complete) : "";

 // アニメ用の CSS オブジェクトを作成する関数
 function makeAnimCSS(type,showhide){
  type = new Number(type);
  if (showhide === false) { // 隠蔽されている時のアニメ用 CSS 作成
   return type==0 ? {marginTop:o.oH/2+"px", marginLeft:o.oW/2+"px"}:// center
   type==1 ? {marginTop:0,marginLeft:0}: // 左上端
   type==2 ? {marginTop:0,marginLeft:o.oW + "px"}: // 右上端
   type==3 ? {marginTop:o.oH+"px", marginLeft:o.oW+"px"}:// 右下端
   type==4 ? {marginTop:o.oH+"px", marginLeft:0}: // 左下端
   type==5 ? {marginTop:0}: // 上辺
   type==6 ? {marginLeft:o.oW+"px"}:// 右辺
   type==7 ? {marginTop: o.oH+"px"}:// 下辺
   {marginLeft:0}; // 左辺
  // 表示されている時のアニメ用 CSS 作成
  // type 値が 5 と 7 の時にはトップ値のみ、6 と 8 の時にはレフト値のみ
  // 0 ~ 4 の時にはトップ値とレフト値を使用する。
  } else return (type==5 || type==7) ? {marginTop:o.initMTL.marginTop}
   : (type==6 || type==8) ? {marginLeft:o.initMTL.marginLeft} : o.initMTL;
 }

 if (type > 8) // エラー処理
  (function(){
   alert("第 1 引数は 0~8 だけが指定できます。\nやり直してください。\n"+
   "slideToggleEx( 0~8, 継続時間, easing関数, アニメ後実行関数)"); return;
  })();
 else { // type 値が 0 ~ 8 の時
  // アニメ用 CSS の最終作成( margin 以外のプロパティ値からなるオブジェクトに、
  // makeAnimCSS 関数で作ったオブジェクトを併合する)
  var obj =$.extend( {}, // margin 以外のプロパティ群
    ( type==5 || type==7 ) ? {} : o.animWidth,
    ( type==6 || type==8 ) ? {} : o.animHeight,
    {opacity:"toggle"} );
  /* 偶数回目の起動か、アニメ対象が隠蔽時の起動の時には、makeAnimCSS の
   * 第 2 引数を true に、奇数回目の起動か、アニメ対象が表示されている時には、
   * makeAnimCSS の第 2 引数を false にする。
   * これによりアニメ用 CSS 値を二通りの場合に対応させて作成する。*/
  $.extend(obj,(!o.odd || o.hidden) 
   ? makeAnimCSS(type,true) : makeAnimCSS(type,false));
  return this.animate(obj, o.duration, o.easing,o.complete); // アニメーション起動
 }
} // End of $.fn.slideToggleEx function

/* デフォルト値を slideToggleEx メソッドの opts プロパティに設定しておく。
 * このオブジェクトは slideToggleEx メソッドの実行が終わった後の情報記録装置
 * としても機能する。*/
$.fn.slideToggleEx.opts = {
 duration:1000, easing:null, complete:function(){},
 animHeight : { // 高さに係るアニメ CSS の既定値
  height:"toggle",marginTop:"toggle",marginBottom:"toggle",paddigTop:"toggle",
  paddingBottom:"toggle",borderTopWidth:"toggle",borderBottomWidth:"toggle"
 }, animWidth : { // 幅に係るアニメ CSS の既定値
  width:"toggle",marginLeft:"toggle",marginRight:"toggle",paddigLeft:"toggle",
  paddingRight:"toggle",borderLeftWidth:"toggle",borderRightWidth:"toggle"
 }
};
})(jQuery);

▲ToTop

▼ver use "position:relative"
// jQuery plugin : slideToggleEx() Release at 2009.8.21, verup 2009.9.9
(function($){
var ver="not absolute but relative animation on position relative";
// top と left プロパティによって起終点を操る position relative バージョン
$.fn.slideToggleEx = function( type, duration, easing, fn ){
 var $target = this;
 var o = $.extend({},$.fn.slideToggleEx.opts);
 // 初めてそのインスタンスから呼ばれたか、インスタンスが変わった場合のみ
 if(!o.target || o.target[0]!==$target[0]) {
  $.extend(o,{
   orig : o,
   target : $target,
   oH : $target.outerHeight() + parseInt($target.css("margin-top"))
    + parseInt($target.css("margin-bottom")),
   oW : $target.outerWidth() + parseInt($target.css("margin-left"))
    + parseInt($target.css("margin-right")),
   odd : false
  });
  $.extend($.fn.slideToggleEx.opts,o);
  if ($target.css("position") ==="static")
   $target.css({position:"relative",top:"0",left:"0"});
 }
 o.odd = $.fn.slideToggleEx.opts.odd = !$.fn.slideToggleEx.opts.odd;
 o.hidden = $target.is(":hidden");
 o.duration = duration || o.duration;
 o.easing = typeof duration !=="object" ? (easing || o.easing) : "";
 o.complete = typeof duration !=="object" ? ($.isFunction(fn) && fn || o.complete) : "";

 function makeAnimCSS(type,showhide){ // アニメCSSプロパティを作成する関数
  var type = new Number(type);
  var plmn = showhide ? "-=" : "+="; // showhide == true → "-="
  return type==0 ? {top: plmn + o.oH/2 +"px", left: plmn + o.oW/2 +"px"} : // center
  type==1 ? {top: plmn + 0, left: plmn + 0} : // 左上端
  type==2 ? {top: plmn + 0, left: plmn + o.oW +"px"} : // 右上端
  type==3 ? {top: plmn + o.oH +"px", left: plmn + o.oW +"px"} : // 右下端
  type==4 ? {top: plmn + o.oH +"px", left: plmn + 0} : // 左下端
  type==5 ? {top: plmn + 0, left: plmn + 0} : // 上辺
  type==6 ? {top: plmn + 0, left: plmn + o.oW +"px"} :// 右辺
  type==7 ? {top: plmn + o.oH +"px", left: plmn + 0} :// 下辺
  type==8 ? {top: plmn + 0, left:plmn + 0} : {top:plmn + 0, left:plmn + 0} ;// 左辺
 }

 if (new Number(type) > 8) // エラー対処
  (function(){
   alert("第 1 引数は 0~8 だけが指定できます。\nやり直してください。\n"+
   "slideToggleEx( 0~8, 継続時間, easing関数 )"); return;
  })();
 else {
  var obj = (!o.odd || o.hidden) 
   ? makeAnimCSS(type,true)  // 偶数回目の起動か、または要素が隠蔽されている時の CSS 作成
   : makeAnimCSS(type,false); // 奇数回目の起動か、要素が表示されている時の CSS 作成
  $.extend( obj, // top と left だけのCSSオブジェクトに幅と高さ関係値も追加
    ( type==5 || type==7 ) ? {} : o.animWidth, // 上辺か下辺の時には幅方向CSSは対象外
    ( type==6 || type==8 ) ? {} : o.animHeight, // 右辺か左辺の時には高さ方向CSSは対象外
    {opacity:"toggle"} ); // 透明度もアニメ対象プロパティとする
  return this.animate(obj, o.duration, o.easing, o.complete); // アニメ起動
 }
}; // End of $.fn.slideToggleEx

// 初期値設定とプロパティ記憶装置としての機能のために
// ※ これは position 無指定版と指定版に共通する同一のものです。
$.fn.slideToggleEx.opts = {
 duration:1000, easing:null, complete:function(){},
 animHeight : {
  height:"toggle",marginTop:"toggle",marginBottom:"toggle",paddigTop:"toggle",
  paddingBottom:"toggle",borderTopWidth:"toggle",borderBottomWidth:"toggle"
 }, animWidth : {
  width:"toggle",marginLeft:"toggle",marginRight:"toggle",paddigLeft:"toggle",
  paddingRight:"toggle",borderLeftWidth:"toggle",borderRightWidth:"toggle"
 }
};
})(jQuery);

▲ToTop

▼このコードは、メソッドプラグインではありませんが、プラグインとセットで include
 ファイルに登録しておくと重宝します。これがないと fireSlideToggleEx-n のクラス指定を
 しても next sibling 要素などを slideToggleEx の適用対象とすることは出来ません。
/* regist click Event to fire slideToggleEx() for nextBlock
 * クリックイベント起動ボタンと slideToggleEx 適用対象を登録する。
 * これも position 無指定版、指定版に共通するコードです。*/
 1:$(function(){ // 当然 DOM が Ready されてから起動する必要があります。
 2: var duration = 1000, easing = null,fn = function(){}, clk = {};
 3: function func(i){
 4:  $.each(clk[i],function(){
    // target オブジェクトは slideToggleEx 対象の個々のノード 1 つだけを格納する。
 5;   var $target={};
     // $target オブジェクトの j プロパティに slideToggleEx 対象ノードを格納する。
     // fireSlideToggleEx-x クラス指定されたボタン要素がブロック要素の場合には
     // next siblingを block 以外の inline 要素の場合には親要素の
     // next sibling 要素を slideToggleEx 対象とする。
 6:   $target[i] = $(this).css("display")=="block" ? $(this).next() : $(this).parent().next();
 7:   if ($target[i].length) {
 8:    $(this).click(function(){
       // IE においては右側をアニメ起終点にすると固まる事が多いので、
       // 強制的に同種の左側起終点に指定を替える。
 9:     if (jQuery.browser.msie)
10:      var k = i==2 && 1 || i==3 && 4 || i==6 && 8 || i;
11:     else k=i;
       // slideToggleEx を起動する。
12:     $target[i].slideToggleEx(k, duration, easing, fn);
13:     $(this).blur(); // ボタン要素のフォーカスを外す
14:    });
15:   }
16:  });
17: }
18: for (var i=0; i<9; i++){ // 0 から 8 迄の巡回処理
    // クリックイベントを登録するオブジェクト clk の i プロパティを作成し、
    // それに "fireSlideToggleEx-i"( i は 0~8 ) class 名のノードをもつ
    // jQuery インスタンスを登録する。これにより、ページ内にある
    // fireSlideToggleEx-n クラス名を持つノードを捉える。
19:  clk[i] = $(".fireSlideToggleEx-" + i);
    // i 番名のノードがなければ loop の先頭行に戻って i++ する。
20:   if (!clk[i].length) continue;
    // i 番名のノードが存在した場合には、当該インスタンスの
    // 各ノード毎に巡回処理を行うために func 関数を呼び出す。
21:  func(i);
22:  clk[i].hover( // マウスオーバー/アウト時のボタン背景色の変更
23:   function(){$(this).css({backgroundColor:"pink"})},
24:   function(){$(this).css({backgroundColor:""})}
25:  )
26:  // マウスが押し下げられた場合の色替え
27:  .mousedown(function(){$(this).css('background-color','palegreen')})
28: }
29:});

▲ToTop

コード作成上の苦労話

非常に苦労したのは、slideToggleEx プラグインの再起動の際に、従前値を保持させる措置でした。

無名関数のトップレベルで、slideToggleEx メソッド外に変数を用意すれば解決することなのですが、是が非でもプラグインのメソッド外に変数を置かないでまとめたかったので、拘ってコードを作りました。

その結果、メソッド外となる点では変わらないのですが、『Javascript 第 5 版』p.144 や cycle プラグインを参考にして slideToggleEx メソッドのプロパティに値を保持させることにしました。

この点は極めて重要なポイントなので、じっくりと記述することにします。

メソッド実行が終わるとその中で定義された変数は消失してしまうので、当該メソッドの起動回数を記憶させる変数は当該メソッド外になければなりません。しかし外に変数を置くのは美しくありません。

そこでメソッドのプロパティを記憶装置にすることにしました。

そのことについて具体的にコードに触れながら、以下で説明したいと思います。

▲ToTop

メソッドのプロパティに情報を記録させる方法
 1: var $target=this;
 2: var o = $.extend({},$.fn.slideToggleEx.opts);
 3: // 初めてそのインスタンスから呼ばれたか、インスタンスが変わった場合のみ
 4: if(!o.target || o.target[0]!==$target[0]) {
 5:  $.extend(o,{
 6:   orig : o,
 7:   target : $target,
 8:   oH : $target.outerHeight() + parseInt($target.css("margin-top"))
 9:    + parseInt($target.css("margin-bottom")),
10:   oW : $target.outerWidth() + parseInt($target.css("margin-left"))
11:    + parseInt($target.css("margin-right")),
12:   odd : false
13:  });
14:  $.fn.slideToggleEx.opts = $.extend($.fn.slideToggleEx.opts,o);
15:  if ($target.css("position") ==="static")
16:   $target.css({position:"relative",top:"0",left:"0"});
17: }
18: o.odd = $.fn.slideToggleEx.opts.odd = !$.fn.slideToggleEx.opts.odd;

上の 18 行のコードは slideToggleEx プラグイン( position 指定版 )の最初の部分から抽出したものです。

  1. まずインスタンスへの参照を $target 変数に登録します(#1)。

    これはインスタンスへの参照が必要な場合にその都度 this を使うと、シーンによっては参照先が変わってしまうことがあるので、何らかの変数が必要だからです。別に self でも良いのですが、cycle プラグインに倣って jQuery インスタンスへの参照であることが視覚的にわかるように $ を使い、また target とすることによりアニメ対象であることを意味的にも表示するようにしました。

  2. 次にメソッドの opts プロパティを o オブジェクトに転写します(#2)。

    この行は極めて重要な役割を果たします。これで o オブジェクトに初期値が設定されると共に、同じインスタンスからの 2 度目以降の slideToggleEx の呼び出しの際には、初回呼び出し時に設定された諸値が、初回呼び出し時の 14 行の実行によって、opts プロパティに登録されているので、情報満載のその opts が o に複写されます。

    この結果、4 行目の if 文において、o.target プロパティは存在するし、o.target[0] === $target[0] となるので、4 ~ 17 行がパスされます。こうして同じインスタンスに対して、諸値設定を繰り返させない効率化を実現しました。

  3. 他方、slideToggleEx の最初の呼び出しの際、またはインスタンスが変わった時の呼び出し時には、o.target プロパティが存在しないか、o.target[0] と $.target[0] は異なるため、4 行目の if 文が成立し、5 ~16 行が実行されます。

    まず、opts オブジェクトの初期値をバックアップするために、それが転写された o オブジェクトを orig プロパティに保存します(#6)。このバックアップは当面使いませんが、何らかの必要が後で生じるかもしれないとの老婆心です。

    次に、target プロパティに $target への参照を登録します(#7)。これにより上で述べたような 二度目以降の呼び出し時の if 文不成立を成り立たせます。

  4. o.oH と o.oW には インスタンスに登録されている最初の要素の外寸を登録します。これも 1 回だけ測ればよいので if 文の中に入れました(#8 ~ 11)。
  5. o オブジェクトの最後のプロパティは起動回数を記録するためのプロパティです。これは 18 行との関係で false とする必要があります(#12)。
  6. 以上により初回呼び出し時にだけ、インスタンスに係る諸情報を設定・獲得し、その値を 2 行目で得た o オブジェクトに上書きし(#5)、その直後にその拡張された o オブジェクトを opts オブジェクトに併合します(#18)。こうすることにより、o オブジェクトが持つ情報が opts オブジェクトに複写・保存され、slideToggleEx が実行を終えても、当該インスタンスに係る情報を slideToggleEx.opts プロパティが保持し続けます。
  7. 15 ~ 16 行では 当該インスタンスに登録された要素の position 指定をチェックし、relative になっていなければそのように設定します。

    こうすることにより slideToggleEx 対象要素を作成する時には一々 position 指定をしなくても良いようにしました。なおこの処置も当然 1 回だけ行えばよいので、if 文の中で行います。

  8. 最後の 18 行は、起動回数を記録するためのコードです。

    12 行で false とされた o.odd 値は 14 行によって opts.odd = false と複写されます。そして 18 行でこれを否定することにより opt.odd は trueとなり、これが o.odd にも代入されます。

    こうして初回起動時の o.odd 値は true となり奇数回目であることが登録されます。二度目の呼び出し時には 2 行からいきなり 18 行に飛ぶので 18行の o.odd は false、つまり偶数回目となります。

    ここにおいて、常に opts.odd に偶数/奇数回数を示す値が保持され続け、そこから o.odd 値が複写され、呼び出しの都度変更されることがポイントです。

  9. 最後に、slideToggleEx を呼び出すインスタンスが変わった場合のコード進行を説明します。

    この時には if 文の 2 番目の条件が効果を発揮します。起動元インスタンスが変われば、2 行目によってゲットされる o.target はそれ以前の別のインスタンスへの参照を保持しているため、必ず o.target[0] は $.target[0] と異なります。こうして if 文が成立し、改めて起動元インスタンスの要素サイズ( o.oH と o.oW )が計測されます。

    そして、その結果は 14 行で opts オブジェクトに複写され、当該インスタンスからの二度目以降の呼び出し時には改めて o オブジェクトに複写されます。

    こうして以前のインスタンスに登録されていた要素のサイズ計測結果は、上書きされて消失し、新しい現在の呼び出し元インスタンスに登録されている要素のサイズが opts オブジェクトに保持され、o オブジェクトに登録されます。

▲ToTop

クリックイベント登録と slideToggleEx 対象要素を特定するためのコードについて

このコードはプラグインメソッドではありませんが、容易に slideToggleEx プラグインを利用するために不可欠なものです。そして作成にかなり苦労を重ねた難産コードでした。そこで一節を設けて詳細に説明しておきたいと思います。

■ クリックイベントと slideToggleEx 適用対象を登録するためのコード ( 再掲です )
/* regist click Event to fire slideToggleEx() for nextBlock */
 1:$(function(){ // 当然 DOM が Ready されてから起動する必要があります。
 2: var duration = 1000, easing = null,fn = function(){}, clk = {};
 3: function func(i){
 4:  $.each(clk[i],function(){
     // target オブジェクトは slideToggleEx 対象の個々のノード 1 つだけを格納する。
 5;   var $target={};
     // $target オブジェクトの j プロパティに slideToggleEx 対象ノードを格納する。
     // fireSlideToggleEx-x クラス指定されたボタン要素がブロック要素の場合には
     // next siblingを block 以外の inline 要素の場合には親要素の
     // next sibling 要素を slideToggleEx 対象とする。
 6:   $target[i] = $(this).css("display")=="block" ? $(this).next() : $(this).parent().next();
 7:   if ($target[i].length) {
 8:    $(this).click(function(){
       // IE においては右側をアニメ起終点にすると固まる事が多いので、
       // 強制的に同種の左側起終点に指定を替える。
 9:     if (jQuery.browser.msie)
10:      var k = i==2 && 1 || i==3 && 4 || i==6 && 8 || i;
11:     else k=i;
       // slideToggleEx を起動する。
12:     $target[i].slideToggleEx(k, duration, easing, fn);
13:     $(this).blur(); // ボタン要素のフォーカスを外す
14:    });
15:   }
16:  });
17: }
18: for (var i=0; i<9; i++){ // 0 から 8 迄の巡回処理
    // クリックイベントを登録するオブジェクト clk の i プロパティを作成し、
    // それに "fireSlideToggleEx-i"( i は 0~8 ) class 名のノードをもつ
    // jQuery インスタンスを登録する。これにより、ページ内にある
    // fireSlideToggleEx-n クラス名を持つノードを捉える。
19:  clk[i] = $(".fireSlideToggleEx-" + i);
    // i 番名のノードがなければ loop の先頭行に戻って i++ する。
20:   if (!clk[i].length) continue;
    // i 番名のノードが存在した場合には、当該インスタンスの
    // 各ノード毎に巡回処理を行うために func 関数を呼び出す。
    // ここに func 関数の第 1 引数 clk[i] が外側の関数内にある変数 clk への
    // 参照を保持しているので、func 関数はクロージャーとなっている。しかし、
    // グローバル環境から func 関数への参照はないので、クロージャーを通じた
    // ローカル変数の活用は行っていない。
21:  func(i);
22:  clk[i].hover( // マウスオーバー/アウト時のボタン背景色の変更
23:   function(){$(this).css({backgroundColor:"pink"})},
24:   function(){$(this).css({backgroundColor:""})}
25:  )
26:  // マウスが押し下げられた場合の色替え
27:  .mousedown(function(){$(this).css('background-color','palegreen')})
28: }
29:});

要点は以下の通りです。

  1. 一般的に同一ページ内で複数の slideToggleEx 対象があるのは当たり前であり、更に同一の起終点から起動させる slideToggleEx 対象が複数ある場合も決して少なくないこと。
  2. 従って class 名を頼りに click イベントを登録するものの( 使う度に決めなければならない id を頼りにすることは出来ません。)、同一 class 名の要素がそれぞれ個別に識別できなければなりません。さもないと、1 つのボタンをクリックした際に、同一クラス名を有する slideToggleEx 対象ノードの全てが一斉にアニメートしてしまいます。

以上の要点を踏まえたコードは結構複雑な構成になりました。

  1. (#2) イベント登録オブジェクト clk を用意します。
  2. (#3 ~ 17) 個々のノードに対してクリックイベントを登録する関数を定義します。この関数を設けたことには大きな意味があります。関数化しないで 21 行の位置に each メソッドを置くと、for loop 内にあるために、どんな場合でも slideToggleEx の第 1 引数が 9 となってしまうからです。
  3. (#18) 9 回の巡回処理により、クラス名を頼りに、個々のノードに対してクリックイベントを登録します。
  4. (#19)まず、クリックイベントを登録するオブジェクト clk の i プロパティを作成し、それに "fireSlideToggleEx-i"( i は 0~8 ) class のノードをもつ jQuery インスタンスを登録します。このインスタンスは複数のノードを含んでいる場合もあり得ます。
  5. (#20) ノードが 1 つも含まれなければ、i が 1 増されてループの最初から処理が再開されます。
  6. (#21) func(i)を呼び出します。この関数が個々のノードに対してクリックイベントを登録します。
  7. (#4) clk[i] インスタンスに登録されたノードの数だけ each 巡回処理を繰り返します。
  8. (#5) $target オブジェクトはその i プロパティに slideToggleEx 対象の個々のノードを 1 つずつを格納するオブジェクトです。
  9. (#6) this は clk[i] に登録されている 1 つのノード を意味します。その jQuery インスタンス $(this) の display style 値を調べて、next sibling 要素への参照を $target[i] プロパティに登録します。
  10. (#7) 返されたインスタンスに slideToggleEx 対象となるノードが 1 つ以上あれば 8 行目以降が実行されます。
  11. (#8) 個々の要素 ( $(this)、つまり clk[i] に登録されている各ノード) に click イベントを登録します。こうして個々の要素毎に、個々の slideToggleEx 対象が特定されてクリックイベントが登録されます。
  12. (#9 ~ 10) IE の場合ブロックの右側を起終点とするアニメーションは固まる場合が多々あります。

    そこで IE に限って右側の起終点を利用せずに、同等の左側起終点となるように変換します。

  13. (#11) IE 以外のブラウザの場合の処理です。
  14. (#12) $target[i] から slideToggleEx メソッドを起動します。
  15. (#22 ~ 27) これらの行は一般的なコードです。

 

■ コメントの投稿 ■

管理者にだけ表示を許可する

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/731-d4f564f2

●参照元一覧●

<provided Fc2>
<provided i2i>

▲ToTop

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。

----------
200909070032
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。