Posts Tagged ‘ポップアップ’

Greasemonkeyでサイト既存CSSの影響を受けないポップアップパネルを作る方法

Greasemonkeyは各サイトでユーザースクリプトを実行できて便利ですが、ある要素を挿入したときにそれがサイトに元々書いてあるCSSの影響を受けてしまうことがあります。
一つのサイトならまだしもhttp*で動くようなものだと対応仕切れないのでiframeを使いサイトに書いてあるCSSの影響を受けないパネルを作る。
iframeの中はそのサイトにあるCSSの影響を受けないので、iframe内にGreasemonkeyで表示したいものを置けば影響を受けないものが作成できる。
makeFrameというのが今回の主題。

makeFrame(gotFrame1);
makeFrame(gotFrame2);

function gotFrame1(iframe, win, doc) {
  iframe.height = "350";
  iframe.width = "500";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.left = "0";
  doc.body.innerHTML += "Frame1ですね。"
}
function gotFrame2(iframe, win, doc) {
  iframe.height = "350";
  iframe.width = "500";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.right = "0";
  iframe.style.backgroundColor = "#ddd";
  doc.body.innerHTML += "Frame2ですよ。"
}
// Creates a new iframe and attaches it to the DOM, waits for it to load, tests
// that we did not hit https://bugzilla.mozilla.org/show_bug.cgi?id=295813 nor
// https://bugzilla.mozilla.org/show_bug.cgi?id=388714 (and retries otherwise),
// to finally call the provided done callback, passing the iframe, its window
// and document. (The optional name parameter, if provided, will be used to name
// the iframe in window.frames, or be created as "pane-1" onwards, otherwise.)
/*
    var cacllback = function(iframe, win, doc){

    }
    makeFrame(cacllback);
    makeFrame(cacllback , "frameName");
    makeFrame(cacllback , "frameName" , true);// debug mode
*/
function makeFrame(callback/*(iframeTag, window, document)*/, name, debug) {
    function testInvasion() {
        iframe.removeEventListener("load", done, true);
        var message = ((new Date) - load.start) + "ms passed, ";
        try { // probe for security violation error, in case mozilla struck a bug
            var url = unsafeWindow.frames[framename].location.href;
            message += url == "about:blank" ? "but we got the right document." : "and we incorrectly loaded " + url;
            if (debug) console.log(message);
            done();
        }
        catch(e) {
            if (console && console.error && console.trace) {
                console.error(e);
                console.trace();
            }
            if (debug) console.log(message + "and our iframe was invaded. Trying again!");
            document.body.removeChild(iframe);
            makeFrame(callback, name);
        }
    }
    function done() {
        clearTimeout(load.timeout);
        if (debug) console.log("IFrame %x load event after %d ms", framename, (new Date) - load.start);
        var win = unsafeWindow.frames[framename];
        var doc = iframe.contentWindow.document;
        // 苦し紛れのエスケープ
        var esframeName = "'"+framename+"'";
        // 自分自身のiframeを閉じるボタン
        var xImg = doc.createElement("img");
        xImg.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAATElEQVQoka2RSQ4AIAgD+f+jp96M0aq49AgdUiB0qZCkONQ/EBAwDOrrU7A1uZqN2hodtNwRqNdz0VOg62+jzuDUcVzkf+/I6h28UQHjW25Gob5AIAAAAABJRU5ErkJggg=="
        xImg.setAttribute("onclick", "parent.document.getElementsByName("+esframeName+")[0].style.display='none';");
        xImg.setAttribute("style","background-color:red;border:3px;position:fixed;top:0px;right:0px");
        doc.body.appendChild(xImg);
        callback(iframe, win, doc);
    }
    var iframe = document.createElement("iframe");
    var framename = iframe.name = typeof name != "undefined" ? name : ("pane" + (makeFrame.id = (makeFrame.id || 0) - 1));
    iframe.setAttribute("style", "overflow:auto;z-index:18999; border:0; margin:0; padding:0;top:auto; right:auto; bottom:auto; left:auto;background-color:#fff");
    iframe.src = "about:blank";
    iframe.addEventListener("load", done, true);
    var frames = makeFrame.data || {};
    var load = frames[framename] || {
        start: new Date,
        sleepFor: 400
    };
    load.timeout = setTimeout(testInvasion, load.sleepFor);
    load.sleepFor *= 1.5;
    frames[framename] = load;
    makeFrame.data = frames;
    document.body.appendChild(iframe);
}

makeFrame関数は(callback ,[フレームのname , debugモード])という引数なので、gotFrame1という関数(callback)を引数にしてmakeFrameを読んでいる。 callbackには(iframe, iframeのwindow, iframeのdocument)が入ってるいるので、iframeのstyleをいじればパネルの色やサイズ、表示する場所などを指定できる。 上記のソースだと左下にframe1、右下にframe2が表示できる。

表示例

元ネタからの改良点

  • パネルを閉じるボタンの追加

それぞれのパネル右上に表示されているxボタンは、パネルを閉じるボタンとして機能している。 innerHTMLが+になってるのはiframe内にxボタンを追加しているため。

  • Flashより上部に表示

パネルなのでFlashがあってもその上に表示できるようにした方が動作的にはいいと思うのでCSSを少し修正した。
要素をFlashより上部する方法は以前書いたFlashよりも前面にポップアップを表示するFirefox 3.6でFlashの上に position: fixed; な要素を表示できなくなった件 – なんとなく目記を見るといい。
Firefox3.6では挙動が変わったので注意。
Flashより上に表示するには”position: fixed; overflow: auto;”とした要素であり、以下の条件を満たす必要がある。

  1. 透過でない(Opacityを使わない or 背景色を無指定にしない)
  2. CSS3?(-moz-)系のstyleを使わない。(-moz-box-shadowなどは陰の部分だけFlashより後ろに表示されてしまう
    角丸border-radiusなどは要素に適応されるので要素全体がFlashより後ろに表示される。)

このmakeFrameを使ったサンプルGreasemonkeyとして
ニコニコ動画再生ページからその動画のマイリストコメントをパネル上で参照できる

Nico MylistComments for Greasemonkey
http://userscripts.org/scripts/show/72319

を作ってみた。

元ネタ(元ネタのサンプルはtypoがあるので、そのままだと動かない)

HTML Injection Tips – greasemonkey – GitHub
http://wiki.github.com/Martii/greasemonkey/html-injection-tips
makeFrame

TwitpicのAltが文字化けしているのを修正するGreasemonkey

TwitPicは便利なTwitter向け写真投稿サイトですが、写真のaltに日本語があるとaltの内容が文字化けしてしまいます。
fix twitpic altはその文字化けしたaltを修正するGreasemonkeyです。

ss-2009-09-30-08-46-21

インストールすれば、画像にマウスオーバーしたとき文字化けが修正された文字列が表示されます。(Firefox標準だとポップアップはしなかったかも)

Flashよりも前面にポップアップを表示する

JavaScriptでポップアップを表示する時(Lightboxとかページ内でポップするやつ)にflashの上に表示しようとすると なぜかflashの背面に表示されてしまうことがあるので解決方法のメモ。 (Greasemonkeyスクリプト書いてるときに少し詰まった。)
一つ目の方法 Flushの前面にページの領域を表示する – Ulmhaftで紹介されているように cssでポップアップする領域(divとか)を

position:fixed;
overflow:auto;

とすればflashより前面に表示されるみたいです。
二つ目の方法 こちらはflashの表示タグに変更を加える方法 参考web-conte.com | blue | Lightbox JS v2.0 と Flash

<!-- object要素内に下記を追加 -->
<param name="wmode" value="transparent" />
<!-- embed要素に下記の属性を追加 -->
wmode="transparent"

のようにembedタグに要素を加えるとflashより上に表示できる。 javascriptなら addParam(“wmode”, “transparent”); しかし、この方法はflash内のテキストフィールドに日本語を打てなくなるとういう欠点があります。

wmode を transparent に設定した際の注意点 他にいい方法はあるのかな?
後は考えられるのはflashをdivなどのコンテナで囲んで、表示非表示を切り替える方法。
この方法は毎回flashの再生がスタート地点に戻るので使いづらいかも。

Greasemonkeyでページ内の画像をポップアップ表示させる(5種類)

Greased Lightbox – shifting pixel
http://shiftingpixel.com/lightbox
GreasedLightbox.user.js
http://shiftingpixel.com/downloads/greasedlightbox.user.js
画像をクリックすることで Lightboxのようにポップアップ表示します。

+ で拡大、- で縮小(Enterで元のサイズに戻る)
← →で画像移動
0(ゼロ)で最大化
x、Escキーや他のところをクリックするとで中止

右上のボタンからスライドショーもできるという優れものw
ソースのslideTime : 4,をいじることで時間も変えられます。(キャッシュを削除する?)
多分この手の画像ポップアップでは一番の高機能だと思います。

テストするにはグーグルが一番→ Google Image Search.

Image Link Tooltip v0.5

画像リンクの上にカーソルをのせると自動で読み込むタイプ。
LightBoxのような表示をする。
画像をクリックすることで元に戻る。

Image links inline viewer

画像リンクの上にカーソルをのせると自動で読み込むタイプ。
カーソルの下に左ぴったりに表示される。
カーソルを画像からどかすと勝手に消えるので、流して見るのには向いてるかも。

画像のURLを展開するgreasemonkeyComments

作者さんがページを閉じてしまったのでそのまま転載。

showimageurl.user.js画像のURLを展開するgreasemonkeyを書いてみたよ
画像を見るのにいちいちリンクをクリックするのはメンドイという
メンドクさがりやな人は使うといいよ
絵師さんのサイトを巡回するときに楽だよ
初期設定ではtumblr.com上でしか実行しないので
@includeに実行したいサイトを追加して使ってね

ページ内にリンク先の画像を展開する greasemonkeyスクリプト。
ページのデザインが崩れることがあるので場所を選んで使うべき。
showimageurl.user.js

画像リンクの上にカーソルをのせると自動で読み込むタイプ。
まだ調整中みたいな感じ。

参考サイト

サムネイルをクリックするとlightbox効果で画像を表示してくれるGreased Lightbox

プロフィール: azu(アズ)
Firefoxの事やソフトウェアの紹介や使い道、Greasemonkeyの作成
  • OS:Windows Vista, 7
  • ブラウザ:Firefox
  • Twitterのアカウントはこちら
  • azu_re
  • メールアドレス(Twitterの方が確実)
  • info@ドメイン名
リンク

WebMoney ぷちカンパ