03 | 2017/04 |  05

  1. 無料サーバー

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

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

スポンサーサイト

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

 

My jQuery Plugin : animated Popup 改訂版

このエントリイの改訂履歴など
  • 初稿:2009/04/19
  • 完結:2009/04/23
  • 第 1 回改訂:2009/04/25 right、bottom 指定をやめ全て left 又は top に統一した。
  • 第 2 回改訂:2009/04/26 画像も表示できるように引数処理を修正した。またポップアップ表示ボックスの色味を自在に操れるように引数を1つ追加した。これらによりこのプラグインの使いやすさが向上した。
  • 第 3 回改訂:背景やボーダーの色が思うように変化しないバグを修正

残念ながら IE ではここで説明するプラグインは動きません。

その理由は IE8 のエラーメッセージに拠れば「 jquery.js のアニメーション関連コードに問題有り 」と表示されるのですが、Firefox、Opera 及び Windows 版 safari で問題なくこのページのアニメーションが表示されるので、エラーメッセージ自体のエラーではないかと思われます。

つまりIE8の標準モードにおけるバグではないかと推測しています。

IE でも動くよう改訂するつもりですが、上のような理由ですので対応策が見つかりません。

ここで言う Animated Popup とは

ポップアップ表示をアニメーションメソッドを使って行うことを意味しています。例えば極小の点から一定の幅と高さを有する表示ボックスをズームポップアップし、それを消すときにはズームアウトするような、そんなポッップアップです。

Windows Vista でウィンドウ開閉時に行われるような、あのようなズームイン/アウトをポップアップ表示/隠蔽にも取り入れてみたいと思い立ち 4月11日頃に作成を開始しました。

何はさておき、その実例を示すことが先決でしょう。

下のボタンをクリックするとあるいはその近傍に、あるいは画面中央に、あるいは画面右下に、あるいは指定してある位置 {left:100px,top:200px} に、ポップアップがズームイン/アウトされます。表示する際のポップアップサイズは順に300、350、400、500px に、またアニメーションに要する時間はそれぞれ 1200、600、1600、2000 ミリ秒に設定してあります。

 クリックした位置の傍にポップアップ表示します。

クリックすると画面の中央にポップアップ表示します。

クリックすると画面の右下にポップアップ表示します。

クリックすると指定してある位置にポップアップ表示します。

クリックすると画面の中央に或るサイトの或る写真をポップアップ表示します。写真出典元は フォトライブラリ です。

▲ToTop

Animation と Easing

Easing は Animation 動作速度を変化させる「加速度メソッド」のことで、元々 Flash ツールである Acrion Script の Tween クラスの加速度メソッドとして誕生したようです。(半可通の知識しか持ち合わせていないので「ようです」としておきます。)

この Easing 関数が jQuery プラグインとして提供されているので、早速それを導入し、このページでは敢えて動きの激しい easeOutElastic を使用しました。本来、文字を表示するには変化の激しい elastic は相応しくないでしょうが、Easing を初めて使用した記念として「激しい」ものを選択してみたのです。

因みに、George Smith 氏により提供されているプラグイン「Easing Plugin」は、10種類あり、各々に3つの効果(easeIn、easeOut、easeInOut)を持たせて Easing 関数が定義されているため、都合 30 種類の easing 関数があります。→ Plugins | jQuery Plugins

その Easing の各々の動きの違いを示したサイトとして興味深いのは、flash ムービーですが easing_demo が実に分かりやすく有益です。これによりそれぞれの Easing がどんな挙動をするのか一目瞭然に理解できます。easing 関数内の代数式がグラフ化されていることも非常に有益です。

そこで、このデモサイトをまねて、このページ上で実現しているアニメーションポップアップに対して 32 種類の Easing 効果を適用するリストボックスを設置してみました。easing_demo に比べて文字表示の場合には各 easing の差異がわかりにくいのですが、まあそれはご愛敬ということで...。

下のリストボックスの説明
  • アニーメーションポップアップの表示位置は 「 画面中央 」 としました。
  • Easing に要する時間はそれぞれの関数の差異が分かり易いように長めに設定しました(2秒)。
  • jquery.js に組み込まれている linear と swing の 2 つの Easing 関数もリストアップしたので都合 32 種類の easing 関数が登録されています。
  • 別の easing 関数を選択する前に表示されているポップアップを隠蔽する必要はありません。自動的に前の表示を消して、新たな表示を行います。
補足:上の リストボックスに係るスクリプトの説明

このページのソースコードを表示すれば分かることですが、jquery.js を使って初めて form を扱ったので、記録を残すために敢えてここに記します。

■アイテムが選択された際の処理を行うスクリプトコード
$("#sel665").change(function(){
 var index = this.selectedIndex,
   selEasing = this.options[index].value,
   txt="これは easing 関数: "+selEasing+" を使って<br />表示/隠蔽するアニメーションポップアップです。";
 $(this).animatedPopup(txt,["c","c"],2000,selEasing,{width:"400px"});
});
html説明
selectタグに id="sel665" と size=10を、最初の option タグに非選択属性 disabled="disabled" を、二番目の option タグに初期値 selected="selected" を設定しました。
Javascript 説明
  • 要点は selectタグの jQuery インスタンスに change イベントを登録することです。
  • まずリストボックスから選択されたアイテムのインデックス番号を変数に代入し、その値を使って options 配列から選択されたアイテムの value 値を取りだし、最後にポップアップ文を構成します。
  • 以上の僅か 3 つの変数を定義するだけで準備は完了。後は適切な引数付きで animatedPopup メソッドを登録するだけです。

以上の簡単なコードによって、リストボックス内の項目が選択されたその瞬間に発生する change イベントにより、イベントハンドラーが起動されて必要な処理を行います。

▲ToTop

作成した Animaeted Popup の仕様

  • 作成した Animaeted Popup は jquery.js のプラグインとして組み込める形式としました。
  • Animaeted Popup の呼び出しは次の書式で行います。jQuery(expr) はjQueryインスタンスならば何でも構いません。
    jQuery(expr).animatedPopup(contents, layout, duration, easing, options, options2);
  • <引数の説明>
     * contents: Strings in Animated Popup
     * layout: displaying position of Animated Popup
     * 	       text,ex. ["c","t"] (It means :left="center",top="top")
     *         or object,ex.{left:"100px",top:"200px"}
     *         or {left:"center",top:"100px"}
     * duration: durating time of animation(msec), ex.500 or "slow" etc.
     * easing: easing name (text), ex."easeInOutQuad","easeOutBounce",..32通りの指定が可能
     * 但し 32 種類を利用するには Easing Plugin を組み込む必要がある。
     * このサイトで利用している jquery.js には Easing Plugin を組み込み済みです。
     * options: Add CSS Object to Popup DIV, ex.{width:"400px",・・・}
     * options2: Add CSS Object to Popup DIV's CLOSE Bar, ex.{background:"midnightblue",・・・}
     * 全ての引数にはデフォルト値が設置済みなので複数の任意の引数が省略されても誤動作しません。
     * 何も引数がない場合、その旨を表示する animatedPopup を画面中央に表示します。

▲ToTop

作成した Animaeted Popup の Javascript コード

コードは長めになりました。説明を含めて 190 行あります。

ここでその全てを掲載しブロックごとに解説を加えることとします。

animatedPopup プラグインの全コード
  1:(function($){
  2:$.fn.extend({
  3:animatedPopup: function(contents,layout,duration,easing,options,options2){
  4:/*
  5: * <Example of Implementation>
  6: * jQuery("p").animatedPopup("And I love you so. Yesterday. Yellow Submarine.",
  7: *   ["c","b"],800,"swing",{width:"300px"})
  8: *
  9: * <arguments explanation >
 10: * contents: Strings in Animated Popup
 11: * layout: displaying position of Animated Popup
 12: *      text,ex. ["c","t"] (It means :left="center",top="top")
 13: *      or object,ex.{left:"100px",top:"200px"}
 14: *      or {"left":"center","top":"100px"}
 15: * duration: durating time of animation(msec), ex.500 or "slow" etc.
 16: * easing: easing name (text), ex."easeInOutQuad","easeOutBounce",...
 17: * options: Add CSS Object to Popup DIV, ex.{"width":"400px",・・・}
 18: * options2: Add CSS Object to Popup DIV's Title DIV, ex.{background:"midnightblue",・・・}
 19: *
 20: * <history>
 21: * released 2009/4/22 ver0.1
 22: * update 2009/4/25 ver0.2, 2009/4/26 ver0.3
 23: */
 24: var jQInst=$(this), winWH = {width:$(window).width(),height:$(window).height()},
 25:  errFlag,lcr,tcb,xName,yName,m=[],addValue={x:0,y:0},isImg,
 26:  mousePos={left:0,top:0},xCenter=$(window).width()/2,yCenter=$(window).height()/2;
 27:  // CSS 既定値は width 値が contents により変わるので、関数化しインスタンス毎に設定する。
 28: var defaultCSS =function(){
 29:  isImg = contents.match(/.*((<img.+src.+)|(<object.+)|(<embed.+)).*/i);
 30:  return {
 31:   "color":"white","font-weight":"bold","margin":0, "padding":"19px 5px 5px 5px",
 32:   /* 画像の場合ここで width を決めては駄目*/
 33:   "width": (isImg && isImg[1]) ? null : "300px",
 34:   "background-color":"royalblue", "border":"5px plum ridge", "text-align":"center",
 35:   "display":"block","visibility":"visible"
 36:  }
 37: }
 38: /* ポップアップに使用するCSS値を設定する*/
 39: var popupCSS = $.extend(true,defaultCSS(),options || {});
 40: /* closeBar CSS値も容易に変更できるように設定する */
 41: var closeBarCSS = function(){return $.extend(true,{
 42:  "position":"absolute","zIndex":"1001","text-align":"center",
 43:  "opacity":0.75,"top":0,"left":0,"width":"100%","cursor":"pointer",
 44:  "font-size":"small","lineHeight":"1.2em","background-color":"midnightblue"
 45: },options2 || {})};
 46:
 47: // bind onmousemove event on document
 48: mousePos.oX = 4; mousePos.oY = 16; //マウスカーソルからの離隔距離
 49: $(window).mousemove(function(e){
 50:  mousePos.left = (jQuery.browser.msie ? window.event.clientX - document.body.clientLeft : e.clientX) + mousePos.oX;
 51:  mousePos.top = (jQuery.browser.msie ? window.event.clientY - document.body.clientTop : e.clientY) + mousePos.oY;
 52: });
 53:
 54: // error 処理関数(後に拡張できるように関数にしておく)
 55: var errFunc = function(){ errFlag=true; return function(){return}}
 56:
 57: // animatedPopup の配置位置算出関数
 58: var getPos = function(layout){
 59:  if (layout && layout.constructor!= Object && layout.constructor!= Array ){
 60:   alert("配置は2つのテキスト:例 \"Center\",\"Top\" 、または\nオブジェクト形式:例 {left:\"10px\",top:\"100px\"} で指定してください。");
 61:   errFunc()();
 62:  }
 63:  var setPos = layout;
 64:  if (setPos.constructor==Array) {
 65:   var chk1 = /^((l.*)|(c.*)|(r.*))/.exec(setPos[0].toLowerCase());
 66:   var chk2 = /^((t.*)|(c.*)|(b.*))/.exec(setPos[1].toLowerCase());
 67:   if (chk1 && chk2){
 68:    lcr = chk1[2] && "left" || chk1[3] && "center" || chk1[4] && "right";
 69:    tcb = chk2[2] && "top" || chk2[3] && "center" || chk2[4] && "bottom";
 70:    xName = (lcr!=="right") ? "left" : "right";
 71:    yName = (tcb!=="bottom") ? "top" : "bottom";
 72:   } else {
 73:    if (!chk1 && !chk2) {
 74:     alert("左右上下 \""+ setPos[0] +" , "+ setPos[1] +"\" 共に指定が間違っています。\nやり直してください。");
 75:    } else if (!chk1 && chk2){
 76:     alert("左右の指定 \""+ setPos[0] +"\" が間違っています。\nやり直してください。");
 77:    } else if (chk1 && !chk2 ){
 78:     alert("上下の指定 \""+ setPos[1] +"\" が間違っています。\nやり直してください。");
 79:    }
 80:     errFunc()();
 81:   }
 82:  } else if (typeof setPos!=="string" && setPos.constructor==Object) {
 83:   for (name in setPos){
 84:    name=name.toLowerCase();
 85:    if (name=="left" || name=="right") {xName = name;lcr=name}
 86:    if (name=="top" || name=="bottom") {yName = name;tcb=name}
 87:   }
 88:   if (xName==null || yName==null){
 89:    alert("left、right、top、bottom 以外の\n指定は無効です。やり直してください。");
 90:    errFunc()();
 91:   }
 92:   // 位置指定値が "left" のように文字で為されたときの対応
 93:   if (!setPos[xName].match(/\d+/))
 94:    m[0] = setPos[xName].toLowerCase().match(/^(left|center|right)$/);
 95:   if (!setPos[yName].match(/\d+/))
 96:    m[1] = setPos[yName].toLowerCase().match(/^(top|center|bottom)$/);
 97:   if (!setPos[xName].match(/\d+/) && m[0]===null || !setPos[yName].match(/\d+/) && m[1]==null){
 98:    alert("配置指定値が間違っています。\nやり直してください。");
 99:    errFunc()();
100:   }
101:   addValue={
102:    x :( m[0] ? ((m[0]==="center") ? xCenter :0) : parseInt(setPos[xName])),
103:    y :( m[1] ? ((m[1]==="center") ? yCenter :0) : parseInt(setPos[yName]))
104:   };
105:  } else if(layout){
106:   alert("配置指定が無効です。やり直してください。"); errFunc()();
107:  }
108:  var obj={};
109:  obj[xName]= ((lcr==="center") ? xCenter : 0) + addValue.x;
110:  obj[yName]= ((tcb==="center") ? yCenter : 0) + addValue.y;
111:  return obj;
112: };
113:
114:$(function(){
115: // popup 表示用の div 要素タグの作成
116: if (!$("#dispElem").size()) {
117:  $("<div id='dispElem'></div>").css({
118:   position:"absolute",display:"none",zIndex:"1000"
119:  }).appendTo(document.body);
120: }
121: var disp=$("#dispElem");
122:
123: // Popup 隠蔽用×タグの作成
124: if (!$("#xMark").size()){
125:  $("<div id='xMark'>CLOSE</div>").append("<div style='width:13px;float:right;margin-top:-1em;'>×</div>").appendTo(disp);
126: }
127: var xMark = $("#xMark").css(closeBarCSS());
128:
129: // STEP1:*************** 表示前に popup エレメントの高さを測定する
130: var getElemWH= function(){ // 表示 popup サイズ算定
131:  // popup 表示前に横幅と文字数に応じた高さを計測する(非表示描画で測定)
132:  contents = contents || "ポップアップする内容が指定されていません。<br />やり直してください。";
133:  disp.html(contents).css($.extend(true,popupCSS,{"visibility":"hidden","height":null}));
134:  if(isImg && isImg[1]) disp.css("width",null);
135:  return {
136:   iW: popupCSS.width=(options && parseInt(options.width) || defaultCSS().width && parseInt(defaultCSS().width) || disp.width()),
137:   iH: popupCSS.height=disp.height(),
138:   oW: disp.outerWidth(),oH: disp.outerHeight()
139:  }
140: }
141:
142:  // 幅/高さが極小の要素 css 値を設定する。これにより拡張/縮小を演出する。
143:  // またここで初めてスクロールされていた場合の変動値を配置px値に追加する。
144: var shrinkCSS=function(){
145:  var scrLeft=$(window).scrollLeft(),scrTop=$(window).scrollTop(),
146:   obj={"width":"1px", "height":"1px", "border":"0px", "padding":"0px","margin":"0px"};
147:  if (!layout){
148:   obj.left=mousePos.left+scrLeft+"px";
149:   obj.top=mousePos.top+scrTop+"px";
150:  } else {
151:   var pos = getPos(layout);
152:   if (errFlag) return;
153:   obj.left=((xName=="left")-(xName=="right"))*pos[xName]+
154:    (xName=="right")*winWH.width + scrLeft+"px";
155:   obj.top=((yName=="top")-(yName=="bottom"))*pos[yName]+
156:    (yName=="bottom")*winWH.height + scrTop+"px";
157:  }
158:  return obj;
159: }
160:
161: var hideElem = function(e){ // popup 要素をアニメーション隠蔽する
162:  disp.empty().animate(shrinkCSS(),{queue:false,duration:duration,easing:easing});
163: }
164: var animaElem = function(e){
165:  $(":animated").queue('fx',[]).stop(); // 登録済みのアニメを全て削除停止する
166:  var doneShrink = shrinkCSS(); // この関数内で1回だけ起動する
167:  if (errFlag) return;
168:  // STEP2:***************
169:  var elemWH = getElemWH(); //エレメントサイズ計測実行
170:  if (!layout){ // 画面からはみ出さないように CSS 値を調整
171:   if (winWH.width < mousePos.left+elemWH.oW)
172:    popupCSS.left = winWH.width + $(window).scrollLeft() - elemWH.oW +"px";
173:   if (winWH.height < mousePos.top+elemWH.oH)
174:    popupCSS.top =  winWH.height + $(window).scrollTop() - elemWH.oH +"px";
175:  } else { // popup をセンター配置する場合の CSS 設定
176:   popupCSS.left = parseInt(doneShrink.left) -
177:    ((lcr==="center" || m[0] && m[0]==="center") ? Math.round(elemWH.oW/2) : (xName==="right") ? Math.round(elemWH.oW) :0) +"px";
178:   popupCSS.top = parseInt(doneShrink.top) -
179:    ((tcb==="center" || m[1] && m[1]==="center") ? Math.round(elemWH.oH/2) : (tcb==="bottom") ? Math.round(elemWH.oH) :0) +"px";
180:  }
181:
182:  // STEP3:*************** 極小要素を指定されたアニメーション起動位置に配置
183:  // dispElem の幅と高さを1pxにして所定位置に配置する(但し非表示描画)
184:  disp.empty().css(doneShrink);
185:  // STEP4:*************** 表示アニメーション
186:  disp.html(contents).append(xMark.css(closeBarCSS()))
187:   .css({visibility: "visible",display:"block"})
188:   .animate(popupCSS,{queue:false,duration:duration||"slow",easing:easing||"swing"});
189:  // STEP5:*************** × クリック時に隠蔽アニメーションを起動する。
190:  // ここで隠蔽関数を起動するようにしておかないと、複数回ボタンがクリックされた
191:  // 場合に隠蔽操作ができなくなる。理由は未解明。
192:  xMark.click(hideElem);
193: }
194: jQInst.click( errFlag ? function(){errFlag=false; $(this).unbind("click");} : animaElem );
195:}); // End of "DOMReady function"
196:} // End of "animatedAlert function"
197:}); // End of "Extend function"
198:})(jQuery);

▲ToTop

animatedPopup プラグインの解説

その意味や役割から幾つかのブロックに分けて解説します。

第Ⅰブロック(#1-22)

まず最初のブロックは、このメソッドの引数を定義しそれらを解説している部分です。

無名関数による起動と DOMReady 関数の利用(#1、#100)

このプラグインでは、一般的方法に倣って全体を無名関数で括り、即実行するようにしました。またポップアップ表示やポップアップ消去のための絶対配置 div 要素を追加し、かつそれらに様々なメソッドを適用する必要があることから、必要最小限の範囲を DOMReady function で括りました。

$.fn.extend クラスメソッドの利用(#2)

これにより、jQuery インスタンスのメソッドとして animatedPopup 関数を登録します。

animatedPopup 関数の引数(#3-18)

引数は6つあります。第一引数はポップアップボックス内に表示する文字列で、第2引数 layout は様々な方法でポップアップ位置を指定できるよう工夫し、第2引数を指定しない場合には、起動元 jQuery インスタンスが指し示す要素の近傍にポップアップするように設計しました。

第5及び第6引数も工夫しました。extend メソッドの2つめの使い方、つまり「 オブジェクト拡張 」を利用して、popup 要素のデフォルトCSS を設定しておくと共に、options で自在にそれを変更できるようにしました。幅や色、ボーダーの色と幅等々気分自由に変更することが出来るようにすることが目的であり、それを達成しました。

なお、この方法は jquery.js の Ajax ブロックで採用されていますのでそれを参考に考案しました。

▲ToTop

第Ⅱブロック(#24-45)

このブロックは、ローカル変数を定義している部分です。

■変数定義部分(再掲)
 24: var jQInst=$(this), winWH = {width:$(window).width(),height:$(window).height()},
 25:  errFlag,lcr,tcb,xName,yName,m=[],addValue={x:0,y:0},isImg,
 26:  mousePos={left:0,top:0},xCenter=$(window).width()/2,yCenter=$(window).height()/2;
 27:  // CSS 既定値は width 値が contents により変わるので、関数化した。
 28: var defaultCSS =function(){
 29:  isImg = contents.match(/.*((<img.+src.+)|(<object.+)|(<embed.+)|(<iframe.+)).*/i);
 30:  return {
 31:   "color":"white","font-weight":"bold","margin":0, "padding":"19px 5px 5px 5px",
 32:   /* 画像の場合ここで width を決めては駄目*/
 33:   "width": (isImg && isImg[1]) ? null : "300px",
 34:   "background-color":"royalblue", "border":"5px plum ridge", "text-align":"center",
 35:   "display":"block","visibility":"visible"
 36:  }
 37: }
 38: /* ポップアップに使用するCSS値を設定する*/
 39: var popupCSS = $.extend(true,defaultCSS(),options || {});
 40: /* closeBar CSS値も容易に変更できるように設定する */
 41: var closeBarCSS = function(){return $.extend(true,{
 42:  "position":"absolute","zIndex":"1001","text-align":"center",
 43:  "opacity":0.75,"top":0,"left":0,"width":"100%","cursor":"pointer",
 44:  "font-size":"small","lineHeight":"1.2em","background-color":"midnightblue"
 45: },options2 || {})};
jQuery インスタンスの取得(#24)

まず最初にこのプラグインの呼び出し元となる jQuery インスタンスを取得します。

DOMReady 関数内で jQuery インスタンスを呼び出そうとしたのですが、関数内では this は window オブジェクトを参照してしまうため、前もってここで取得しておくことにしました。

表示中の window の幅と高さの取得(#24)

これは jquery.js で定義されているクロスブラウザな便利なメソッドをそのまま活用しました。

これらの値を取得する意味は、画面の中央や左や右にピタリと寄せて配置する場合に利用するためです。

ポップアップ窓のデフォルト CSS 設定(#28-37)

ボーダーやパディング、そして色と背景色──これらの初期値を定めておかないとその都度思案し確定し指定しなければなりません。これはいかにも面倒なので既定値を設定しました。options で特に指定しなければ既定値が適用された popup 窓が表示されるわけです。

実は画像や動画にも対応させるために、最終段階でこのブロックを大きく改変しました。

#29 では正規表現を利用して img タグ、object タグ、embed タグ、あるいは iframe タグ文字列が第一引数 contents に含まれるかどうかをチェックします。そしてそれらのいずれかが含まれる場合には、デフォルト値としての画像サイズを設定しないこととしました。(#33)

これは引用先のCSS設定を反映する場合があったので、敢えて width 値を定めずにおいて、引用先サイトの padding 設定値なども反映した outerWidth 値を取得するためです。

実際に表示するポップアップ窓の CSS 値の指定(#38-39)

これには extend メソッドの2つめの機能である"ボブジェクト拡張"を利用しました。

optionsで任意の CSS 値を与えれば、デフォルトCSSを上書きしてユーザーの要望通りの表現を実現することが出来ます。また ||{} により options が指定されなかった場合にデフォルト値を利用するように工夫しました。

ポップアップ窓上辺の CLOSE バー CSS 値の指定(#40-45)

これも extend メソッドの"ボブジェクト拡張"を利用しました。

options2で任意の CSS 値を与えれば、デフォルト値を上書きしてユーザーの要望通りの表現を実現することが出来ます。また ||{} により options2 が指定されなかった場合にデフォルト値を利用するように工夫しました。

その他の変数(#25-27)

重要な役割を果たすローカル変数をここで定義しました。

addValue は配置位置がピクセル指定された場合のそのピクセル値を格納します。

mousePos はイベント発生要素の近傍にポップアップを配置する場合に必要となるマウスカーソルの現在値を所得するための変数です。

xCenter、yCenter は画面中央に配置するために必要な値で、それぞれ横方向の画面中央位置、縦方向の画面中央位置を取得します。

▲ToTop

第Ⅲブロック:マウス move イベントの登録とエラー対応(#4752)

第2引数 layout を指定しない場合に、マウスカーソル近傍にポップアップさせるためには、マウスの動きを常に Javascriptが 「監視」 しその位置を取得していなければなりません。そのためのイベント登録を行う部分です。これにより document の任意の箇所においてマウスカーソルの動きを常駐監視し、その位置を取得することになります。

 47: // bind onmousemove event on document
 48: mousePos.oX = 4; mousePos.oY = 16; //マウスカーソルからの離隔距離
 49: $(window).mousemove(function(e){
 50:  mousePos.left = (jQuery.browser.msie ? window.event.clientX - document.body.clientLeft : e.clientX) + mousePos.oX;
 51:  mousePos.top = (jQuery.browser.msie ? window.event.clientY - document.body.clientTop : e.clientY) + mousePos.oY;
 52: });
 53:
 54: // error 処理関数
 55: var errFunc = function(){ errFlag=true; return function(){return}}

ここでも IE が、IE だけが特殊な方法を採用しており、そのために面妖な設定をしなければならないのはユーザーにとって不幸なことです。早く IE のユーザー比率が低下することを願ってやみません。IE8 の登場によりその願いはまた叶うことなく先送りされてしまいましたが、中長期的には IE 固有の仕様は消え去る運命にあることは間違いないでしょう。

実際、後のエントリイで触れましたが、IE8 では少なくともスタイル設定に関しては Web 標準準拠に切り替わりました。これは 1 社だけで頑迷に固執し続けてきた奢りが、10年来のブラウザ戦争の中でやっと崩れ去ったことを意味しており、記念すべき歴史的事件と言って差し支えないでしょう。

#54 のエラー対応は「関数を返値とする」特殊な関数を利用します。これにより返値は return 値を有する関数となるので、errFunc()() のようにして、返値である関数を呼び出し先で実行することによりトップレベルにおいて return 値を返すことが可能となります。

ここに最初の括弧は errFunc 関数を実行するため、2つめの括弧は errFunc 関数の返値としての関数を実行するためです。#61 など随所で活用しています。

▲ToTop

第Ⅳブロック:ポップアップ配置位置の設定メソッド(#57-112)

このブロックはたった1つのメソッド登録ですが長大になりました。しかし、様々な指定方法に対応するために必要不可欠な部分であり、長くなってしまったのはエラー処理をふんだんに盛り込んだためでもあります。

#59-62 は最初のエラー処理です。

不適切な layout 指定があった場合の警告表示とコード進行停止を指定しています。

#64-82 は layout が配列だった場合の処理です。

#65-72 で、left、le あるいは l だけでも受容するように指定文字を簡略化できるように工夫し、所定の文字が与えられた場合には、それらを left、center、right、top、bottom の文字列に変換しています。

lcr には left、center、または right の文字が入力され、tcb には top、center、または bottom が代入されます。

また、xName には left か right が、yName には top か bottom が代入されます。

#73-81 は配列指定が適切ではなかった場合のエラー処理です。

#82-107 は layout がオブジェクト指定された場合の処理です。

#83-87では layout オブジェクトを走査して、配置指定に係る定義値を取得し、変数に代入します。捜査の結果必要な文字がなければ #88-91 でエラー処理します。

#92-100 は 配置指定が px 値ではなく "center" などの文字列で行われた場合の処理です。

#93-97 で配列 m に横方向と縦方向の配置指定文字列を代入し、layout が適切な指定でなければ、#97-100 でエラー処理します。

#101-107 では縦横方向の配置指定値を取得します。

二項演算子を活用して、センター配置か否か、及び px 指定値がある場合の2つのケースから値を取得します。

エラー発生時には空オブジェクトを返すようにしました。

#108-110 ではここ迄の処理で確定した配置用変数を活用して CSS 値を設定します。

センター配置の場合のみ画面中央位置を取得し、その他は指定されていればピクセル値を代入します。

▲ToTop

第Ⅴブロック:ポップアップ用 div 要素の作成(#111-134)

ブラウザにとってポップアップ用要素が用意できなければ何も始められないため、これ以降は DOMReady 関数で括ります。

popup 表示用の div 要素タグの作成(#115-120)

2回目以降の animatedPopup 起動時に dispElem が重複設置されないように 116 行でこのノードの存在確認を行います。もし存在すれば、改めて変数 disp に当該ノードを参照する jQuery インスタンスを登録します。

存在しない場合には、タグ要素を CSS 設定値を含めて作成し、その後に jQuery インスタンスを作成し変数に代入します。

この CSS 設定では絶対配置、非表示、レイヤー順を指定し、ポップアップを自在に配置できるように、また body 部に追加した時点ではそれが表示されないよう準備します。

popup 隠蔽用×印タグの作成(#123-127)

ポップアップ用 div 要素の右上にこのポップアップを隠蔽するためのバツ印を用意しました。ここでも二重登録しないようにこの要素の存在確認を行います。

更に×印だけではマウスカーソルをその位置にフィットする手間が面倒なので、隠蔽クリックを受け入れる箇所を点から線に拡張して、タイトルバー形式にしました。

▲ToTop

第Ⅵブロック:アニメーション用の諸関数定義(#129-193)

ここ迄でアニメーションポップアップのための準備が終わりました。愈々、動きのあるポップアップ表示や隠蔽操作のための関数を定義します。

ポップアップする要素の高さのサイズを測定する getElemWH 関数

まず第一引数 contents が未指定の場合の対応を 132 行で行いました。未指定の場合には所定の文章( || の右側の文章 )を用意しておき、これを animetedPopup 関数を使ってポップアップします。

文字列をポップアップする場合特に、その要素サイズを「表示前に」如何にブラウザに知らせるかが課題となります。文字列の文字数が固定されていても、文字の横幅は一定ではないので内容によってはサイズは変わりますし、一般にポップアップ表示を行う文字列は長さは不定・可変です。そのためブラウザは、幅が指定されていなければ表示領域一杯の幅が指定されたものと見なし、或いは要素の幅が指定されている場合にはその幅で要素を表示しますが、ブラウザはこれらのいずれの場合においても、要素表示前にはその要素の高さを認識しません。

別のエントリイで不定型ボックスサイズを表示する前にブラウザに認識させる方法について詳細に触れましたが、このプラグインで採用した方法は、自前で考案した透明化してサイズを測定する方法ではなく、jquery.js で利用されている visibility 属性を利用する方法を採用しました。

jquery.js で採用している表示前サイズ計測方法は、1. position : absolute、2. display : block、3. visibility : hidden とすることにより、「絶対配置のブロック表示状態にしてそれを表示させない」状態を作るものです。(jquery.js: css 関数内の #773 で呼び出される #735-748 の swap 関数)

なお、このプラグインで実際に必要となるのは outerHeight と innerHeight なのですが、この際無意味ですが4つのサイズを測定しておくようにしました(苦笑)。

またinnerHeight については、代入式を iH のプロパティ値とすることにより、同時に 2 つのプロパティに値を取得させました。

ポップアップボックスの拡張/縮小を演出する shrinkCSS 関数

アニメーションを演出するために幅と高さが極小のスタイル値を設定します。これによりアニメーションの始点と終点の位置と要素の表示状態を取得します。

またアニメーションの始点/終点を取得するためには、縦横のスクロール状態を Javascript インタープリタに認識させなければなりませんから、この関数内でスクロール値を取得します(#145)。

後述するように、クリック時のイベントハンドラー内から、shrinkCSS 関数を呼び出して、そのときのスクロール値を取得します。

次にこの関数内から #151 で getPos 関数を呼び出していますが、これにより画面内の左右上下中心のどの位置に配置するか、あるいはマウスカーソルの近傍に配置するかを確定します。

エラーフラグが立っている場合にはコード進行を止めます。(#147)

#153-156で right や bottom 指定された場合に left や top に変換しています。

right / bottom 指定された値をleft / top に変換する計算式は、最後の最後まで苦労を重ねました。getPos 関数からの戻り値は、right / bottom 指定のママですが、#153-156 においてこれらを left / top に変換します。この結果 shrinkCSS 関数からの戻り値は left / top のみとなります。

popup 要素をアニメーション隠蔽する hideElem 関数

これはいわば逆アニメーションで、animaElem 関数で表示したポップアップを縮小しながら隠蔽します。最初にコンテンツを削除してから shrinkCSS 関数をよびだし、かつこのアニメーションを待ち行列に登録しないよう queue 値を false にします。

なお、shrinkCSS 関数でエラーが発生する可能性がありますが、hideElem 関数は、必ずanimaElem 関数が走行した後にしか起動されず、animaElem 関数内において shrinkCSS 関数にエラーが発生した場合の処理は記述されています。エラー発生時には hideElem 関数呼び出しまで到達しませんので、当該関数ではエラー処理を必要としません。

アニメーションポップアップ表示を行う animaElem 関数

ここでは次のような様々な処理を行っています。1.登録アニメーションの削除と停止(#165)、2. この関数内で一回だけ shrinkCSS 関数を呼び出し、結果を変数に記録(#166)、この返値が空の場合の処理(#167)3.画面からポップアップをはみ出させない処理(#170-174)、4.画面センターに配置する場合、あるいは right / bottom が指定された場合の、ポップアップサイズと表示位置の調整(#176-180)、4.アニメーションの始点設定(#184)、5.アニメーション表示(#186-188)(ここでも隠蔽処理同様に待ち行列には登録しません。)、そして 6.ポップアップ窓の隠蔽ハンドラー呼び出しです(#190-192)。

ここでの要点は以下の点です。

  • ポップアップ要素を画面外にはみ出させない処理のために必要となる要因は、画面サイズ、スクロール値及びポップアップ要素のサイズです。
  • アニメーション待ち行列の扱いは、全てのアニメーションを非登録としました。当然ですが登録してしまうと、二度目以降の animatedPopup() 起動時において、最初以降から直前までの以前に利用したアニメーションが順次起動してしまうためです。
  • 179行で、duration や easing が指定されなかった場合のデフォルト値を設定しました。
  • ポップアップの隠蔽はクリックイベントを登録して行いますが、表示関数の中から行うようにしました。連続してクリックしてポップアップさせた場合に、クリックしてもそれを消せない場合が発生したためです(原因は不明)。

▲ToTop

第Ⅶブロック:クリックイベントの登録(#190)

最後の処理です。要素タグへのクリックイベント登録では、エラー発生時に登録済みクリックイベントを削除するようにしました。ここで最初にして最後ですが errflag 値を利用します。

イベントハンドラー内で使用した $(this) は click が jQInst のメソッドですから、jQInst を参照します。

 

■ コメントの投稿 ■

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

●トラックバック●

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

●参照元一覧●

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

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