リンク先の画像をポップアップ表示するブックマークレット


前回の「URLのリンク化」に引き続き、今回はリンク先の画像をポップアップ表示するブックマークレットを作ったので紹介します。これを使うといちいちリンク先へ移動することなく画像の内容を確認できます。

jQuery を使って書き直すとともに機能を追加した最新版はこちら

機能

画像へのリンクにマウスカーソルを合わせると、リンク先の画像がポップアップで表示されます。
リンクからカーソルを外すとポップアップが閉じます。

以下のブラウザで動くことを確認しています。
: Internet Explorer (8.0)
: Firefox (4.0)
: Opera (11.10)
: Chrome (11.0)
: Safari (5.0)

使い方

以下のリンクをクリックすると画像ポップアップ機能が有効になります。
お気に入りになどに登録して使ってください。
画像ポップアップ表示

また、HTMLに次のscriptタグを記述しておくと、そのページ内の画像リンクがポップアップ表示されるようになります。

画像リンクの例
『光芒』
『木漏れ日(高尾山)』

ソースコード

http://b.tipszone.jp/imagePopup.js

Update
2010-12-18: 画像の上下が画面外にはみ出さないよう、表示位置を修正する機能を追加
2011-05-08: 画像読み込み完了後にサイズをチェックするよう修正。エラー処理を追加。
2011-05-14: 画像リンクに対応

(function() { var myLib = { setEventHandler: function(element, eventName, handler) { if (element.addEventListener) { element.addEventListener(eventName, handler, false); } else { element.attachEvent("on" + eventName, function(event) { handler(event); }); } }, addCSS: function(cssStr) { var css = document.createElement('style'); css.setAttribute("type", "text/css"); if (css.styleSheet) { css.styleSheet.cssText = cssStr; } else { css.appendChild(document.createTextNode(cssStr)); } document.body.appendChild(css); }, getWindowHeight: function() { return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; } };

var removeFlag = new Array();
var popup_counter = 0;

function imagePopup(event) {
    var elem = event.target || event.srcElement;
    var popupId = elem.popupId;
    var div = document.createElement('div');
    div.id = 'imagePopup' + elem.popupId;
    div.style.position = 'absolute';

    // Image tag
    var img = document.createElement('img');
    img.src = (elem.href || elem.parentNode.href);
    img.style.border = '1px outset #ccb';

    set_default_size_and_pos(div, img, event.clientX, event.clientY);

    myLib.setEventHandler(
        img,
        'load',
        function() {
            if (img.complete || 'complete' == img.readyState) {
                set_pos(div, img, event.clientX, event.clientY);
            }
        }
    );
    myLib.setEventHandler(
        img,
        'error',
        function() {
            if (div && removeFlag[popupId]) {
                elem.style.textDecoration = 'line-through';
                div.className = "image_link_error";
                div.innerHTML = 'エラー';
            }
        }
    );

    div.appendChild(img);
    document.body.appendChild(div);

    // Set event handler
    myLib.setEventHandler(div, 'mouseover', function() { removeFlag[popupId] = false; });
    myLib.setEventHandler(div, 'mouseout', function() { div.parentNode.removeChild(div); });

    removeFlag[popupId] = true;
}

function set_default_size_and_pos(div, img, cx, cy) {
    var window_height = myLib.getWindowHeight();
    var max_height = parseInt(window_height * 7 / 10);
    var max_width  = parseInt((window.innerWidth  || document.documentElement.clientWidth || document.body.clientWidth) * 7 / 10);
    img.style.maxHeight = (max_height) + 'px';
    img.style.maxWidth  = (max_width ) + 'px';

    if (navigator.userAgent.indexOf("MSIE") != -1) {
        // For Internet Explorer
        var h = 1;
        var w = 1;

        if (img.height > max_height) { h = img.height / max_height; }
        if (img.width  > max_width ) { w = img.width  / max_width; }

        if (1 < h || 1 < w) {
            var t = Math.max(h, w);
            img.style.height = parseInt(img.height / t) + 'px';
            img.style.width = parseInt(img.width / t) + 'px';
        }
    }

    set_pos(div, img, cx, cy);
}

function set_pos(div, img, cx, cy) {
    var window_height = myLib.getWindowHeight();
    var max_height = parseInt(window_height * 7 / 10);

    // Position
    cx += (document.body.scrollLeft || document.documentElement.scrollLeft);
    cy -= 100;
    if (cy < 5) {
        cy = 5;
    } else if (window_height - (cy + Math.min(img.height, max_height)) < 5) {
        cy = window_height - Math.min(img.height, max_height) - 5;
    }
    cy += (document.body.scrollTop  || document.documentElement.scrollTop);
    div.style.left = (cx + 15) + 'px';
    div.style.top = cy + 'px';
}

myLib.addCSS("\
    .image_link_error {\
        color: red;\
        border: 1px solid black;\
        background-color: white;\
        padding: 3px;\
    }\
");

imagePopup_sethandler = function(node) {
    var a = node.getElementsByTagName('a');
    for (var i = 0; i < a.length; i++) {
        if (!a[i].href.match(/\.(?:jpe?g|gif|png|bmp|webp)(?:\?|$)/i)) { continue; }

        // used for discrimination of the deletion object
        a[i].popupId = popup_counter;

        // Image popup
        myLib.setEventHandler(a[i], 'mouseover', imagePopup);

        // Image remove
        myLib.setEventHandler(
            a[i],
            'mouseout',
            function(event) {
                var elem = event.target || event.srcElement;
                var popupId = elem.popupId;
                var div = document.getElementById('imagePopup' + popupId);

                setTimeout(
                    function() {
                        if (div && removeFlag[popupId]) {
                            div.parentNode.removeChild(div);
                        }
                    }
                    ,50
                );
            }
        );

        popup_counter += 1;
    }
}

imagePopup_sethandler(document);

})();

処理概要
  1. <a>タグをgetElementsByTagName('a')で全部取得し、取得したタグごとに以下を繰り返す。
  2. mouseoverに画像をポップアップするイベントハンドラをセット
  3. mouseoutにポップアップを削除するイベントハンドラをセット
イベントハンドラの処理概要(<a>タグのmouseover)
  1. ポップアップ用に新しく<div>タグを作成し、その中に<img>タグを追加する。srcは対象画像
  2. <div>タグのpositionをabsoluteに設定する。(絶対位置指定)
  3. 現在のカーソルの位置を取得し、表示位置をカーソルのちょっと右に設定する。
  4. <div>タグのmouseoutに<div>タグ自身を削除するイベントハンドラをセットする。
  5. mouseoverには、上で<a>タグにセットしたmouseoutハンドラで削除されないようにするためのイベントハンドラをセットする。
    これにより、<a>タグからポップアップされた画像の上へカーソルを動かしたときには、ポップアップが閉じないようになります。

このコードは改変や配布含め自由に使っていただいてかまいません。
不具合などありましたら、コメント欄からご連絡ください。

カテゴリー: 記事 タグ: , , パーマリンク

コメントを残す