2017年2月3日金曜日

StackEditでアップした記事の画像をBloggerのサイズに自動調整する

今回はStackEditでアップした記事の画像をBloggerで表示する時、自動的にサイズ変更するスクリプトを書いてみました。いままで大きな画像をアップしてたり、いちいちサイズ指定なんてやってらんない、なんて人にはおすすめです。

ほんとはBloggerのLightBoxとも連携させたかったんだけど、力不足で実現できず… だれかできた人いませんか? 教えてください。m(_ _)m

つ colorbox つ fancybox …. (ぉぃ

機能

  • StackEditでアップした記事に含まれる画像を、Bloggerで表示するときに本文の幅をはみでないように自動的に調整する。
  • ただし、もともとリンクが設定されていたり、幅指定されているものはそのまま。
  • Bloggerで表示した時ブラウザの別タブ、別ウィンドウなどで元のサイズで画像を表示する。
  • モバイルの画面にはたぶん影響ありません。自分のiPhoneでのみ確認済み。

スクリプトの設置

  • jQueryのインクルード
    jQueryが使えるよう下記のような記述を追記。すでにjQueryを使用している場合、2系を使ってください。たぶん3系では動きません(未確認)。また3系と共存させる方法を知らないので、誰か知っていたら教えてください。
<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'/>
  • 下記スクリプトを<head>タグ内に追加。
    画面横幅は<script>タグのすぐ下のCUSTOM_IMAGE_MAX_WIDTHで指定してください。
<script language='javascript' type='text/javascript'>

  var CUSTOM_IMAGE_MAX_WIDTH = 640;

  // start processing after load a whole page
  $(window).load( function () {
//    console.log('start processing images');

  // list post
    $('.post-body').each(function(i, postBlock) {
      postBlock = $(postBlock);

  // list img
      postBlock.find('img').each(function(j, imgTag) {
        parentTagLetter = $(imgTag).parent().get(0).tagName;

  // processing img tag
    // add a tag on parent
        if (parentTagLetter != 'A') {

    // create the parent element as a tag
          imageUrl = $(imgTag).attr('src').replace(/\/s\d+\//, '/s1600/');
          $(imgTag).wrap('<a></a>');

    // add attributes on a tag
          $(imgTag).parent().attr('href', imageUrl);
          $(imgTag).parent().attr('target', '_blank');
          $(imgTag).parent().attr('imageanchor', '1');

    // if innerHTML does not have the string 'width', add attributes on img tag
          checkObj = $(imgTag).clone(true);
          $(checkObj).removeAttr('src alt title rel').remove;
          strAttrImgTag = checkObj.get(0).outerHTML;
          if (strAttrImgTag === void 0 ||  !(/width/i.test(strAttrImgTag))) {

    // get image size
            imgWidth = $(imgTag).width();
            imgHeight = $(imgTag).height();

    // if image size is bigger than max width, set small size
            if ( imgWidth > CUSTOM_IMAGE_MAX_WIDTH) {
              $(imgTag).width( CUSTOM_IMAGE_MAX_WIDTH)
            }
          }
        }
      });
    });
//    console.log('finish processing images');
  });
</script>

使い方

特にありません。なおStackEditで画像を扱うときに少し気をつければ、Bloggerでも画像をうまく扱えます。こんなスクリプトいらない、デス。

StackEditへの画像の貼り付け方

エディタ画面で、画像を文章中で貼り付けたい場所にカーソルを持っていきます。そして貼り付けたい画像をエクスプローラで選んでプレビュー画面にドラッグアンドドロップするだけです。エディタ画面にドロップしても反応しません。

StackEditに画像を貼り付けるときの画像幅指定

画像を貼り付けるときにダイアログボックスがでてきます。そこには画像の幅を指定する入力欄があります。StackEditは画像を貼り付けられるとGoogle+に画像をアップロードします。このアップロードする画像のサイズを指定します。幅が640pxより大きい画像の場合は、640pxを指定すると、記事表示画面で画像の収まりがよくなります。

値を入力しないと画像のもとの大きさのままファイルがアップロードされ、記事を表示したときも画面の幅より大きく表示されてしまいます。そんな時このスクリプトが自動的に画像の幅を640pxにして表示します。

補足

  • このスクリプトは記事の中の画像だけを扱います。
  • 記事の画像にリンクをつけている場合、このスクリプトは何もしません。
  • 記事の画像に幅指定(imgタグでwidth指定)している場合、このスクリプトはStackEditに貼り付けた画像を元の大きさで表示するためのリンクをつけます。

参考情報

本当はStackEditでアップした記事の画像が、Bloggerで作成した記事みたいに画像をLightBoxで表示する、っていうのをやりたかったんだけど、色々調べてて行き詰まっちゃいました。
LightBoxというのは、記事の画像をクリックしたらギャラリーみたいに見せてくれるすぐれものです。でも、StackEdit使おうかってひとは、画像なんてみれてたらいーやー、面倒なことはしねーよー、 LightBoxってなにそれおいしいの? ですよね? ってことで断念しました (すっぱい葡萄理論)。

調べたことは書いておくので、だれかいいやり方あったら教えて下さい(切望)。

StackEditとBloggerで作成されるHTML

  • StackEdit

画像1枚分です。

<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVZAn2yump9r6XThBgjBjteIso02P3fikJxJJdk1zZyDzV0otk1j1D9VQjWmas09mMrXzxTZBjAsm-rgSEFlk0PM4jjZSAW2wvDaEXjW4Gqetqg6UG3oNGNrjL1_E7V_50I5SreJ8JoxVa/s0/2017-01-23%252520%2525281%252529.png" alt="StackEditでの作業" title="StackEditでの作業"><br><br> <br>
  • Blogger

画像2枚分です。

<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0RkriWspJJ2wEY_S9UCJoCc7XHvHRMTFpz-WGMWGWbY9rnGOwvTtcdMnXUzca4ruLiQg8cK8GmQiSbNtQOEhnyMt2Vm97lQG7-IYalO8nZGfmjOavfI0rlUxT4GkHH7fTbycsBdLPo5EM/s1600/article_with_small_font.png" imageanchor="1"><img border="0" height="95" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0RkriWspJJ2wEY_S9UCJoCc7XHvHRMTFpz-WGMWGWbY9rnGOwvTtcdMnXUzca4ruLiQg8cK8GmQiSbNtQOEhnyMt2Vm97lQG7-IYalO8nZGfmjOavfI0rlUxT4GkHH7fTbycsBdLPo5EM/s320/article_with_small_font.png" width="320" /></a><br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1DHHMugIcWs2Ipxw3JV1EGWCjM00g0CWTzn4b0LwcPHEyxbLIvL2-6RH6M8QiR5tT1e-gimB-wr2Judub0NHoqQbUVWvl0kvkYLMnxLgw9P8tdt72JlJoZzXSsfk1U77Ufrt6bVVTpTtn/s1600/2017-01-28+%25283%2529.png" imageanchor="1"><img border="0" height="368" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1DHHMugIcWs2Ipxw3JV1EGWCjM00g0CWTzn4b0LwcPHEyxbLIvL2-6RH6M8QiR5tT1e-gimB-wr2Judub0NHoqQbUVWvl0kvkYLMnxLgw9P8tdt72JlJoZzXSsfk1U77Ufrt6bVVTpTtn/s640/2017-01-28+%25283%2529.png" width="640" /></a>

StackEditとBloggerを比較するとこんな感じ。

  • imgタグ
比較内容 StackEdit Blogger
src プロトコル https https
src ホスト名 lh3.googleusercontent.com 4.bp.blogspot.com
属性 - border height width

ホスト名は、ひとつめのドットまで(lh3など)は画像によって変わります。
imgタグのホスト名をStackEditとBloggerで入れ替えてもLightBoxで表示されました。グループ化もされたままでした。

  • aタグ

imgタグのリンク。Bloggerにはあるけど、StackEditにはない。

比較内容 StackEdit Blogger
a - パスの内snnnnが異なる。
nnnnはimgのwidthと同じ値
href プロトコル - http/httpsスイッチ可能
imageanchor - 複数の画像で同じ値 (1)

aタグのsnnnは表示する画像のサイズ指定です。Bloggerの「作成」の画面で指定した画像の大きさに合わせて数値が変わります。imgタグのwidthと同じです。heightも固定比率で変化しました。

サイズ width snnnn
200 s200
320 s320
400 s400
特大 640 s640
元の大きさ 指定なし s1600またはs0

StackEditの画像の扱い

StackEditに画像をドラッグアンドドロップすると、StackEditはGoogleフォトに画像をアップロードします。Googleフォトは、画像を表示する時に表示したいサイズを指定すると、そのサイズにして画像を送ってきてくれます。

StackEditで画像をアップロードするとき、画像の幅を指定することができます。でもここで画像の幅を指定しても、アップロードした画像のサイズは元のサイズのままで変わりません。その代わりStackEditではこの数値を使ってGoogleフォトの画像を表示するimgタグを作成します。上記のsnnnnのところです。Googleフォトはsnnnnで指定した横幅の画像をブラウザに送信します。

Bloggerの画像の扱い

Bloggerの記事作成画面での画像関係の機能は豊富です。

  • 投稿画面で画像をアップロードする時は何も聞いてきません。最大サイズチェックはしている模様。
  • 画像に対してLightBoxを呼び出すaタグを付与
  • 投稿画面で画像をアップロードした後はUIで以下の指定が可能
    • サイズ指定: 小、中、大、特大、元の大きさ
    • 配置: 左 - 中央 - 右
    • 説明: 画像の下に表示するテキスト
    • プロパティ: テキストタイトル(title)、代替テキスト(alt)

配置場所はdivタグでコントロール、説明はtableで実現しています。

LightBoxの動き

LightBoxは、記事に掲載している画像をフォトギャラリーのように見せてくれるツールです。画像をクリックすると写真がクローズアップされ、背景が少し暗くなります。写真1枚でも、複数を束ねてグループにし、アルバムみたいにもできます。

LightBoxを使うには次の手順です。

  • ページにLightBoxを使うためライブラリを組み込む。
  • Aタグで画像ファイルのリンクを作る。
  • イメージをグループ化するにはAタグに属性relを指定する。

以下のようなコードでLightBoxの機能を呼び出すことができるそうです。

<a href="image.png" rel="lightbox">画像</a>

ただしひとつ大事な条件があります。ページが読み込まれたらLightBoxが動いてaタグに対してクリックされたらLightBoxを呼び出す関数が動くように設定しています。具体的には、LightBoxのライブラリが動くときにaddEventListnerを使ってaタグのclickイベントを登録しています。

なので、そのライブラリの処理の部分が動くまでに、ページのソースにaタグを書いておくなどしてaタグがページの要素として存在していることが必要です。あるいはa要素を作成後、addEventListnerするなどすればなんとかできそうだなぁ、と思っていました。

BloggerでLightBox関係の処理を予想してみる

LightBoxの動作方式に沿うためにBloggerでは次のことがされているはずです。

  • 記事ごとのイメージをまとめるグループ識別子を付ける
  • aタグにclickイベントを登録する

グループ識別子の方はrel属性こそありませんが、クラスpost-bodyのidが使えそうです。しかしタグへのclickイベントはソースを見渡してもどこにもありません。一体どうやってLightBox起動のイベントを発火させているのでしょうか。

BloggerでのLightBox関係の動き

かなり複雑でした。参考サイトさんがなければ全くわかりませんでした。大体次のように動作しているようです。

  1. ウィジェットを実行する部分がブログの設定を調べてLightBox機能が有効であれば、そのウィジェットをロードする。(_BlogView)
  2. _WidgetManagerがLightBoxウィジェットをマネージャに_RegisterWidgetメソッドで登録する。
  3. 登録時に初期化処理をおこない、imgタグにclickイベントをつける。その他、LightBoxを呼び出すための準備を行う。

結局できないの? う~ん、残念!

できませんでした。力不足です…

LightBox起動のためには、clickイベントに対して起動のためのコールバック関数を設定しなければなりません。しかしBloggerではLightBox起動のためのコールバック関数が無名関数です。_WidgetManager._RegisterWidgetがこれを仕掛けています。他にもLightBoxで使いそうなオブジェクトを色々とimgのイベントリスナーのハンドルに仕掛けています。

ならばもう一度_WidgetManagerで_BlogViewだけ再実行できないか…と思ったのですが、方法がわかりませんでした。ここまで来て…悔しいなぁ。

だれかわかる方いらっしゃったら教えてください。お願いします。

参考サイト

ありがとうございます。大変勉強になりました。

0 件のコメント:
コメントを投稿

気づいたこと、不具合、ご意見など、コメント待ってます!