09 | 2009/10 |  11

  1. 無料サーバー

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

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


softbank 孫社長が iPhone について誇大宣伝!

yahooBB の誇大宣伝が社会的に問題視され、そして softbank 携帯のゼロ円広告が誇大広告だとして国から是正を指導されたことは記憶に新しい。

にもかかわらず、孫社長は懲りないらしい。

曰く───

「iPhoneを使い始めて、PCを使う頻度が10分の1に減った」とし、ネット利用の95%をiPhone経由で行っていることを明らかに。「インターネットはPCと思っている人は時代から取り残される」とし、「ほとんどのケータイはiPhone化しつつある」と話した。さらに、「PCを使ってインターネットを使う人は化石のような人と思われる時代が来るのではないか」と述べた。(4-9月期決算でソフトバンク孫社長、「ほとんどのケータイはiPhone化する」 | 携帯 | マイコミジャーナル

iPhone を使うことにより、「PCの使用が10%になり、ネット利用の95%が iPhone 経由」と宣わっているのである。更に、「PCを使ってインターネットを使う人は化石のような人と思われる時代が来るのではないか」とは余りに PC を馬鹿にした台詞である。

彼はおそらく、ワードやエクセルやパワーポイントやアクロバットや photoshop を業務上使わないのだろう。およそ、メールと Web サイト閲覧程度しかしないのであろう。

ワードやエクセルの文書作成を iPhone で行うなんて、およそ考えられないはずなのに、勝ち誇り、平然と特殊解を一般解であるかのように言いふらすのは、余りに我田引水というものだろう。そして同時にそれはまさしく誇大宣伝である。

そもそも、私は iPhone を softbank にだけは扱って欲しくなかった! こんな風に誇大宣伝されることが火を見るより明らかだったからだ。

しかしまただからといって、docomo や au が素晴らしいわけではないところが、また憎らしい。

しかし「携帯の iPhone 化」は正しい!

孫社長の言は殆どが誇大宣伝、我田引水ではあるが、しかし「ほとんどのケータイは iPhone 化する」との指摘には全く同感する。

2007年に iPhone が登場した際、即座に感じた私の第一印象は、まさしく「次世代に主流となるであろうケータイが登場した」というものだった。

具体的に言えば、常時ネットに、或いは同義だがクラウドに接続し、様々なシーンで不可欠となる情報を随時 output し input する個人情報端末───それこそが personal computer の現時点におけるあるべき姿だろう。そしてそのような PC の中で携帯性に優れたそれこそが、iPhone 型携帯、否 iPhone 型 PC なのだ。

片手又は両手の親指で操作するケータイは、少なくとも Business シーンからは近い将来消滅していくだろう。

iPhoneを使う(1)──基本アプリのインストール

購入して1週間で14本のアプリをインストール

タッチパネルの操作を快適に行いつつも、通常のケータイで当たり前のことが出来ないことには苛つきを覚える。───カメラにズーム機能がない、クリップボードの履歴が取れない、辞書登録機能がない等々───

そこで、もしかしたらアプリケーションでこれらの欠点を補完するものがあるかもしれない、と思いつき、この 1 週間、アプリ検索に精を出してきた。

iPhone アプリは無数にあるが、一部を除いてそのどれもが無料か数百円で購入できる。そしてユーザーは数百円以下だからこそ導入する。ハードだけではなくソフトでも稼ぐ Apple 社の見事な戦略に踊らされていることには忸怩たる思いを抱くが、それでも必要に駆られて、やむなく私もアプリをインストールせざるを得なくなった。

アプリ紹介サイトもまた無数にある

この場合でも「先達のあらま欲しきことなり」は鉄則となる。サイト上の先達たちの経験と知識を拝借しない手はない。その一例を挙げれば以下の通りである。

これらのサイトを参考にして、欠点を補うに足るアプリをインストールしたのである。

▲ToTop

満を持した訳ではないが、遂に iPhone を購入した

iPhone にはアメリカで登場したその時から注目していた

今や、日本の各携帯キャリアもタッチパネル操作が可能な「携帯」を発売しているが、それが iPhone で登場した時には、感動すら覚えたものだ。───これこそが「携帯」であり、パーソナルコンピューティングであり、個人的な情報端末のあるべき姿を示している! 丁度 Mac が personal computer のあるべき姿を示したように、Apple 社がまたしても歴史を作った───と感じたのである。

その「事件」は 2007 年 7 月のことであった。→ anything from here iPhone熱狂 in America. そして日本では?

iPhone 発売当初は、固有の携帯文化が障壁となって日本では発売されず、そのことに忸怩たる思いをしたことを今でも鮮烈に覚えている。

そして 2008 年、日本でも発売されたが...

お財布ケータイがない、カメラの解像度が200MB、QRコードを読めない、ワンセグもない等の、およそ日本の携帯文化にはそぐわない固有の機能的制限は未だ許せた。しかしコピペが出来ないなんて、そもそもそんな情報端末があり得るのか!───

タッチパネルの素晴らしさや、回すと 90 度回転する画面機能や、拡大縮小を 2 本の指で行える素晴らしさ等々、魅力的な機能には喉から手が出る程羨望を抱いたのであるが、しかし、2008 年段階の iPhone は余りにもお粗末だった。故にとても購入する気が起きなかったのである。

▲ToTop

しかし、やっと欠点のいくつかを改善して 3GS が登場した!

案の定、欠点の多い iPhone は日本の携帯キャリアに驚異を与えなかったし、Apple 社も反省と前進を迫られたのだろう。

2009年───遂に iPhone 3GS が、これまでのいくつかの欠点を克服して発売された。やっと使用に足る携帯情報端末が登場したのである。それが iPhone 3GS だった。

そして iPhone 3GS を購入し、まだまだ五合目にしか登っていないことを知った

満足度は期待度から測れば50点くらいだろうか。決して満足のいくものではなかったと言わざるを得ない。

日本の携帯では当たり前の「コピペの履歴保存機能」はないし(勿論無料/有料の clipboard アプリはあるが、決して操作性が抜群と言えるものはまだ存在していないように思われる。)、辞書に単語登録すら出来ない。つまり、それなりの日本語文章を打ち込むには、余りに貧弱な入力環境なのである。こうした事態は、日本固有の文化に対する「武装」が、iPhone ではまだまだ極めて不十分であると言わざるを得ない。

だからこそ日本の携帯各社は枕を高くして眠れるのであろう。

折角、様々な機能を満載して、本格的に使用するに足る「携帯情報端末PC」という新概念を具体化した商品を発売したのに、まだまだ五合目くらいにしか登り切れていないと思うのは、私だけだろうか。

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

slideToggleEx プラグインは不完全だった

エントリイNo.731 において、slideToggleEx 自作プラグインメソッドについて詳述しました。

ところが、そこで紹介したプラグインメソッドコードは不完全でした。隠蔽状態から起動するアニメーション対応を全く考慮していなかったので、その状態で起動すると思わぬ動きをしてしまうのです。つまり、実は半分しか完成していないのでした。(^^;; ヒヤアセ

そのことに気がついたのは 9 月中旬。その時点から、改めてコード全体を見直さざるを得なくなり、改めて animate メソッドの再学習を迫られたのです。

その後一ヶ月余り。四苦八苦、七転び八起きを繰り返した末に、昨晩やっと隠蔽状態からの起動にも対応した slideToggleEx 版が完成したので、ここに投稿することにします。

用意するもの・ことは以下の 5 つです。(この部分は No.731 の再掲)
  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 構造(この部分も No.731 の再掲)

上の 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 プラグイン活用コード

アニメ継続時間と easing 関数は、後述する 「 click イベントを登録し slideToggleEx メソッド適用対象をピックアップするコード 」 において、1 秒に設定し、easing は無指定としています。このコードを弄れば自在に継続時間と easing 関数は変更できますが、使う際にその都度 duration と easing 関数を変更する必要はないと考え、(1) トリガーとなるボタンタグと (2) slideToggleEx 対象のブロックタグ、及び (3) slideToggleEx-n クラス名を指定するだけで使えればよいと判断しました。

以下に掲載したコードリストの表示と隠蔽には、当然 slideToggleEx を適用しています。直下のボタンをクリックすると、 slideToggleEx メソッドが起動し、アニメ対象要素であるコードリストが当該要素の右上から展開し、再びボタンをクリックすると右上へ隠蔽されます。( 起終点= 2 )

コードには各行に詳細な説明を記述したので、何を行っているのか分かると思います。

■プラグイン slideToggleEx() メソッドコード(完全版)
  0:// jQuery plugin : slideToggleEx() Release at 2009.8.21, ver 1.1:9.9, 1.3TheLastVer:10.9 01:00am
  1:(function($){
  // アニメーションコードの性格を簡単に記述しておく
  2:var ver="relative animation under position relative";
  // プラグイン指定
  3:$.fn.slideToggleEx = function( type, duration, easing, fn ){
  4: if (type > 8) // エラー対処
  5:  (function(){
  6:   alert("第 1 引数は 0~8 だけが指定できます。\nやり直してください。
      \n"+"slideToggleEx( 0~8, 継続時間, easing関数, アニメ後実行関数 )"); return;
  7:  })();
   // 変数設定、初期値複写
  8: var $target = this, o = $.extend({},$.fn.slideToggleEx.opts);
   // 9 ~ 23 行は、o オブジェクトにtargetとプロパティがない場合、
    * またはターゲットが異なった場合、つまり初めてそのインスタンスから呼ばれたか、
    * インスタンスが変わった場合に起動される。
    * このブロックはアニメ対象に対して様々な初期化を行う。
    */
  9: if(!o.target || o.target[0]!==$target[0]) {
 10:  $.extend(o,{
 11:   orig : o, // 当面使わないが念のために o をバックアップ
 12:   target : $target,
 13:   el : $target[0], // アニメ対象ノードへの参照を取得
 14:   type : type,
 15:   initstate : !$target.is(":hidden"), // アニメ前の状態が隠蔽か表示か
 16:   cnt : 1 // インスタンス毎の起動回数カウンター
 17:  });
    // アニメ対象が切り替わり、再びあるインスタンスに slideToggleEx メソッドが
    // 適用された時には、最初に呼び出された時の設定を再利用できるように data
    // メソッドを活用してコード進行の効率化を図る。
    // また o オブジェクトにアニメ対象要素等のサイズに係るプロパティを追加する。
 18:  $.extend(o, $.data(o.el,"initdone") || getSize());
    // アニメ対象ノードの固有 style 値を取得する。
 19:  for (var p in o.cssdefault.H) o.cssOrig.H[p] = $.css(o.el,p,true);
 20:  for (var p in o.cssdefault.W) o.cssOrig.W[p] = $.css(o.el,p,true);
    // 上のメソッドでは単位が付かないので付与する。
 21:  o.cssOrig.H.height +="px"; o.cssOrig.W.width +="px";
      // o オブジェクトを $.fn.slideToggleEx.opts オブジェクトに併合する。
 22:  $.extend($.fn.slideToggleEx.opts,o);
 23: }
   /* 24 ~ 36 行迄のブロックは、slideToggleEx が呼び出される度に
    * 作用する。27 行で type 値をチェックするのは、同一要素における異なる type 値
    * によるslideToggleEx メソッドの連続起動の場合に対処するためである。
    * slideToggleEx メソッドの連続起動の場合には、呼び出される度に o.duration、
    * o.easing、o.complete が変化する可能性があるので、これらも呼び出し毎に
    * 定義する必要がある。
    */
   // window サイズが変更された時には親要素サイズを計測し直す。
 24: window.onresize = getParentWH;
 25: o.cnt = $.fn.slideToggleEx.opts.cnt++; // カウンター値を 1 増する。
 26: o.odd = o.cnt % 2; // o.cnt が奇数か偶数かを判定する
 27: o.type = o.type!==type ? type : o.type;
   // duration などの初期値は $.fn.slideToggleEx.opts に用意しておく。
 28: o.duration = duration || o.duration;
 29: o.easing = typeof duration !=="object" ? (easing || o.easing) : "";
 30: o.complete = typeof duration !=="object" ? ($.isFunction(fn) && fn || o.complete) : "";
 31:
   /* アニメ対象ノードに AdjustN( N は type 値 )名で
    * 関連づけられたオブジェクトがなければ、adjustcssAnim 関数を呼び出し、
    * その返値を o.cssAdjust.show 及び .hide プロパティに代入する。
    * 関連づけられたオブジェクトがあればそのまま利用する。
    * ここに o.cssAdjust は animate メソッドで利用するアニメ用 CSS プロパティの内、
    * 起終点位置に応じて変化する top 及び lef 値だけを保持するオブジェクトである。
    * show 及び hide プロパティには "+=" などの relative アニメーション値が設定される。
    */
 32: o.cssAdjust = $.data(o.el,"Adjust"+o.type) ||
 33:  $.data(o.el,"Adjust" + o.type, {show:adjustcssAnim(true), hide:adjustcssAnim(false)});
   /* アニメ対象ノードに AnimN( N は type 値 )名で関連づけられた
    * オブジェクトがなければ、setAnimCSS 関数を呼び出してその返値を o.cssAnim
    * オブジェクトに代入する。関連づけられたオブジェクトがあればそのまま利用する。
    * ここに cssAnim は animate メソッドで利用するアニメ対象プロパティの全てを
    * 保持するオブジェクトであり、29 行で取得した top値と left値も併合する。
    */
 34: o.cssAnim = $.data(o.el,"Anim" + o.type) || $.data(o.el,"Anim" + o.type, setcssAnim());
   /* アニメ対象ノードに BeforeN( N は type 値 )名で関連づけられた
    * オブジェクトがなければ、makecssBefore 関数を呼び出してその返値を o.cssBefore
    * オブジェクトに代入する。関連づけられたオブジェクトがあればそのまま利用する。
    * ここに cssBefore は animate メソッド起動直前のアニメ対象要素のスタイル属性値を
    * 取得し、あるいは設定するためのオブジェクトである。
    */
 35: o.cssBefore = $.data(o.el,"Before" + o.type) || $.data(o.el,"Before" + o.type, makecssBefore());
   // 当該のアニメ対象要素に初めて、あるいは別のアニメ対象操作後に再び
   // slideToggleEx メソッドを適用した時に、最初に起動された場合にのみ適用するコード。
   // 対象要素の表示状態に応じて、animate メソッド適用前の CSS 値を設定する。
 36: if (o.cnt==1) $target.css( o.initstate ? o.cssBefore.show : o.cssBefore.hide );
 37:
   /* アニメーション起動
    * 第 2 引数がオブジェクトではない時
    * 要素の animate メソッド適用前の表示状態と slideToggleEx メソッドの起動
    * 回数に応じて、当該メソッド第一引数である CSS オブジェクトを選択的に適用する。
    */
 38: if (typeof o.duration !=="object")
 39:  return this.animate( (o.initstate && !o.odd || !o.initstate && o.odd)
 40:   ? o.cssAnim.show : o.cssAnim.hide, o.duration, o.easing, o.complete );
   // 第 2 引数がオブジェクトの時
   // 要素の animate メソッド適用前の表示状態と slideToggleEx メソッドの起動
   // 回数に応じて、当該メソッド第一引数である CSS オブジェクトを選択的に適用する。
 41: else
 42:  return this.animate( (o.initstate && !o.odd || !o.initstate && o.odd)
 43:   ? o.cssAnim.show : o.cssAnim.hide, o.duration ); // アニメ起動
 44:// 以下は以上迄のコードから呼び出される関数群である。
   /* getSize はアニメ対象ノードの position 指定を行い、サイズを測る関数。
    * この関数は或る要素に対して slideToggleEx メソッドを適用した初回だけにたった1 回
    * だけ起動される。 54 行と 35 行の data メソッドによって data 関連づけを行わっている
    * ので、同じ要素に対する 2 度目以降の呼び出し時には、たとえ非連続的に呼び出された
    * としても、この関数は呼び出されない。
    */
 45: function getSize(){
    // position 指定を relative に
 46:  if ($target.css("position") ==="static") $target.css({position:"relative"});
 47:  var obj={}, parent={};
 48:  return obj= {
       // 親要素の幅と高さを取得
 49:   parent : {W:getParentWH().W, H:getParentWH().H},
       // アニメ対象要素のマージン辺までの高さ(算出スタイル値)取得
 50:   oH : parseInt($.css(o.el,"height",true,"margin")),
       // アニメ対象要素のマージン辺までの幅(算出スタイル値)取得
 51:   oW : parseInt($.css(o.el,"width",true,"margin")),
       // アニメ対象要素のボーダー辺までの高さ(算出スタイル値)取得
 52:   oHb : parseInt($.css(o.el,"height",true,"border")),
       // アニメ対象要素のボーダー辺までの幅(算出スタイル値)取得
 53:   oWb : parseInt($.css(o.el,"width",true,"border"))
 54:  };
 55: }
 56: function getParentWH(){ // アニメ対象の親要素のサイズを計測取得する関数
 57:  var parent = $target.parent();
 58:  return o.parent={W:parent().width(),H:parent().height()};
 59: }
   // アニメーション起終点に応じたアニメ用 top/left 値設定関数
 60: function adjustcssAnim(showhide){
 61:  var plmn = showhide ? "-=" : "+=";
 62:  return o.type==0 ? {top:plmn + o.oH/2 +"px", left:plmn + o.oW/2 +"px"} : // center
 63:   o.type==1 ? {} : // 左上端。top も left もアニメ対象プロパティとしない。
 64:   o.type==2 ? {left:plmn + o.oW +"px"} : // 右上端
 65:   o.type==3 ? {top:plmn + o.oH +"px", left:plmn + o.oW +"px"} : // 右下端
 66:   o.type==4 ? {top:plmn + o.oH +"px"} : 3aspan class="aquamarine"
 
 67:   o.type==5 ? {} : // 上辺。top も left もアニメ対象プロパティとしない。
 68:   o.type==6 ? {left:plmn + o.oW +"px"} : // 右辺
 69:   o.type==7 ? {top:plmn + o.oH +"px"} : // 下辺
 70:   {} ; // 左辺。top も left もアニメ対象プロパティとしない。
 71: }
   /* アニメ用プロパティを作成する関数
    * o.cssdefault を基にして横方向/縦方向のプロパティを作成し、またその有無を
    * type 値毎に変化させる。
    * 例えば、type 値が 5 の場合、横方向のプロパティはアニメ対象とはしない。
    * また、margin は auto が指定されている場合にはアニメ用プロパティとせず、
    * その他の場合には他のプロパティと同様に"toggle"とする。
    * 79 行で横/縦方向のプロパティを合体させ、不透明度もアニメ用プロパティと
    * して追加する。
    * 最後に 80~82 行において、それまでに作ったアニメ用 CSS オブジェクトに
    * アニメーション起終点に応じて変化する top と left プロパティを追加する。
    */
 72: function setcssAnim(){
 73:  var obj = {};
 74:  obj.W = (o.type!=5 && o.type!=7) ? $.extend({}, o.cssdefault.W,
 75:    (o.oW!==o.oWb) ? {marginLeft:"toggle",marginRight:"toggle"} : {}) : {};
 76:  obj.H = (o.type!=6 && o.type!=8) ? $.extend({}, o.cssdefault.H,
 77:    (o.oH!==o.oHb) ? {marginTop:"toggle",marginBottom:"toggle"} : {}) : {};
 78:  obj = $.extend({}, obj.W, obj.H, {opacity :"toggle"});
 79:  return o.cssAnim = {
 80:   show:$.extend({},obj,o.cssAdjust.show),hide:$.extend({},obj,o.cssAdjust.hide)
 81:  };
 82: }
   // animate メソッド適用前の適用対象要素の CSS 値を作成する関数
 83: function makecssBefore(){
 84:  var obj = {}, ret = {};
    /* margin をアニメ対象にした場合において、margin 値が "auto" の時には、
     * jquery.js の各種メソッドでサイズを測定しても margin 値が捕捉できない。
     * その結果アニメーションは予期せぬ動きをしてしまうため、まず、margin 値を
     * 強制的にゼロにし、替わりに auto 指定によって確保された margin 値に相当する
     * left 値と top 値に置き換える。これにより予期したとおりのアニメーションを
     * 引き起こさせる。
     */
 85:  // if marginLeft/Top == "auto", fix marginLeft/Top.
 86:  obj.W = (o.el.style && $.attr(o.el.style,"margin-left")==="auto") ?
 87:   {left : (o.parent.W - o.oWb)/2 +"px", marginLeft : "0px", marginRight : "0px"} :
     /* この場合も、margin 値は $.css メソッドを使って取得しないと駄目。
      * 例えば margin 指定が簡略的に margin: 10px のように行われている場合には、
      * jquery.js は margin-left、margin-right などの個々の margin 値を取得しない。
      */
 88:   {left :"0px",
 89:    marginLeft:$.css(o.el,"margin-left",true), marginRight:$.css(o.el,"margin-right",true)};
 90:  obj.H = (o.el.style && $.attr(o.el.style,"margin-top")==="auto") ?
 91:   {top : (o.parent.H - o.oHb)/2 +"px",marginTop : "0px", marginBottom : "0px"}:
 92:   {top : "0px",
 93:    marginTop:$.css(o.el,"margin-top",true), marginBottom:$.css(o.el,"margin-bottom",true)};
    // ここ迄の処理結果を show プロパティに格納する。
    // このプロパティがアニメ対象が表示されている時のアニメ前 CSS 値となる。
 94:  ret.show = $.extend({}, o.cssOrig.H, o.cssOrig.W, obj.W, obj.H);
    /* 以下はアニメ対象が隠蔽されている場合の処理
     * アニメ用CSSオブジェクトの hide オブジェクトに top プロパティが存在している
     * 場合にのみ適用する。
     * top プロパティが存在していない場合には、top プロパティはアニメ対象としない。
     */
 95:  if (o.cssAdjust.hide.top) // アニメ用 CSS オブジェクト作成関数を利用して
     // アニメ前 CSS オブジェクトを作成する。
 96:   obj.top = new Number(parseInt(obj.H.top))
 97:    + new Number(parseInt(o.cssAdjust.hide.top.slice(2)))+"px";
    // アニメ用CSSオブジェクトの hide オブジェクトに left プロパティ
    // が存在している場合にのみ適用する。
    // left プロパティが存在していない場合には、left プロパティはアニメ対象としない。
 98:  if (o.cssAdjust.hide.left) // アニメ用 CSS オブジェクト作成関数を利用
     // してアニメ前 CSS オブジェクトを作成する。
 99:   obj.left = new Number(parseInt(obj.W.left))
100:    + new Number(parseInt(o.cssAdjust.hide.left.slice(2)))+"px";
    // ここ迄の処理結果を hide プロパティに格納する。
    // このプロパティがアニメ対象が隠蔽されている時のアニメ前 CSS オブジェクトとなる。
101:  ret.hide = $.extend({}, ret.show, obj);
    // data メソッドによる関連づけを行ってから ret オブジェクトを返す。
102:  return ret;
103: }
104:} // End of $.fn.slideToggleEx
105:
106:// default 値設定と記憶用プロパティとしての機能のために
107:$.fn.slideToggleEx.opts = {
   // 既定値としての引数設定
108: duration : 1000, easing : null, complete : function(){},
   /* auto 指定への対応が必要な margin、及び type 値に応じて変化させる
    * 必要のある top と left ───これらを除くアニメ対象プロパティリスト。
    * 羅列されているプロパティは、最小値の 0 又は 1 (width と height のみ)と
    * 要素固有のプロパティ値との間でアニメーションさせることになる。
    * 高さ方向と横方向とを区別するのは、type 値に応じてアニメ対象プロ
    * パティの要/不要が変化するためである。
    */
109: cssdefault : {
110:  H : {
111:   height:"toggle",paddingTop:"toggle",paddingBottom:"toggle",
112:   borderTopWidth:"toggle",borderBottomWidth:"toggle"
113:  },
114:  W : {
115:   width:"toggle", paddingLeft:"toggle",paddingRight:"toggle",
116:   borderLeftWidth:"toggle",borderRightWidth:"toggle"
117:  }
118: },
119: cssAdjust : {},
120: cssOrig : {H:{},W:{}},
121: cssBefore : {}
122:};
123:})(jQuery);

▲ToTop

slideToggleEx Javascript コード解説

直上に掲載したコードに至るまで、実は多くのバージョンを作成し、失敗しては作り直す「らせん的」過程を何度も繰り返しました。しかし、その苦労話の前に、まずコード作成の基本的方針を述べておくべきでしょう。

slideToggleEx が想定しているシーン
  1. slideToggleEx アニメ対象ノードは表示されていても隠蔽されていても、いずれの状態でも良い。
  2. 1 つの homepage や blog エントリイ内に、複数の slideToggleEx アニメ対象ノードが存在し、それぞれのアニメ起終点は、各々同一でも良いし、異なっても良い。
  3. 1 つのアニメ対象ノードに対して連続して slideToggleEx メソッドを起動することもあり、その場合にはアニメ起終点がその都度変わることもあり得る。
  4. 独自仕様の多い IE においても起動出来るアニメーションとする。
slideToggleEx コードの効率化
  1. slideToggleEx メソッドを同一ノードに適用する場合には、コード進行過程を出来る限り繰り返さないようにする。そのために jQuery.data クラスメソッドを活用してアニメ対象ノードに情報を関連づける。
  2. 一度計算した値や使用した関数は、結果を出来る限り再利用する。そのために、jQery プロトタイプオブジェクトのプロパティを活用する。

▲ToTop

コード作成上の苦労話・強調したい点

1. メソッド終了後にも情報を保持させる措置

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

無名関数のトップレベルで、slideToggleEx メソッド外に変数を用意すれば解決することなのですが、是が非でもプラグインのメソッド外に変数を置かないでまとめたかったので、拘ってコードを作りました。その結果、メソッド外となる点では変わらないのですが、『Javascript 第 5 版』p.144 や cycle プラグインを参考にして slideToggleEx メソッドのプロパティに値を保持させることにしました。

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

そこでメソッドのプロパティを記憶装置にすることにしました。コードの 107 行から 122 行がその記憶装置です。

2. アニメーション開始前の対象ノードの CSS 値の処理

要素が隠蔽されていても表示されていても、要素固有の margin、border、padding、width、height 値などは保持されています。隠蔽されていてもそのスタイル諸値がゼロになるわけではありません。そのことをまず把握し理解する必要があります。( 実は私はこのことへの理解が不十分でした。 )

次に、slideToggleEx メソッドの適用対象が複数存在しているエントリイにおいて、アニメ起動が異なる要素に対してアト・ランダムに行われる場合、それぞれの要素に対して適切なアニメを起こさせることがかなり難しいことでした。

以前、slideToggleEx メソッド対象となった要素は偶々隠蔽されているかもしれないし、表示されているかもしれません。今 slideToggleEx アニメを引き起こした要素も表示されているかもしれないし、隠れているかもしれません。このようなアト・ランダムな状態においても、それぞれの要素毎に適切な slideToggleEx アニメーションが引き起こされるようにしなければなりません。

以上を踏まえた処理として cssBefore オブジェクトを用意しました(32 ~ 33 行)。このオブジェクトによりアニメーション起動前の要素のプロパティを事前に設定するわけです。これにより隠蔽状態から表示へとアニメートする要素が、適切な位置で表示されるようになりました。

3. margin 値の扱い

margin 値は一般に 「 margin:1em auto 」 などのように簡略的に指定されている場合が多いでしょう。

ところがこのような指定の場合には、jquery.js の css メソッド等を活用しても margin-left 等の個々の margin 値を取得することが出来ません。特に auto 指定がされている場合、margin をアニメプロパティに指定すると全く予想外のアニメーションが引き起こされてしまいます。jquery.js は auto 指定された margin 値を数値的に捉えることが出来ないので、margin-left、margin-right 等のプロパティをゼロと判読してしまうためです。

こうして、margin 値が様々な様式で指定されている場合でも、それを適切な数値として把握する必要が生じます。

そのための処理は makecssBefore 関数で行わせました。

▲ToTop

4. アニメ開始前における対象要素の CSS 値設定

animate メソッドは、アニメ開始前の要素の様々な属性値(スタイル属性値を含む。width、margin etc.)をアニメ開始値として採用します。(もし或るプロパティの属性値がない場合には開始値を 0 とします。)このため表示されている要素にアニメーションを適用する場合には、一般的にはアニメ前 CSS 値を設定する必要はありません。

例えばアニメ対象要素に width="380px" が設定されていれば、ブラウザがその値を解釈して、380px 幅の要素を表示しているわけです。この場合 width プロパティのアニメ開始値が何も指定されていなければ、 animate メソッドは要素固有値である 380px を width プロパティのアニメ開始値とします。

ところが隠蔽されている要素にアニメーションを適用する場合には様相が異なってきます。

隠蔽されている要素を表示するアニメーションの場合でも、その隠蔽が一般的にそうであるように display = "none" 指定によって行われている場合には、対象要素の固有の属性値は存在し続けます。要素が単に非表示になっているだけで、display = "none" 以外の属性値は表示されていた時の値が保持され続けます。

この状態に対して隠蔽要素を表示させる animate メソッドを適用すると、animate メソッドの仕様上、要素固有値がアニメ開始値になるのですから、アニメプロパティが要素固有値となってしまいます。この結果、0 からスタートさせたかったアニメーションは引き起こされません。

従って、隠蔽要素を表示させるアニメーションの場合、アニメ開始値を animate メソッド起動前に強制的に指定する必要があります。こうして強制的に CSS 値を指定するための cssBefore オブジェクトが必要・不可欠となります。

さて、その cssBefore はアニメーションの初期値を定めるわけですから、アニメーションの態様に応じて( つまり起終点位置に応じて )変化します。ボックス要素の左上、上辺、左辺などを起終点とするアニメーションの場合には問題になりませんが、例えば、アニメが要素の中心位置から始まる場合には、top と left の開始値をボックス内容辺、ボーダー辺あるいは margin 辺までの、幅や高さの半分の値に設定する必要があります。また、開始点がボックスの右上の場合には、left の開始値をボックス内容辺、ボーダー辺あるいは margin 辺までの幅に設定する必要があります。

以上に述べた隠蔽状態における cssBefore オブジェクトの作成を makecssBefore 関数の後半で行っています。

なお、アニメプロパティ値を toggle や show に指定すると、animate メソッドは要素の固有属性値をアニメの終了値として利用します。この利便性故に、アニメプロパティ値に toggle を多用することになります。

▲ToTop

5. $.data メソッドの活用

slideToggleEx プラグインでは以下の 4 箇所で $.data メソッドを利用しました。

  1. 18 行 …… $.extend(o, $.data(o.el,"initdone") || getSize());
  2. 32~33 行 ……o.cssAdjust = $.data(o.el,"Adjust"+o.type) ||    $.data(o.el,"Adjust" + o.type, $.data(o.el,"Adjust" + o.type, adjustcssAnim(false));
  3. 34 行 …… o.cssAnim = $.data(o.el,"Anim" + o.type, $.data(o.el,"Anim" + o.type, setcssAnim());
  4. 35 行 …… o.cssBefore = $.data(o.el,"Before" + o.type) || $.data(o.el,"Before" + o.type, makecssBefore());

このメソッド利用した目的は、ずばりコード進行の効率化/高速化です。このメソッドを使うことにより、不必要に同じ計算を繰り返させたくなかったのです。

上の 4 例は皆同様な形式を取っているので、どれか 1 つ分かれば他は推して知るべしです。なので、ここでは一番最後の 35 行で使った $.data メソッドについて触れておきます。

$.data(o.el,"Before" + o.type) は、アニメ対象要素 o.el に "BeforeN" ( N は type 値 )と言う名称で関連づけられたオブジェクトがある場合には、そのオブジェクト( cssBefore オブジェクト)を返し、それが左辺の o.cssBefore に代入されます。一方、関連づけられた情報がなければ false を返すので、次にある || 演算子が働きます。

|| 演算子が作用すると、オペランドである makecssBefore 関数が実行されます。

この関数では最後の行に $.data メソッドがあるので、関数によって算出したオブジェクトを、このメソッドによりアニメ対象要素 o.el に "BeforeN" 名で関連づけます。関連づけられたオブジェクトは return により左辺の o.cssBefore オブジェクトに返されます。

こうして、同一要素に対する同一 type の slideToggleEx メソッド起動時には───実際、表示/隠蔽はセットで履行されるはずだから、多くの場合 slideToggleEx メソッドは、同一要素に対して同一 type 値で繰り返し実行されます。───最初の呼び出し時にだけ makecssBefore 関数が実行され、二度目以降は固有の名称で要素に関連づけられているオブジェクト値が利用されて、 makecssBefore 関数は実行されません。これがコード進行の「最初の」「効率化」であり「高速化」です。

$.data メソッドを利用したことによる効率化は、これだけではありません。或る要素Aが slideToggleEx によって表示/隠蔽され、次に別の要素Bがやはり slideToggleEx で表示/隠蔽されたと仮定します。この後に再び要素Aに slideToggleEx メソッドを適用した場合に、更なる効率化・高速化が発揮されます。

既に $.data メソッドによるA、B各々の要素へのオブジェクトの関連づけは済んでいますから、要素Bに続けてAに slideToggleEx アニメを適用した時には、既にAに関連づけられているオブジェクトが利用され、makecssBefore 関数は起動されません。こうして無駄なコード進行が排除されます。

以上のことが 4 つの関数に対して行われるので、現在操作対象となっている頁がリロードされない限り、slideToggleEx アニメーションが一度適用された要素においては、 slideToggleEx 内にある様々な関数を殆ど実行する必要がなくなります。こうしてコード進行が大いに高速化されます。高速化は言い換えれば省エネでもあるので、流行の言葉を使えば「エコ」なコード進行が行われると言っても良いかもしれません。

▲ToTop

クリックイベント登録と slideToggleEx メソッド適用対象の簡便な登録コード

さて、slideToggleEx を使うシーンは、ボタンをクリックして或るコンテンツを表示したり隠蔽する場合が多いと思われます。そうだとすれば、その一連の操作( クリックイベントの登録・或るコンテンツの指定・slideToggleEx メソッドの要素への適用 )をコード化して半自動化してしまえば、大変楽になります。

次に述べるコードは、この一連の操作、つまりボタンへのクリックイベント登録と、クリック時の slideToggleEx メソッド適用対象の特定とそのメソッドの起動をまとめて行うものです。

具体的には 「 或るボタンがクリックされたら、slideToggleEx アニメーションが適用される或る要素が特定され、slideToggleEx メソッドが起動する 」 そのような Javascript コードです。

そのコードでは、同一ページ内に存在する、複数の同一又は異なる type の slideToggleEx アニメーションの、トリガーボタンとアニメ対象を一括して登録します。slideToggleEx の引数であるアニメ継続時間、easing 関数及びアニメ終了後の実行関数は、コードの冒頭で登録し、これを slideToggleEx メソッドに渡すようにしています。

そもそもコード作成当初では、slideToggleEx メソッドの引数を何とか HTML 文内で行いたいと考えました。クラス指定によって、アニメの起終点 ( type ) を指定するだけではなくその他の引数もまとめて指定したいと思いました。

しかし、クラス名文字列の中に、duration、easing などの文字をその都度組み込むと、冗長なクラス名指定となってしまい、いかにも面倒ですし、値だけを羅列するようにしても煩雑で順番を含めてわかりにくくなります。それにボタンクリックによる要素の表示/隠蔽操作において、その都度 duration や easing の値を変化させる必要性が高いとは思えません。

以上から、クラス名の中に slideToggleEx メソッドの引数を盛り込むことはやめました。

なお、ここにおける duration 等の指定は、ここで対象としている「 ボタンクリックによって起動される slideToggleEx 起動方法 」 において、slideToggleEx メソッドの引数を指定するものです。他方、slideToggleEx プラグインコードにおける $.fn.slideToggleEx.opts オブジェクト内でも duration 等を指定していますが、これは slideToggleEx メソッドの一般的な既定値を設定するものです。

下のボタンをクリックすると隠蔽状態にあるそのコードが、右下から展開され、再びボタンをクリックすると右下に隠れます。(type 3)

▼このコードは、メソッドプラグインではありませんが、プラグインとセットで include
 ファイルに登録しておくと重宝します。これがないと fireSlideToggleEx-n のクラス指定を
 しても next sibling 要素などを slideToggleEx の適用対象とすることは出来ません。

// button 要素へのクリックイベント登録及び slideToggleEx メソッド適用対象のピックアップ
// クリックイベント起動ボタンと slideToggleEx 適用対象を登録する。
124:// regist click Event to fire slideToggleEx() for nextBlock
125:$(function(){ // 当然 DOM が Ready されてから起動する必要があります。
   // 初期値設定
126: var duration = 1000, easing = null, complete = function(){}, clk = {};
127: function func(j){
128:  $.each(clk[j],function(i){
     // target オブジェクトは slideToggleEx 対象の個々のノード 1 つだけを格納する。
129:   var $target={};
     // $target オブジェクトの j プロパティに slideToggleEx 対象ノードを格納する。
     // fireSlideToggleEx-x クラス指定されたボタン要素がブロック要素の場合には
     // next siblingを block 以外の inline 要素の場合には親要素の
     // next sibling 要素を slideToggleEx 対象とする。
130:   $target[i] = $(this).css("display")=="block" ? $(this).next() : $(this).parent().next();
131:   if ($target[i].length) {
132:    $(this).click(function(){
       // slideToggleEx を起動する。
133:     $target[i].slideToggleEx(j, duration, easing, fn);
134:     $(this).blur(); // ボタン要素のフォーカスを外す
135:    });
136:   }
137:  });
138: }
139: for (var j=0; j<9; j++){ // 0 から 8 迄の巡回処理
    // クリックイベントを登録するオブジェクト clk の i プロパティを作成し、
    // それに "fireSlideToggleEx-i"( i は 0~8 ) class 名のノードをもつ
     // jQuery インスタンスを登録する。これにより、ページ内にある
     // fireSlideToggleEx-n クラス名を持つノードを捉える。
140:  clk[j] = $(".fireSlideToggleEx-" + j);
141:    if (!clk[j].length) continue;
    // i 番名のノードがなければ loop の先頭行に戻って i++ する。
142:  func(j);
143:  clk[j].hover( // マウスオーバー/アウト時のボタン背景色の変更
144:   function(){$(this).css({backgroundColor:"pink"})},
145:   function(){$(this).css({backgroundColor:""})}
146:  )
    // マウスが押し下げられた場合の色替え
147:  .mousedown(function(){$(this).css('background-color','palegreen')})
148: }
149:});
150:});

▲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が開きます。