Blogger:表示速度向上のためCSSとJavaScriptの置き場を考える:その4

Blogger:表示速度向上のためCSSとJavaScriptの置き場を考える:その3の(ヘ)(ト)(チ)からjQueryとdocument.write()を除去します。

前の関連記事:Blogger:表示速度向上のためCSSとJavaScriptの置き場を考える:その3


(へ)Blogger:レイアウト編集(9)各投稿の更新日時の表示をする(成功編)


Blogger:レイアウト編集(9)各投稿の更新日時の表示をする(成功編)

まずウェブバージョンの部分について現在使っているコードを抽出します。

テンプレートのHTMLの編集でウィジェットへ移動→Blog1。

このBlog1ウィジェットの中のpostインクルードの中の公開更新日時の表示部分を抜き出します。
  <div class='post-header-line-1'>
<!--公開更新日時の表示 開始-->
  <div style='float:right;font-size: 0.9em;text-align:right;margin-left:20px'>
  <b:if cond='data:blog.pageType == &quot;item&quot;'><!--アイテムページのとき-->
    <div id='toko_nitiji'/>
    <script>
      $.getJSON(&quot;http://&quot;+location.hostname+&quot;/atom.xml?path=&quot;+location.pathname+&quot;&amp;alt=json-in-script&amp;callback=?&quot;,
        function(json){
          var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);
          var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);
          $(&quot;#toko_nitiji&quot;).html(kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;+koshinbi+&quot;更新&quot;+&quot;&lt;br&gt;&quot;);
          $(&quot;#label_hyoji&quot;).css(&#39;padding-top&#39;,&#39;15px&#39;);
      });
    </script>
  <b:else/><!--アイテムページ以外のとき-->
    <b:if cond='data:post.dateHeader'> 
      <script type='text/javascript'>var post_dateHeader = &quot;<data:post.dateHeader/>&quot;</script> 
    </b:if> 
    <script>
      var feed_date=post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;;
      var kokaibi=date_shoshiki(feed_date);
      document.write(kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;);
    </script>  
  </b:if>
    <data:top.authorLabel/> <data:post.author/>
</div>
<!--公開更新日時の表示 終了-->
    <div id='label_hyoji'>
<b:if cond='data:post.labels'>
  <data:postLabelsLabel/>
    <b:loop values='data:post.labels' var='label'>
      <a expr:href='data:label.url+ &quot;?max-results=10&quot;' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != &quot;true&quot;'>,</b:if>
    </b:loop>
</b:if> 
</div>
  </div>
<div style='clear: both;'/> 
</div>
まずこの5行目から14行目で使っているjQueryを除去します。
    <div id='toko_nitiji'/>//ここに書き込まれる。
    <script>
      $.getJSON("http://"+location.hostname+"/atom.xml?path="+location.pathname+"&alt=json-in-script&callback=?",//jQueryで個別の投稿のフィードを取得。
        function(json){
          var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);//フィードから公開日時を得て整形。
          var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);//フィードから更新日時を得て整形。
          $("#toko_nitiji").html(kokaibi+"公開"+"<br>"+koshinbi+"更新"+"<br>");// <div id='toko_nitiji'/>に代入。
          $("#label_hyoji").css('padding-top','15px');//ラベル表示の上に15px空間を空ける。
      });
    </script>
HTMLエンティティを戻すとこうなっています。

関数data_shoshiki()は他でも使っているのでテンプレートのHTMLの</head>の上にもっていっています。
  <script>
    function date_shoshiki(feed_date){//「2013-08-29T22:07:」を「2013年08月29日22時07分」に整形する関数。
        return feed_date.slice(0,17).replace("-","年").replace("-","月").replace("T","日").replace(":","時").replace(":","分");
    }
  </script>

$("#toko_nitiji").html(kokaibi+"公開"+"<br>"+koshinbi+"更新"+"<br>");// <div id='toko_nitiji'/>に代入。
これは脱jQuery .html() .text() .val() | q-Azを参考にelement.innerHTMLに書き換えました。
 document.getElementById("toko_nitiji").innerHTML = kokaibi+"公開"+"<br>"+koshinbi+"更新"+"<br>";// <div id='toko_nitiji'/>に代入。
$("#label_hyoji").css('padding-top','15px');//ラベル表示の上に15px空間を空ける。
これは脱jQuery .css() | q-Azを参考にelement.styleで書き換えました。
 document.getElementById("label_hyoji").style.paddingTop = "15px";//ラベル表示の上に15px空間を空ける。
$.getJSON()を書き換える方法も脱jQuery $.getJSON() | q-Azを参考にしようと思ったのですが長らくJavaScriptを触っていなかったせいか理解できませんでした、、、

なのでBlogger:ページ番号付ページナビ(8)Paginavi_Bloggerモジュールの導入PageNavi_Blogger/pagenavi.js at master · p--q/PageNavi_Blogger · GitHubで作った関数writeScript()を使うことにしました。
    function writeScript(url) {  // document.write()の代替。URLを読み込む。
        var newInclude = document.createElement('script');
        newInclude.type = 'text/javascript';
        newInclude.setAttribute("src", url);
        document.getElementsByTagName('head')[0].appendChild(newInclude);
    };
この関数writeScript()を使うとフィードを取得するURLを実行するタグをheadタグの中に入れて実行することになります。

appendChild vs insertBefore | High Performance Web Sitesを読んでheadタグはすべてのページにあるわけではないので他の方法にしようと思った記憶がありますがどうしようと思ったのか忘れてしまいました。

モバイルバージョンでも使う関数toko()もheadタグに書くことにしました。
  <script>
    function date_shoshiki(feed_date){//「2013-08-29T22:07:」を「2013年08月29日22時07分」に整形する関数。
        return feed_date.slice(0,17).replace("-","年").replace("-","月").replace("T","日").replace(":","時").replace(":","分");
    }
    function writeScript(url) {  // document.write()の代替。URLを読み込む。
        var newInclude = document.createElement('script');
        newInclude.type = 'text/javascript';
        newInclude.setAttribute("src", url);
        document.getElementsByTagName('head')[0].appendChild(newInclude);
    }
    function toko(json){
        var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);//フィードから公開日時を得て整形。
        var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);//フィードから更新日時を得て整形。
        document.getElementById("toko_nitiji").innerHTML = kokaibi+"公開"+"<br>"+koshinbi+"更新"+"<br>";// <div id='toko_nitiji'/>に代入。
    }
  </script>
これをテンプレートのHTMLの</head>の上にもっていってjQueryの部分を以下のように書き換えました。
    <div id='toko_nitiji'/>
    <script>
        var url = "https://"+location.hostname+"/atom.xml?path="+location.pathname+"&alt=json-in-script&callback=toko";
        writeScript(url);
    </script>
ラベル表示の上に15px入れるのはdivに直接プロパティを設定することにしました。

ということでテンプレートのHTMLは書き換えたのはまず</head>の上に以下を挿入しました。
  <script>//更新日時の表示で使用
    function date_shoshiki(feed_date){//&#12300;2013-08-29T22:07:&#12301;を&#12300;2013年08月29日22時07分&#12301;に整形する関数&#12290;
        return feed_date.slice(0,17).replace(&quot;-&quot;,&quot;年&quot;).replace(&quot;-&quot;,&quot;月&quot;).replace(&quot;T&quot;,&quot;日&quot;).replace(&quot;:&quot;,&quot;時&quot;).replace(&quot;:&quot;,&quot;分&quot;);
    }
    function writeScript(url) {  // document.write()の代替&#12290;URLを読み込む&#12290;
        var newInclude = document.createElement(&#39;script&#39;);
        newInclude.type = &#39;text/javascript&#39;;
        newInclude.setAttribute(&quot;src&quot;, url);
        document.getElementsByTagName(&#39;head&#39;)[0].appendChild(newInclude);
    }
    function toko(json){
        var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);//フィードから公開日時を得て整形&#12290;
        var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);//フィードから更新日時を得て整形&#12290;
        document.getElementById(&quot;toko_nitiji&quot;).innerHTML = kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;+koshinbi+&quot;更新&quot;+&quot;&lt;br&gt;&quot;;
    }
  </script>
Blog1ウィジェットのpostインクルードの部分は以下のように書き換えました。
    <div id='toko_nitiji'/>
    <script>
        var url = "https://"+location.hostname+"/atom.xml?path="+location.pathname+"&amp;alt=json-in-script&amp;callback=toko";
        writeScript(url);
    </script>
  <b:else/><!--アイテムページ以外のとき-->
    <b:if cond='data:post.dateHeader'> 
      <script type='text/javascript'>var post_dateHeader = &quot;<data:post.dateHeader/>&quot;</script> 
    </b:if> 
    <script>
      var feed_date=post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;;
      var kokaibi=date_shoshiki(feed_date);
      document.write(kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;);
    </script>  
  </b:if>
    <data:top.authorLabel/> <data:post.author/>
</div>
<!--公開更新日時の表示 終了-->
    <div style="padding-top: 15px"><!--ラベル表示の上に15px空間を空ける。-->
これでjQueryを除去できました。

(ト)Blogger:モバイルサイト(6)更新日時の表示などヘッダーの改造


Blogger:モバイルサイト(6)更新日時の表示などヘッダーの改造


mobile-postインクルードもpostインクルードと同様に書き換えます。
<!--公開更新日時の表示 開始-->
   <div id='toko_nitiji' style='font-size: 0.9em;text-align: right;padding-bottom: 5px'/>
  <script>
    $.getJSON(&quot;http://&quot;+location.hostname+&quot;/atom.xml?path=&quot;+location.pathname+&quot;&amp;alt=json-in-script&amp;callback=?&quot;,
      function(json){
        var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);
        var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);
        $(&quot;#toko_nitiji&quot;).html(kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;+koshinbi+&quot;更新&quot;+&quot;&lt;br&gt;&quot;);
      });
  </script>
<!--公開更新日時の表示 終了-->
これを以下のように書き換えました。

<!--公開更新日時の表示 開始-->
   <div id='toko_nitiji' style='font-size: 0.9em;text-align: right;padding-bottom: 5px'/>
  <script>
        var url = "https://"+location.hostname+"/atom.xml?path="+location.pathname+"&amp;alt=json-in-script&amp;callback=toko";
        writeScript(url);
  </script>
<!--公開更新日時の表示 終了-->
これでjQueryが除去できました。
(2016.12.1追記。静的ページのフィードが取得できずエラーになるのでアイテムページに限定するif文を追加しました。)

(リ)Blogger:投稿タイトルの下に「年月日 曜日 時刻」を表示させる


Blogger:投稿タイトルの下に「年月日 曜日 時刻」を表示させる
    <b:if cond='data:post.dateHeader'> 
      <script type='text/javascript'>var post_dateHeader = "<data:post.dateHeader/>"</script> 
    </b:if> 
    <script>
      var feed_date=post_dateHeader+"T"+"<data:post.timestamp/>"+":";
      var kokaibi=date_shoshiki(feed_date);
      document.write(kokaibi+"公開"+"<br>");
    </script>  
これを修正します。


レイアウト画面で「ブログの投稿」ガジェットの日付と時刻表示はBlogger:投稿タイトルの下に「年月日 曜日 時刻」を表示させるのときと違ってこのようにしておかないと関数date_shoshiki()でうまく処理できません。
<div id='kokai_nitiji'/>
<script>
      var post_dateHeader = &quot;<data:post.dateHeader/>&quot;||post_dateHeader
      var kokaibi=date_shoshiki(post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;);
      document.getElementById(&quot;kokai_nitiji&quot;).textContent = kokaibi+&quot;公開&quot;;
</script> 
Node.textContentを使ってこれでうまくいくと思ったらそうはいきませんでした。

インデックスページでは複数の投稿が表示されるために同じidの要素が表示されてしまうために、一番上の投稿だけに一番下の投稿の公開日時が表示されてしまいました。

そこで書き換えた要素のidはelement.idを使って書き換えてしまうことにしました。
<div id='kokai_nitiji'/>
<script>
      var post_dateHeader = &quot;<data:post.dateHeader/>&quot;||post_dateHeader
      var kokaibi=date_shoshiki(post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;);
      var elem = document.getElementById(&quot;kokai_nitiji&quot;);
      elem.textContent = kokaibi+&quot;公開&quot;;
      elem.id = "kokai_nitiji_sumi";
</script> 
これでうまくいきました。

この投稿で変更したところのまとめ


結局最初に掲げたテンプレートのHTMLの編集でウィジェットへ移動→Blog1で、このBlog1ウィジェットの中のpostインクルードの中の公開更新日時の表示部分を抜き出した部分は以下のようになりました。
  <div class='post-header-line-1'>
<!--公開更新日時の表示 開始-->
  <div style='float:right;font-size: 0.9em;text-align:right;margin-left:20px'>
  <b:if cond='data:blog.pageType == &quot;item&quot;'><!--アイテムページのとき-->
    <div id='toko_nitiji'/>
    <script>
        var url = &quot;https://&quot;+location.hostname+&quot;/atom.xml?path=&quot;+location.pathname+&quot;&amp;alt=json-in-script&amp;callback=toko&quot;;
        writeScript(url);
    </script>
  <b:else/><!--アイテムページ以外のとき-->
<div id='kokai_nitiji'/>
<script>
      var post_dateHeader = &quot;<data:post.dateHeader/>&quot;||post_dateHeader;
      if(post_dateHeader){
          var kokaibi=date_shoshiki(post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;);
          var elem = document.getElementById(&quot;kokai_nitiji&quot;);
          elem.textContent = kokaibi+&quot;公開&quot;;
          elem.id = "kokai_nitiji_sumi";
      }
</script> 
  </b:if>
    <data:top.authorLabel/> <data:post.author/>
</div>
<!--公開更新日時の表示 終了-->
    <div style='padding-top: 15px'><!--ラベル表示の上に15px空間を空ける&#12290;-->
<b:if cond='data:post.labels'>
  <data:postLabelsLabel/>
    <b:loop values='data:post.labels' var='label'>
      <a expr:href='data:label.url+ &quot;?max-results=10&quot;' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != &quot;true&quot;'>,</b:if>
    </b:loop>
</b:if> 
</div>
  </div>
<div style='clear: both;'/> 
</div>
変更したのはハイライトした部分です。
(2016.12.1追記。 静的ページでは<data:post.dateHeader/>がundefinedになってしまっていたので、日付情報があるときのみ公開日が表示されるように変更しました。上記コードは変更済です。)

テンプレートのHTMLの</head>の上に以下を挿入しました。
  <script>//更新日時の表示で使用
    function date_shoshiki(feed_date){//&#12300;2013-08-29T22:07:&#12301;を&#12300;2013年08月29日22時07分&#12301;に整形する関数&#12290;
        return feed_date.slice(0,17).replace(&quot;-&quot;,&quot;年&quot;).replace(&quot;-&quot;,&quot;月&quot;).replace(&quot;T&quot;,&quot;日&quot;).replace(&quot;:&quot;,&quot;時&quot;).replace(&quot;:&quot;,&quot;分&quot;);
    }
    function writeScript(url) {  // document.write()の代替&#12290;URLを読み込む&#12290;
        var newInclude = document.createElement(&#39;script&#39;);
        newInclude.type = &#39;text/javascript&#39;;
        newInclude.setAttribute(&quot;src&quot;, url);
        document.getElementsByTagName(&#39;head&#39;)[0].appendChild(newInclude);
    }
    function toko(json){
        var kokaibi =date_shoshiki(json.feed.entry[0].published.$t);//フィードから公開日時を得て整形&#12290;
        var koshinbi=date_shoshiki(json.feed.entry[0].updated.$t);//フィードから更新日時を得て整形&#12290;
        document.getElementById(&quot;toko_nitiji&quot;).innerHTML = kokaibi+&quot;公開&quot;+&quot;&lt;br&gt;&quot;+koshinbi+&quot;更新&quot;+&quot;&lt;br&gt;&quot;;
    }
  </script>

モバイルバージョンについては上記(ト)で変更した部分と、(リ)に対応した変更部分は、mobile-index-postインクルードの部分を変更しました。
<div class='post-header' style='font-size: 0.9em;text-align: right;padding-bottom: 5px;padding-right: 30px'>
<div id='kokai_nitiji'/>
<script>
      var post_dateHeader = &quot;<data:post.dateHeader/>&quot;||post_dateHeader
      var kokaibi=date_shoshiki(post_dateHeader+&quot;T&quot;+&quot;<data:post.timestamp/>&quot;+&quot;:&quot;);
      var elem = document.getElementById(&quot;kokai_nitiji&quot;);
      elem.textContent = kokaibi+&quot;公開&quot;;
      elem.id = "kokai_nitiji_sumi";
</script> 
</div>
これでdocument.write()はすべて除去できたはずです。

参考にしたサイト


脱jQuery .html() .text() .val() | q-Az
htmlはelement.innerHTML、htmlタグのないテキストはNode.textContentで書き換えました。

脱jQuery .css() | q-Az
element.styleで書き換えました。

脱jQuery $.getJSON() | q-Az
XMLHttpRequestで書き換えていますがよくわからなかったのでappendChildを使う方法で書き換えました。

appendChild vs insertBefore | High Performance Web Sites
headタグは常に存在するわけでないことも考慮する必要があるとのことです。

次の関連記事:Blogger:表示速度向上のためCSSとJavaScriptの置き場を考える:その5

PR

0 件のコメント:

コメントを投稿