miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

ブラウザで @media="print" を無効にする bookmarklet

ブラウザの見た目どおりに印刷したいのに、CSS で media="print" なり @media print が設定されていて意図しない形で印刷されてしまうページがたまにあると思います。

ちょっと見た目どおりに印刷したいケースがあったので、@media="print" を無効化する bookmarklet を書いてみました。簡単にしかテストしていませんけど、それらしく動いている気がします。

(追記)はてダで bookmarklet にうまくリンクが張る方法がわからないので、pre で書いておきます。

@media print 無効化

javascript:(function(){for(var s=document.styleSheets,i=0;i<s.length;i++){var e=s[i],m=e.media;if(m.mediaText=="screen"){m.mediaText="all"}else if(m.mediaText=="print"){e.disabled=true;continue}if(!e.cssRules){continue}for(var j=e.cssRules.length-1;j<=0;j--){var r=e.cssRules[j];if(r.media){if(r.media.mediaText=="screen"){r.media.mediaText="all"}else if(r.media.mediaText=="print"){e.deleteRule(j)}}}}})()

Firefox だとなぜか cssRules プロパティにアクセスしたタイミングで「Security error" code: "1000」とか言われてしまうので、後半の処理を削った簡易版も置いておきます。style タグに media 属性が指定されているだけなら、こちらで対応できるんじゃないかと。

@media print 無効化(簡易版)

javascript:(function(){for(var s=document.styleSheets,i=0;i<s.length;i++){var e=s[i],m=e.media;if(m.mediaText=="screen"){m.mediaText="all"}else if(m.mediaText=="print"){e.disabled=true;continue}}})()

簡単に注意点とかを書いておきます。

  • 「見た目通り」といってもページの幅なんかは変わってくるので、本当に見た目通りになるわけではありません。
  • IE では印刷実行時にキャッシュを参照するせいか、動作が不安定です。初回はうまくいったんですが、二回目以降うまく動作しませんでした。

斜め読みしかしてないけど、今回参考にしたサイト。

例によって、もっといいやり方があれば教えてくださいませ。

beautify かけて、簡単にコメントを付加したものも置いておきます。

(function () {
    // スタイルシートごとのループ
    for (var s = document.styleSheets, i = 0; i < s.length; i++) {
        var e = s[i],
            m = e.media;
        if (m.mediaText == "screen") {
            // screen の場合は印刷時も適用されるよう all に変更する
            m.mediaText = "all"
        } else if (m.mediaText == "print") {
            // print の場合は印刷時に適用されないよう無効化する
            e.disabled = true;
            continue;
        }

        // スタイル定義ごとに @media が指定されているケースの対応
        // ※簡易版では削除しています
        if (!e.cssRules) {
            continue;
        }
        for (var j = e.cssRules.length - 1; j >= 0; j--) {
            var r = e.cssRules[j];
            if (r.media) {
                if (r.media.mediaText == "screen") {
                    r.media.mediaText = "all"
                } else if (r.media.mediaText == "print") {
                    e.deleteRule(j);
                }
            }
        }
    }
})()