もっと便利に!jQueryでラクラクサイト制作(実践サンプル付き)

第16回jQueryで楽々実装できるツールチッププラグインを作ってみよう

画像

jQueryプラグインの魅力は、JavaScriptの知識がなくても簡単に色々な機能を実装できることですね。今回は「誰でも簡単に実装できるツールチッププラグイン」を作成してみましょう。

ツールチッププラグインの要件は以下の通りです。

  • titleまたはalt属性がある要素を対象
  • titleとalt属性両方を持っている場合はtitleを優先
  • 対象要素にマウスオーバーでツールチップをフェードイン
  • 対象要素からマウスアウトでツールチップをフェードアウト
  • 対象要素上ではツールチップはカーソルに追従

まずは完成サンプルとソースコードを見てみましょう。

完成ソースコード
    // ここからツールチッププラグイン
    $.fn.easyToolTip = function(options){
    
        // toolTipを生成してbodyに追加しておく
        var toolTip = $('<div id="toolTip"></div>').hide();
        $('body').append(toolTip);
        
        $(this).filter(function(){
            // titleかaltを持っているものだけに絞る
            return this.title || this.alt;
        }).each(function(){
        
            var self = $(this);
            // titleがあればtitleを、なければaltをターゲットにする
            var target = this.title ? 'title' : 'alt';
            // ターゲットにした属性の値を保存する
            var tipText = self.attr(target);
            
            self.hover(function(e){
                // ブラウザのツールチップが表示されるのを防ぐために一時的にtitle(alt)を削除
                self.attr(target,'');
                // toolTipにテキストを入れて表示
                toolTip
                    .stop(true,true)
                    .fadeIn('fast')
                    .text(tipText)
                    .css({
                        position: 'absolute',
                        top: e.pageY - 20,
                        left: e.pageX + 20
                    })
            },function(){
                // title(alt)を元に戻す
                self.attr(target,tipText);
                // toolTipを非表示にする
                toolTip.fadeOut('fast');
            }).mousemove(function(e){
                // カーソルに追従させる
                toolTip.css({
                    top: e.pageY - 20,
                    left: e.pageX + 20
                });
            });
            
        });
    }
})(jQuery);

jQuery(function($){
    // ツールチップの実行
    $('img,a,span').easyToolTip();
});

今回使うメソッドの紹介

まずは今回使うメソッドを復習の分も兼ねて紹介しておきます。

filter

filterで指定した要素に絞ります。今回使っている方法は、filterの中のfunctionで絞り込みの条件を返しています。return this.title;とした場合、div要素の中でtitle属性を持っているものに絞ります。

$('div').filter(function(){
    return this.title; // ここに条件文
});

stop

jQueryではfadeInやslideDownなど、要素を簡単にアニメーションさせるメソッドがありますが、これらは実行された際に一度アニメーションキューに保存され、順番に実行されていきます。stopメソッドは、現在実行されているアニメーションを中断するためのメソッドです。

ただしマウスの動きによって連続してアニメーションを実行するなど、使い方によっては、中途半端にアニメーションを止めてしまい、次回の実行に支障が出たりします。

stop(true,true)というように実行すれば便利に使うことができますので、使う場合は、(true,true)も併せて覚えておくとよいでしょう。

stopを使わない場合
$('a').hover(function(){
    $(this).next().fadeIn('fast');
},function(){
    $(this).next().fadeOut('fast');
});
stopを使った場合
$('a').hover(function(){
    $(this).next().stop(true,true).fadeIn('fast');
},function(){
    $(this).next().fadeOut('fast');
});

2つのサンプルの動作を見比べると、アニメーションのキューが残っているか残っていないかがはっきり分かると思います。

プラグインの枠組み

まずはプラグインの枠組みを作っておきます。これから書いていくコードはこれの中に書きます。

$.fn.easyToolTip = function(){
}

プラグインは以下のように実行できます。

$('a,span,img').easyToolTip();

ツールチッププラグインの作成

ツールチップをDOMに追加する

var toolTip = $('<div id="toolTip"></div>');
$('body').append(toolTip);

実行時に受け取る要素からtitleまたはalt属性を持っているものに絞る

ここで前述のfilterを使います。以下は、titleまたはalt属性を持っているもののみを返します。

$(this).filter(function(){
    return this.title || this.alt;
})

対象とする要素に実行する機能を割り当てる

filterで対象を絞り、eachで対象全てに機能を割り当てます。まずは、何度も使うのでselfに$(this)のエイリアスを当てておきましょう。

$(this).filter(function(){
    return this.title || this.alt;
}).each(function(){
    var self = $(this);
    var target = this.title ? 'title' : 'alt'; // ①
    var tipText = self.attr(target); // ②
});

targetはtitleまたはaltになりますが、両方持っている場合も考えられるので、その場合はtitle属性を優先するように3項演算子を使います。上記の①は以下のようにも書くことができます。

if(this.title){
    var target = 'title';
}else{
    var target = 'alt';
}

取得したtargetの値を②で保存しておきます。

ツールチップの表示、非表示

hoverメソッドを使ってmouseover、mouseout時の動作を記述します。

self.hover(function(e){
    toolTip
        .stop(true,true)
        .fadeIn('fast')
        .text(tipText)
        .css({
            position: 'absolute',
            top: e.pageY - 20,
            left: e.pageX + 20
        })
},function(){
    toolTip.fadeOut('fast');
});

ここでのポイントは、カーソルが要素に乗ったときにツールチップを表示させるのですが、マウスカーソルの右上あたりにツールチップを表示することです。

カーソル位置の取得

カーソルの右上あたり、をcssメソッドを使って指定するのですが、これには、mouseoverにbindする無名関数の引数のe(識別できればなんでもよい)を利用します。引数eは関数内でpageYやpageXといったプロパティを持ち、この2つの値からカーソルの位置を得ることができます。今回のサンプルではカーソルから右上に20pxずつずらして表示しています。

画像
.css({
    position: 'absolute',
    top: e.pageY - 20, // カーソルを基準として上へ20px
    left: e.pageX + 20 // カーソルを基準として右へ20px
})

カーソルに追従するツールチップ

このことを利用して、要素上でカーソルが動いたときはカーソルに追従するようにcssの値を書き換えます。次のサンプルを見るとカーソルが動くたびにコンソールにカーソル位置が表示されるのが分かると思います。

$('html').mousemove(function(e){
    console.log('Y: '+e.pageY+'\nX: '+e.pageX);
});
画像

ツールチッププラグインにもmousemoveの処理を追加します。

self.hover(function(e){
    toolTip
        .stop(true,true)
        .fadeIn('fast')
        .text(tipText)
        .css({
            position: 'absolute',
            top: e.pageY - 20,
            left: e.pageX + 20
        })
},function(){
    toolTip.fadeOut('fast');
}).mousemove(function(e){
    // カーソルに追従させる
    toolTip.css({
        top: e.pageY - 20,
        left: e.pageX + 20
    });
});

ブラウザデフォルトのツールチップを無効にする

画像

ここまででほぼ完成ですが、titleやalt属性を持っている値にカーソルが乗ったとき、ブラウザデフォルトの機能でツールチップが表示される場合があります。今回実装するツールチップと機能が若干かぶるので、表示しないようにします。具体的には、mouseover時にtitleまたはalt属性を削除し、mouseout時に追加する2文を追加するだけです。

self.hover(function(e){
    self.attr(target,''); // titleまたはalt属性を削除
    toolTip
        .stop(true,true)
        .fadeIn('fast')
        .text(tipText)
        .css({
            position: 'absolute',
            top: e.pageY - 20,
            left: e.pageX + 20
        })
},function(){
    self.attr(target,tipText); // 削除したtitleまたはalt属性を追加
    toolTip.fadeOut('fast');
})

以上で完成です。実行してみましょう!

jQuery(function($){
    $('a,span,img').easyToolTip();
});

おすすめ記事

記事・ニュース一覧