第8回 ドラッグ可能なポップアップウインドウを作ろう – jQuery入門

2009 年 5 月 12 日 投稿者: naga3

第8回はjQueryでポップアップウインドウを作ってみましょう。ポップアップウインドウを実現するプラグインは、jQuery UIのダイアログや、jqModalなど優秀なものが沢山あるので、それらに劣るものを車輪の再発明する必要はないのですが、シンプルで改造し易いものが欲しくなる・・・かも知れませんので作ってみます。
もし使ってみたい人がいましたら配布・改造ご自由にどうぞ。連絡も必要ありません、が連絡頂けたら嬉しいかも。
名前は適当に「ipop.js」としました。
動作サンプル

ipop.jsのソース

ファイルが必要ならば右クリックで保存してください。
JavaScript
テスト用のHTML
(function($) {
    $.ipop = function() {
        var wx, wy;        // ウインドウの左上座標
        var mx, my;        // マウスの座標

        // ウインドウの座標を画面中央にする。
        wx = $().scrollLeft() + ($(window).width() - $('#ipop').outerWidth()) / 2;
        if (wx < 0) wx = 0;
        wy = $().scrollTop() + ($(window).height() - $('#ipop').outerHeight()) / 2;
        if (wy < 0) wy = 0;

        // ポップアップウインドウを表示する。
        $('#ipop').css('top', wy).css('left', wx).fadeIn(100);

        // 閉じるボタンを押したとき
        $('#ipop_close').click(function() {$('#ipop').fadeOut(100);});

        // タイトルバーをドラッグしたとき
        $('#ipop_title').mousedown(function(e) {
            mx = e.pageX;
            my = e.pageY;
            $().mousemove(mouseMove).mouseup(mouseUp);
            return false;
        });
        function mouseMove(e) {
            wx += e.pageX - mx;
            wy += e.pageY - my;
            $('#ipop').css('top', wy).css('left', wx);
            mx = e.pageX;
            my = e.pageY;
            return false;
        }
        function mouseUp() {
            $().unbind('mousemove', mouseMove).unbind('mouseup', mouseUp);
        }
    }
})(jQuery);

使い方

JavaScriptの先頭のコメント及びipop_test.htmlを見ると、だいたいは分かると思います。
<div id="ipop">
  <div id="ipop_title">タイトル</div>
  <div id="ipop_close">閉じるボタン</span>
  中身
</div>
このような形式でポップアップする部分を作って、$.ipop()で呼び出すだけです。
CSSとして、
#ipop {
    position: absolute;
    display: none;
    z-index: 9999;
}
この3行は必須です。他のCSSは適当で良いです。

プログラムの解説

まずプログラム全体を
(function($) {・・・})(jQuery);
という部分で囲っていますが、他のライブラリとの名前の衝突を避けるために$が使えなくしている場合の処置です。最後の(jQuery)は、jQueryを引数に取った関数呼び出しです。つまりプログラムの中ではjQueryが$という名前として使えるわけです。なんともうまいやり方です。

ウインドウの座標を画面中央に表示する

wx = $().scrollLeft() + ($(window).width() - $('#ipop').outerWidth()) / 2;
if (wx < 0) wx = 0;
wy = $().scrollTop() + ($(window).height() - $('#ipop').outerHeight()) / 2;
if (wy < 0) wy = 0;
ポップアップウインドウを画面中央に表示するために座標を計算している部分です。$(window).width()で画面全体の幅、$('#ipop').outerWidth()で要素#ipopの(ボーダーも含めた)幅を取得できます。$().scrollLeft()は、右へのスクロール量が取れます。それらを加味して横位置の中央座標を計算しています。縦位置も同じです。
$('#ipop').css('top', wy).css('left', wx).fadeIn(100);
上で計算したウインドウの座標をCSSに設定して表示しています。

タイトルバーでマウスボタンを押下したとき

$('#ipop_title').mousedown(function(e) {
    mx = e.pageX;
    my = e.pageY;
pageX,pageYはマウスボタンが押下されたときのページ左上からの座標が入ります。
$().mousemove(mouseMove).mouseup(mouseUp);
マウスボタンが押下されたときにマウスが移動するときのイベント(mousemove)と、マウスボタンが離されたときのイベント(mouseup)をドキュメント全体に対して登録しています。$()は$(document)の略です。

マウスボタンを押下したまま移動したとき

つまりはドラッグですね。
wx += e.pageX - mx;
wy += e.pageY - my;
ウインドウの位置を、現在のマウス位置からひとつ前のマウス位置を引くことによって割り出しています。

マウスボタンが離されたとき

$().unbind('mousemove', mouseMove).unbind('mouseup', mouseUp);
マウスイベントの登録を解除しています。

注意事項

IEの場合、selectメニューがz-indexの値を無視してウインドウの前面に出てしまう、というバグがあります。その場合はウインドウを表示する直前に
$('select').hide();
でメニューを消し、ウインドウを消した直後に
$('select').show();
でメニューを復活させると良いでしょう。

この記事へのトラックバックURL

コメントをどうぞ