07 | 2017/08 |  09

  1. 無料サーバー

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

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

スポンサーサイト

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

 

jQuery()活用(2) Popup Tips を自作する──jQuery解読(22)

  • 初稿:2007/12/13
  • Update1:2007/12/23 Window下部への popup 飛び出し補正対策を実装。
  • Update2::2007/12/24 popupボックスの「採寸」が各起動要素毎に、一度だけで済むように工夫
  • Update3:2007/12/31 popupされる文字列取得も一度だけで済むように工夫
  • Update4:2010/7/25 全面的な改訂(プラグイン化)

なにはともあれ実例を!

popup Sample Image

上の画像がここでいう popup を表示させた例です。濃い緑色のボックスとその中の白い文字が popup です。黄緑色のボックス内にマウスカーソルをオーバーさせ、 popupが表示 されるようにして、その状態のスクリーンショットを画像化したものです。マウスカーソルの右下に popup ボックスが表示されていることが分かります。

また、この実例部分にも popup 要素を付けましたので、マウスオーバーとなっていると 「popup 実例説明画像」という文字列をコンテンツとする popup が表示されます。

ここで実現した popup の特徴
  1. この popup は後で述べるコードにより実現しており、popup を引き起こすタグ要素(以下、「popup 励起要素」と呼びます)の title 属性値を popup のコンテンツとするように設計しました。つまり、何らかの class 指定を行わなくても jQuery('*[title]') で popup 励起要素を指定することが可能です。
  2. popup 励起要素内で mousemove イベントが起きると、popup 要素はマウスカーソルに追随して移動するように設計しました。
  3. popup する内容には一般的な文字列だけではなく、任意の HTML タグ要素が指定出来ます。例えば番号付き箇条書きや画像を popup させることも可能です。

(ツールチップとしての)Popup

まず実例を提示します。

下の複数の TEST ボックス(これが popup 励起要素に指定されている)内にマウスカーソルをオーバーすると、所定のコンテンツ入り popup がマウスカーソルの右下に表示され、マウスカーソルがボックスから外れると表示が消えます。これがここでいう popup です。マウスカーソルを移動させると popup 要素は追随して移動します。

TEST1 popup コンテンツは文字列
TEST2 popup コンテンツは p 要素
TEST3 popup コンテンツは画像

TEST4 popup コンテンツは動画

動画は自動起動するように設定してあり、別の popup を表示させることにより動画を途中で終わらせることが出来ます。

そもそもこのブログでは、開設(2004年10月)数ヶ月後から随所に popup を利用してきました。その後、微調整や透明化 easing の追加などの修正を行ってきたこの popup は「古典的なイベントハンドル手法」を使用しています。つまり HTML タグの属性として onmouseover/onmouseout ハンドラーを記述する方式で実装しています。

しかし、Microsoft 社の抵抗や無視にも拘わらず、既に DOM Level2 で規定されたイベントハンドリング手法が王道となっている中で、改めて jquery.js を使って popup を作ろうと思い立ち作成しました。jquery.js を利用してどのようにそれを実現するのか、という点で、何らかの参考になれば幸いです。

なお、公開されている jQuery プラグインで toolTips で検索されるものは 103 本( 2010/7/25 現在 )もあり、その多くは可変性・柔軟性において、ここで実現した popup よりも遙かに優れています。それにも拘わらず、独自のプラグインを作成したのは、偏に学習のためであり、どこまで jquery.js を使いこなせるのか、いわば自分を試すためです。

▲ToTop

ここで述べた popup 表示を実現しているコードは次の通りです。

  1:(function($){ //無名関数の指定
  2://jQueryインスタンスメソッド:setPopup の登録
  3:$.fn.setPopup=function(obj){
  4:/* setPopup jQuery インスタンスメソッド
  5: * 任意の要素に記述されている title 属性値を当該要素の popup コンテンツとするためのプラグイン
  6: * 起動例(1): $(function(){$("*[title]").setPopup();});
  7: *  title 属性を有する全ての要素をpopupする対象とする。
  8: * 起動例(2): $(function(){$("*").setPopup();});
  9: *  全ての要素をpopupする対象とする。
 10: * 起動例(3): $(function(){$("p,li").setPopup();});
 11: *  p タグ要素と li タグ要素を popup する対象とする。
 12: * 2010/07/25 Release
 13: */
 14:  //既定値オブジェクトから各プロパティを o オブジェクトに複写
 15:  // obj = {bgColor:"anyColor",maxWidth:"anypx"};
 16:  var opt = obj;
 17:  if (opt && (typeof opt !=="object" || opt.constructor !== Object))
 18:    opt={};
 19:  var o = $.extend({}, $.fn.setPopup.opts, opt),
 20:      //画面サイズ計測関数定義
 21:      getInnerSize = function(obj){
 22:        return {W:$(obj).width(), H:$(obj).height()}
 23:      },
 24:      //スクロール値計測関数定義
 25:      getScroll =  function(obj){
 26:        return {X:$(obj).scrollLeft(), Y:$(obj).scrollTop()}
 27:      };
 28:  //setPopup メソッド起動元 jQuery インスタンスの記憶
 29:  o.$firePopup = this;
 30:  //DOM Ready 登録
 31:  $(function(){
 32:    o.screen = getInnerSize(window); //画面サイズ計測
 33:    o.scroll = getScroll(window); //スクロール値計測
 34:    //Window リサイズイベントハンドラーの登録
 35:    $(window).resize(function(){o.screen = getInnerSize(window)})
 36:      //Window スクロールイベントハンドラーの登録
 37:      .scroll(function(){o.scroll = getScroll(window)});
 38:    //マウス現在座標値の取得メソッド
 39:    $(document.body).mousemove(function(e){
 40:      o.mouse = {  X: e.pageX, Y: e.pageY };
 41:    });
 42:    //popup要素の作成・用意
 43:    o.$popup = $("<div id='popup' />").css({
 44:      position:"absolute", zIndex:10, padding:o.popupPadding, color:o.color,
 45:      background:o.bgColor, border:o.bdWidth + o.bdStyle + o.bdColor,
 46:      textAlign:"left", display:"none"
 47:    }).appendTo(document.body);
 48:
 49:    // popup 要素の設定
 50:    var w,m=[],j,jqIns; //局所変数を用意
 51:    // popup を引き起こす jQuery インスタンス毎にイテレート処理を実施
 52:    o.$firePopup.each(function(i){
 53:      // popup を引き起こす各対象毎に、その title 属性値を
 54:      // popup 要素のコンテンツとするために配列に登録する
 55:      o.content[i] = $(this).attr("title") || null;
 56:      // popup を引き起こす各対象毎に、contentがあれば、
 57:      // popup 要素の算出スタイル幅を測定し、その値を変数 w に格納する。
 58:      w = o.content[i] && o.$popup.html(o.content[i]).width() || null;
 59:      // w が存在する場合、既定の最大値未満ならばそのまま使用し、
 60:          // さもなければ既定の最大値とし、w がない場合には null とする。
 61:      o.popupW[i] = w && (w < o.popupMaxWidth ? w : o.popupMaxWidth) || null;
 62:      // popupすべきコンテンツに img タグがあるかどうか調査し結果を配列 m に格納する。
 63:      m = /(<img\s)[^<]*(src\s?=\s?[\"\'][^\"\']+[\"\']+?)[^<]*(\s\/?>)+?/.exec(o.popupContent[i]);
 64:      // もし変数 m があったならば(img タグだった場合)
 65:      if (m && m[1] ==="<img "){
 66:        // 当該 img タグから jQuery インスタンスを作り、
 67:        // 絶対配置の隠蔽指定をした上で body に挿入する。
 68:        jqIns = $(m[0]).css({position:"absolute",display:"none"}).appendTo(document.body);
 69:        // 挿入された img 要素の算出スタイル値を計算させ、
 70:        // margin 辺間距離から内容辺間距離の差を既に設定済みの o.popupW[i] から
 71:        // 差し引く。
 72:        w = o.popupW[i] - (jqIns.outerWidth(true) - jqIns.width());
 73:        // img タグ要素の width 属性値を書き換えて、画像がpopup
 74:        // ボックスからはみ出さないよう適正に縮小表示されるようにする。
 75:        o.popupContent[i]=o.popupContent[i].replace(m[0],m[1]+m[2]+' border=0 width=\''+ w +'\''+m[3]);
 76:      }
 77:    }).hover( // hover イベントハンドラー登録
 78:      function(){ // mouseover イベントハンドラー
 79:      // 今マウスオーバーとなっている要素の、jQuery インスタンス
 80:      // における登録番号を取得する。
 81:      j = o.$firePopup.index(this);
 82:      // j 番目を popup 要素のコンテンツとして代入してから
 83:      // コンテンツがあれば popup 要素の横幅を設定する。
 84:      if (o.content[j]) {
 85:        o.$popup.html(o.popupContent[j]).width(o.w[j] +"px").fadeIn();
 86:        // title 属性値を削除してブラウザ既定の ツールチップ表示
 87:        // を抑止する。
 88:        $(this).attr("title", "");
 89:    },function (){ // mouseout ハンドラー
 90:      if (o.content[j]) o.$popup.fadeOut(); // コンテンツがあれば隠蔽する
 91:    }).mousemove(function(){ // firePopup 要素内で、マウスカーソルが
 92:     // 動いた時のイベントハンドラー登録
 93:      o.$popup.css({
 94:        // window からはみ出さないように left 値を調整
 95:        left:Math.min(o.mouse.X + o.popupOffset.X,
 96:          o.scroll.X + o.screen.W- o.$popup.outerWidth(true))+"px",
 97:        // window からはみ出さないように height 値を調整
 98:        top:Math.min(o.mouse.Y + o.popupOffset.Y,
 99:          o.scroll.Y + o.screen.H - o.$popup.outerHeight(true))+"px"
100:      });
101:    });
102:  });
103:}})(jQuery);
104:// 既定値を登録する。
105:$.fn.setPopup.opts={
106:  content : [], // 文字列の格納配列
107:  width : [], // popup 要素幅の格納配列
108:  maxWidth : 400, // popup 要素幅の最大幅
109:  popupOffset : {X:16,Y:16}, // popup要素とマウスカーソルの相対的な位置関係を定義
110:  popupPadding : "4px", // popup 要素のパディング値
111:  bgColor: "#eff", // popup 要素背景色
112:  bdWidth: "2px",// popup 要素のボーダー幅
113:  bdStyle: "outset", // popup 要素のボーダースタイル
114:  bdColor: "lightcyan",  // popup 要素のボーダー色
115:  color: "black"  // popup の文字色
116:};

▲ToTop

上のコードの説明と留意点

以下のアンダーライン部には title 属性を設定してあるので popup が表示されます。

構成
  1. jQuery()を最大限利用しました

    どれだけ jquery.js を使いこなせるか、それを課題としたので可能な限り jQuery インスタンスを多用しました。

  2. 初期化ブロック(15~25 行)

    jQuery インスタンス setPopup のプロパティである opts オブジェクトに既定値を設定しておき、ここから変数 o に既定値を複写します。勿論、setPopup メソッドが引数付きで起動された場合には、その引数値が採用されるようにしました

    またスクリーンサイズとスクロール値を取得する 2 つの関数を定義しました。これらは popup 要素の画面からのはみ出しを防止するために必要となる関数です。

    25行では setPopup メソッドの起動元となった jQuery インスタンスへの参照を o オブジェクトの $firePopup プロパティに代入しています。プロパティ名の最初の 1 文字に $ を付けたのは、それが jQuery インスタンスへの参照であることを明示的に示すためであり、この手法は他のプラグインの学習から学びました。

  3. DOM Ready 関数(27 ~ 97 行)

    setPopup メソッドの大半は、その性質上当該頁が読み込まれるのを待たなければ作動させらません。そこで DOM Ready 関数を使いました。

    28 ~ 37 行はスクリーンサイズとスクロール量を計測するものです。28行と29行で頁が開いた時のそれらを計算させ、31 ~ 37 行で window がリサイズされた場合とスクロールされた場合のイベントハンドラーを登録し、それらの変化に対応させています。

  4. 頁内 mousemove イベント(35 ~ 37 行)

    mousemove イベントハンドラーの登録です。頁内でマウスカーソルが動いた時に、マウスカーソルの現在座標値を取得させ o.mouse オブジェクトに値を代入します。

  5. popup要素作成(39 ~ 43 行)

    popup 要素は事前にブログエントリイ内に用意するのではなく、コードによって自動生成させます。勿論作成後に表示させてはなりませんので、display 値を "none" としています。

  6. popup 励起要素に対する様々な設定(48 ~ 95 行)

    47 行に亘る長いブロックでは、jQuery インスタンスのメソッドチェーンを多用しました。popup 励起要素に対する様々な設定を 1 つの jQuery インスタンスに対して行っています。

    48 ~ 72 行迄のブロックでは popup 励起要素各々に対して、その title 属性値を取得し、それを popup 要素内に収めた場合のコンテンツ幅(カレントスタイル値)を算出し、popup 要素のコンテンツ横幅を設定しています。

    ここでは popup 要素のカレントスタイル値の取得が重要なポイントです。文字列の横幅は、一般にブラウザがそれを描かなければ設定されません。jQuery(要素).width() メソッドは、CSSスタイル display 値が none となっている要素に対しても、カレントスタイル値を算出してくれる便利なメソッドです。

  7. popup コンテンツが画像の場合の処理(58 ~ 71 行)

    ここが今回のコード作成で最も苦労した箇所です。

    既に実例で示したように、ここで作った popup はそのコンテンツとして文字列だけではなく、HTML タグ全般を許容します。つまり箇条書きや画像も popup させられます。(勿論動画も可能です。まだ厳密には対応させていませんが、動画 HTML 文に一寸手を加えればここで作った popup 要素内に動画を表示させ自動再生させることが出来ます。)しかし、画像の場合そのサイズが一般に img タグ内に記述されていて、かつここで設定した popup 要素の既定値である 400px を遙かに越える場合が多々あり得ます。そして popup の性質上 1000px を越えるような画像の元サイズで popup することはあり得ないことですから、適正な大きさに縮小表示させなければなりません。

    ここで縮小表示させるために採用した方法は、画像の src 属性値を書き換えるものです。しかし、その属性値の書き換えは容易には出来ませんでした。画像のソース URL 値にはwidth 値が指定されているものもあれば、ないものもありますし、border 属性が設定されている場合もあります。alt 属性もあったりなかったりします。

    このように多様性のある img タグ要素に対して、所定の最大幅を超えないように画像を表示させるためには、正規表現を用いて文字列置換を行うしか方法がない、と判断しそれを実行しました。その正規表現が 58 行の ”呪文 ”です。

    なお、まだ実現していませんが、動画についても同様の方法で正規表現を使ってサイズ調整することを考えています。当面は動画毎に HTML 文に若干手を加えることで対応していきます。

    更に、一般にブログでは img タグに対して何らかの CSS 値が設定されている場合があります。padding 値などが既定のスタイル値としてテンプレートに設定されている場合が多いのです。そこで、画像をブラウザに表示させてカレントスタイル width 値を取得させ、画像のコンテンツ幅と margin 値迄を含む周囲の装飾的な幅との差を算出し、これをpopup要素のコンテンツ幅から差し引くことにより、popup 要素の最大幅に画像が収まるようにしました。これを行っているのが、60 ~ 71 行です。

  8. popp 励起要素に対する hover イベントハンドラー登録(72 ~ 85 行)

    ここでは現在対象となっている popup 励起要素がどれなのかを、どのようにして Javascript インタプリタに知らせるか、それが最大の問題でした。76 行でそれを行っていますが、jQuery(要素).index メソッドの活用が味噌でした。

    popup 励起要素内でマウスが動いた時のイベントハンドラー(85 ~ 96行)では、window 内から popup 要素がはみ出さないよう、スクリーンサイズ、スクロール値並びにマウスの現在値から、popup 要素の配置位置を設定しました。

▲ToTop

留意点
  1. popupを発生させる要素は、title 属性を持ち得る要素ならば、何でも構わないようにしました。しかも title 属性という一般的な属性値を popup コンテンツとし、汎用化を追求しました。

  2. popup コンテンツは文字列だけではなく、広く HTML 文がコンテンツたり得ます。但し動画には未だ対応していません。

  3. popup ボックスの背景色、文字色、枠等々は既定値として、jQueryインスタンス setPopup オブジェクトのプロパティで設定しました。

  4. タグ内の title 属性の値を popup 内のコンテンツとしたため、title 属性に係るブラウザ既定の動きを消さなければなりません。 title 値が二重に popup されてしまうからです。そのために、title = " " を利用しました。

 

● コメント ●

陳謝!ご案内(タイムブログランキング)さんへ (hkom)

 いただいたコメントを間違えて削除してしまいました。
 陳謝!
 アダルト系のスパムコメントが沢山来るので、それを消している時に間違えて貴社からのコメントも消してしまったのです。
 なお、ランキングには参加する意志が皆無ですので悪しからず。
 今回のコメントで二度目ですが、今後は不要です。

■ コメントの投稿 ■

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

●トラックバック●

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

●参照元一覧●

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

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