コメントが「埋め込み」の場合、コメントフォームを読み込こむための転送量は500kBほどでした。
コメントをするしないにかかわらずこの転送量が発生します。
そこで、コメントをしない場合の転送量を節約するため、クリックでコメントフォームを読み込こむようにしてみました。
widget version1のカスタマイズです。version2は変更する場所(includable
タグ)が違いますが読み替えれば適用可能だと思います。
以下のテーマで動作の検証をしました。
- 公式テーマSimple
- QooQ ver.2.0.0
- 公式テーマContempo(widget version2)
現状の理解と知識で書いたプログラムです。できる限り調べ、検証しましたが、勘違いや間違いなどあると思います。
また、テーマによってはコメント周りがすでにカスタマイズされている場合があります。もし適用する際はご自分のテストブログなどで十分に検証してから組み込んでください。
追記(2023年4月6日):既存のコードをJavaScriptで操作するよりも、Blogger Code PEさんのこちらのコードを使った方が柔軟にカスタマイズできそうです。
作業概要
変更するところは2か所
<b:includable id='comment-form' var='post'>
(以下、id='comment-form'
)<b:includable id='threaded-comment-form' var='post'>
(以下、id='threaded-comment-form'
)
にある<data:post.cmtfpIframe/>
とその下のscript
タグをコメントアウトして以下を追加します。
- ボタン要素
- 親要素を追加して文字実体参照でコメントアウトした
<data:post.cmtfpIframe/>
- JavaScript
<!--<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>-->
<button class="comment-form-button" id="commentFormButton" type="button">
コメントを書く
</button>
<div id="cmtfpIframeWrapper"><!--<data:post.cmtfpIframe />--></div>
<script>
...
</script>
※id='threaded-comment-form'
は追加でiframe
タグのsrc
を変更します。
id='comment-form'
はコメントがないときにコメントフォームを出力するincludable
タグ、
id='threaded-comment-form'
はコメントがあるときにコメントフォームを出力するincludable
タグです。
HTMLを編集します。必ずバックアップを取ってから作業してください。
id='comment-form'を変更
id='comment-form'
を検索。
<b:includable id='comment-form' var='post'>
<div class='comment-form'>
<a name='comment-form'/>
<b:if cond='data:mobile'>
<h4 id='comment-post-message'>
<a expr:id='data:widget.instanceId + "_comment-editor-toggle-link"' href='javascript:void(0)'><data:postCommentMsg/></a></h4>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' style='display: none' width='100%'/>
<b:else/>
<h4 id='comment-post-message'><data:postCommentMsg/></h4>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
</b:if>
<!-- ここから変更-->
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
<!-- ここまで変更-->
</div>
</b:includable>
<data:post.cmtfpIframe/>
とその下のscript
タグをコメントアウト。
ボタン要素と親要素を追加して文字実体参照でコメントアウトした<data:post.cmtfpIframe/>
、JavaScriptを追加する。
変更後
<!--<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>-->
<!-- ボタンクリックでコメントフォームを読み込む -->
<button class="comment-form-button" id="commentFormButton" type="button">
コメントを書く
</button>
<div id="cmtfpIframeWrapper"><!--<data:post.cmtfpIframe />--></div>
<script>
"use strict";
/**
* createScriptのonload属性で実行する関数
*/
function BLOG_CMT_createIframe() {
BLOG_CMT_createIframe("<data:post.appRpcRelayPath/>");
}
//<![CDATA[
/**
* ボタンをクリックしたらコメントフォームを読み込む関数
*/
function loadCommentform() {
/**
* ボタンをクリックしたらdata:post.cmtfpIframeの内容と
* onload属性のBLOG_CMT_createIframeが入ったスクリプトタグをhead内に生成する
*/
function createScript() {
// ボタン要素を非表示
commentFormButton.style.display = "none";
// iframe要素を表示
iframeElement.style.display = "block";
/** data:post.cmtfpIframeの親要素を取得 */
const cmtfpIframeWrapper = document.getElementById("cmtfpIframeWrapper");
/** HTMLに変換 */
const cmtfpIframeHTML = cmtfpIframeWrapper.innerHTML;
/** 正規表現でスクリプトの数字部分を取得 */
const regexp = /jsbin\/([0-9]*)/;
/** マッチした文字列を取得 @return {Array} */
const matchedNumber = cmtfpIframeHTML.match(regexp);
/** スクリプトタグ生成 */
const cmtfpIframeJs = document.createElement("script");
// スクリプトの数字部分にマッチした数字を入れる
cmtfpIframeJs.src =
"https://www.blogger.com/static/v1/jsbin/" +
matchedNumber[1] +
"-comment_from_post_iframe.js";
// onload属性でBLOG_CMT_createIframe関数を実行する
cmtfpIframeJs.onload = BLOG_CMT_createIframe;
// headタグに挿入する
document.head.appendChild(cmtfpIframeJs);
}
/** ボタン要素を取得 */
const commentFormButton = document.getElementById("commentFormButton");
// ボタン要素にクリックイベントを設定
commentFormButton.addEventListener("click", createScript, { once: true });
/** iframe要素を取得 */
const iframeElement = document.getElementById("comment-editor");
// iframe要素を非表示
iframeElement.style.display = "none";
// [コメントを投稿]の文字を削除
document.getElementById("comment-post-message").remove();
}
loadCommentform();
//]]>
</script>
<!-- End ボタンクリックでコメントフォームを読み込む -->
id='threaded-comment-form'を変更
id='threaded-comment-form'
を検索。
<b:includable id='threaded-comment-form' var='post'>
<div class='comment-form'>
<a name='comment-form'/>
<b:if cond='data:mobile'>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' style='display: none' width='100%'/>
<b:else/>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<!-- srcにabout:blankを追加する ここから -->
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
<!-- srcにabout:blankを追加する ここまで -->
</b:if>
<!-- ここから変更 -->
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
<!-- ここまで変更 -->
</div>
</b:includable>
iframe
タグのsrc
にabout:blank
を追加する。(src='about:blank'
)
変更後
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='about:blank' width='100%'/>
<data:post.cmtfpIframe/>
とその下のscript
タグをコメントアウト。
ボタン要素と親要素を追加して文字実体参照でコメントアウトした<data:post.cmtfpIframe/>
、JavaScriptを追加する。
変更後
<!--<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>-->
<!-- ボタンクリックでコメントフォームを読み込む -->
<button class="comment-form-button" id="commentFormButton" type="button">
コメントを書く
</button>
<div id="cmtfpIframeWrapper"><!--<data:post.cmtfpIframe />--></div>
<script>
/*! Copyright:2023 sutajp | Released under the MIT license | https://sutasutashiki.blogspot.com/p/mit-license.html */
"use strict";
/**
* 注: iframeのsrcにabout:blankを設定すること
* src='about:blank'
*/
/**
* createScriptのonload属性で実行する関数
*/
function BLOG_CMT_createIframe() {
BLOG_CMT_createIframe("<data:post.appRpcRelayPath/>");
}
//<![CDATA[
/**
* ボタンをクリックしたらコメントフォームを読み込む関数
*/
function loadCommentform() {
/** 生成したスクリプトタグを格納 */
let cmtfpIframeJs;
/** iframe要素を取得 */
const iframeElement = document.getElementById("comment-editor");
/**
* ボタンをクリックしたらdata:post.cmtfpIframeの内容と
* onload属性の関数が入ったスクリプトタグをhead内に生成する
*/
function createScript() {
// ボタン要素を非表示
commentFormButton.style.display = "none";
// iframe要素を表示
iframeElement.style.display = "block";
/** data:post.cmtfpIframeの親要素を取得 */
const cmtfpIframeWrapper = document.getElementById("cmtfpIframeWrapper");
/** HTMLに変換 */
const cmtfpIframeHTML = cmtfpIframeWrapper.innerHTML;
/** 正規表現でスクリプトの数字部分を取得 */
const regexp = /jsbin\/([0-9]*)/;
/** マッチした文字列を取得 @return {Array} */
const matchedNumber = cmtfpIframeHTML.match(regexp);
/** スクリプトタグ生成 */
cmtfpIframeJs = document.createElement("script");
// スクリプトの数字部分にマッチした数字を入れる
cmtfpIframeJs.src =
"https://www.blogger.com/static/v1/jsbin/" +
matchedNumber[1] +
"-comment_from_post_iframe.js";
}
function fromButton() {
createScript();
// onload属性でBLOG_CMT_createIframe関数を実行する
cmtfpIframeJs.onload = BLOG_CMT_createIframe;
// headタグに挿入する
document.head.appendChild(cmtfpIframeJs);
}
function fromAnchor() {
createScript();
// onload属性でreplyAnchor関数を実行する
cmtfpIframeJs.onload = replyAnchor;
// headタグに挿入する
document.head.appendChild(cmtfpIframeJs);
}
/**
* 返信リンクからcreateScriptが実行された時にonload属性で実行する関数
*/
function replyAnchor() {
BLOG_CMT_createIframe("<data:post.appRpcRelayPath/>");
/** iframe要素のsrc属性の値を取得 */
const iframeElementSrc = iframeElement.src;
/** iframeのsrcから blogspotRpcToken=数字 を取得する正規表現 */
const srcRegexp = /blogspotRpcToken=[0-9]*/;
/** srcの blogspotRpcToken=数字 部分 */
const blogspotRpcToken = iframeElementSrc.match(srcRegexp)[0];
/** iframeの親要素を取得 */
const iframeElementParentElement = iframeElement.parentElement;
/** 親要素のidを取得 */
const parentElementId = iframeElementParentElement.id;
/** idから数字を取得する正規表現 */
const idRegexp = /c([0-9]*)-ce/;
/** idの数字部分 */
const matchedNumber = parentElementId.match(idRegexp)[1];
/** iframeのsrcを新しい文字列に置き換え */
iframeElement.src = iframeElementSrc.replace(
blogspotRpcToken,
blogspotRpcToken + "&parentID=" + matchedNumber
);
for (let index = 0; index < replyAnchors.length; index++) {
// 各返信リンクのクリックイベントを解除
replyAnchors[index].removeEventListener("click", fromAnchor);
}
}
/** ボタン要素を取得 */
const commentFormButton = document.getElementById("commentFormButton");
// ボタン要素にクリックイベントを設定
commentFormButton.addEventListener("click", fromButton, { once: true });
/** 返信リンクを取得 */
const replyAnchors = document.querySelectorAll(
".secondary-text >.comment-reply,.continue >.comment-reply"
);
for (let index = 0; index < replyAnchors.length; index++) {
// 各返信リンクにクリックイベントを設定
replyAnchors[index].addEventListener("click", fromAnchor);
}
/**
* iframe要素を非表示にする関数
* DOMContentLoadedで実行する
*/
function iframeElementsInitialSetting() {
/** iframe要素を非表示 */
iframeElement.style.display = "none";
}
document.addEventListener("DOMContentLoaded", iframeElementsInitialSetting);
}
loadCommentform();
//]]>
</script>
<!-- End ボタンクリックでコメントフォームを読み込む -->
「コメントを投稿」の文字
「コメントを投稿」の文字をJavaScriptで消しています。
必要ならばJavaScriptの該当部分を削除するか//
でコメントアウトしてください。
// [コメントを投稿]の要素を削除
//document.getElementById("comment-post-message").remove();
ボタンのデザイン
ボタンのデザインはCSSで変更してください。
CSS例
.commentFormButton {
cursor: pointer;
padding: 0.5em;
width: 50%;
}
メモ
<data:post.commentFormIframeSrc/>
17.5kB
<data:post.cmtfpIframe/>
6.8kB
一例:コメントフォームロード前186.9kB、ロード後729kB、差542.1kB
以前のコード
記録のため以前のコードも残しておきます
クリックすると開きます
id='comment-form'
id='comment-form'
を検索。
変更する場所は2番目のiframe
タグとその直上のa
タグです。
<b:includable id='comment-form' var='post'>
<div class='comment-form'>
<a name='comment-form'/>
<b:if cond='data:mobile'>
<h4 id='comment-post-message'>
<a expr:id='data:widget.instanceId + "_comment-editor-toggle-link"' href='javascript:void(0)'><data:postCommentMsg/></a></h4>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' style='display: none' width='100%'/>
<b:else/>
<h4 id='comment-post-message'><data:postCommentMsg/></h4>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<!-- ここから変更-->
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
<!-- ここまで変更-->
</b:if>
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
</div>
</b:includable>
コメントアウト、ボタン要素とJavaScriptを追加
a
タグとiframe
タグをコメントアウト。
ボタン要素とJavaScriptを追加します。
変更前
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
変更後
<!--<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>-->
<button id="commentFormButton" class="comment-form-button" type="button">
コメントを書く
</button>
<script>
/*! Copyright:2023 sutajp | Released under the MIT license | https://sutasutashiki.blogspot.com/p/mit-license.html */
//<![CDATA[
"use strict";
/**
* ボタンがクリックされたらコメントフォームを読み込む関数
*/
function loadCommentForm() {
const commentFormButton = document.getElementById("commentFormButton");
// ボタンを非表示
commentFormButton.style.display = "none";
//]]>
/** コメントフォームのURL */
const commentFormIframeSrc = "<data:post.commentFormIframeSrc/>";
//<![CDATA[
/** iframeタグの内容 */
const iframe = `<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='${commentFormIframeSrc}' width='100%'/>`;
// ボタン要素の下にinsertElmentを挿入
commentFormButton.insertAdjacentHTML("afterend", iframe);
}
/** ボタン要素 */
const commentFormButton = document.getElementById("commentFormButton");
// ボタン要素にクリックイベントを設定
commentFormButton.addEventListener("click", loadCommentForm, { once: true });
// [コメントを投稿]の要素を削除
//document.getElementById("comment-post-message").remove();
//]]>
</script>
id='threaded-comment-form'
id='threaded-comment-form'
を検索。
変更する場所は2番目のiframe
タグとその直上のa
タグです。
<b:includable id='threaded-comment-form' var='post'>
<div class='comment-form'>
<a name='comment-form'/>
<b:if cond='data:mobile'>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' style='display: none' width='100%'/>
<b:else/>
<p><data:blogCommentMessage/></p>
<data:blogTeamBlogMessage/>
<!-- ここから変更 -->
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
<!-- ここまで変更 -->
</b:if>
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
</div>
</b:includable>
コメントアウト ボタン要素とJavaScriptを追加
a
タグとiframe
タグをコメントアウト。
ボタン要素とJavaScriptを追加します。
変更前
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>
変更後
<!--<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='' width='100%'/>-->
<button id="commentFormButton" class="comment-form-button" type="button">
コメントを書く
</button>
<script>
/*! Copyright:2023 sutajp | Released under the MIT license | https://sutasutashiki.blogspot.com/p/mit-license.html */
//<![CDATA[
"use strict";
/**
* ボタンがクリックされたらコメントフォームを読み込む関数
*/
function loadCommentForm() {
// ボタンを非表示
commentFormButton.style.display = "none";
//]]>
/** コメントフォームのURL */
const commentFormIframeSrc = "<data:post.commentFormIframeSrc/>";
//<![CDATA[
/** iframeタグの内容 */
const insertElment = `<div id="commentFormWrapper" class="comment-form-wrapper"><iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' expr:height='data:cmtIframeInitialHeight' frameborder='0' id='comment-editor' name='comment-editor' src='${commentFormIframeSrc}' width='100%'/></div>`;
// ボタン要素の下にinsertElmentを挿入
commentFormButton.insertAdjacentHTML("afterend", insertElment);
// 返信リンクから実行されたら
if (this.flag == true) {
const iframes = document.querySelectorAll(".comment-form-wrapper");
// 追加で生成したiframeを非表示
for (const iframe of iframes) {
iframe.style.display = "none";
}
// [コメントを追加]を表示
addCommentText.style.display = "block";
} else {
const commentFormWrapper = document.getElementById("commentFormWrapper");
// 追加で生成したiframeを表示
commentFormWrapper.style.display = "block";
// [コメントを追加]を非表示
addCommentText.style.display = "none";
}
}
// [コメントを投稿]の要素を削除
//document.getElementById("comment-post-message").remove();
/** [コメントを追加] の要素 */
const addCommentText = document.getElementById("top-continue");
addCommentText.style.display = "none";
// [コメントを追加] をクリックしたら非表示
addCommentText.addEventListener("click", function () {
this.style.display = "none";
});
/**
* 返信リンクを連続してクリックできないようにする
* クリックした返信リンクにpointer-events:noneを設定
* 他の返信リンクにstyle属性があればpointer-events:autoを設定
* @param {string} replyAnchorElement - 返信リンクのaタグ
* @param {number} replyAnchorsIndex - index
*/
function switchReplyAnchorClickable(replyAnchorElement, replyAnchorsIndex) {
// 各返信リンクにクリックイベントを設定
replyAnchorElement.addEventListener("click", function () {
// thisはクリックされたオブジェクト
this.style.pointerEvents = "none";
// 返信リンクにstyleがあればautoを設定
for (let index = 0; index < replyAnchors.length; index++) {
if (replyAnchorsIndex !== index) {
if (replyAnchors[index].hasAttribute("style")) {
replyAnchors[index].style.pointerEvents = "auto";
}
}
}
});
}
/** ボタン要素 */
const commentFormButton = document.getElementById("commentFormButton");
// ボタン要素にクリックイベントを設定
commentFormButton.addEventListener("click", loadCommentForm, { once: true });
/** 返信リンク */
const replyAnchors = document.querySelectorAll(
".secondary-text >.comment-reply,.continue >.comment-reply"
);
for (let index = 0; index < replyAnchors.length; index++) {
// 各返信リンクにクリックイベントを設定
replyAnchors[index].addEventListener(
"click",
{ flag: true, handleEvent: loadCommentForm },
false
);
switchReplyAnchorClickable(replyAnchors[index], index);
}
//]]>
</script>
Memo
No.1
widget version1の場合、src
属性をexpr:src
とすることでもプログラムが動きました。
expr:src='data:post.commentFormIframeSrc'
widget version2の場合プログラムが動かなかったので一度変数にしてから組み込みました。
const commentFormIframeSrc = "<data:post.commentFormIframeSrc/>";
src=...'${commentFormIframeSrc}'...
No.2
iframeロード前186.9KB、ロード後729KB、差542.1KB
No.3
下のコードを消すとコメントフォームの高さに影響がでました。
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
同じ返信リンクを連続してクリック
同じ返信リンクを連続してクリックするとコメントフォームの高さに影響がでました。(下に空間・余白ができる)
そこで、同じ返信リンクを連続してクリックできないようにしました。
コメントなし:
コメントを投稿