【節約】クリックでコメントフォームを読み込む【Blogger】の覚え書きです。
- 既存のコードを流用
- なるべくHTMLは変更せずにJavaScriptを使用
勘違いなどあると思いますが、いろいろやってみた感想です。
概要
ボタンクリックで、<data:post.cmtfpIframe/>
とJavaScriptを動的に生成し、コメントフォームを読み込む。
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
基本情報
下記iframe
要素の空のsrc
属性にURLが入ることでコメントフォームが展開する。
<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%'/>
URLは
<a expr:href='data:post.commentFormIframeSrc' id='comment-editor-src'/>
が出力する。(data:post.commentFormIframeSrc
がURLを出力)
次に、<data:post.cmtfpIframe/>
とJavaScriptで、出力したURLをsrc
属性に挿入する。
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
iframeタグにstyle='display:block'
が設定される。
基本情報2
コメントがない場合と、コメントがある場合で、実行するincludable
タグが違う。
各includable
タグの基本構成は同じなので設計によっては1つのincludable
タグにまとめられると思う。
今回のコード
コメントがある場合は返信に使用するリンク(以下、返信リンク)があるので、コメントがない場合と、コメントがある場合でJavaScriptが異なる。
コメントがない場合
<b:includable id='comment-form' var='post'>
を検索
<data:post.cmtfpIframe/>
<script type='text/javascript'>
BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
</script>
をコメントアウトして、以下を追加。
- ボタン要素
- 親要素を追加して文字実体参照でコメントアウトした
<data:post.cmtfpIframe/>
※ - JavaScript
※通常のコメントアウト<!--<data:post.cmtfpIframe/>-->
ではURLを出力しなかった。
<!--<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>
<data:post.cmtfpIframe/>
が出力したURLは
https://www.blogger.com/static/v1/jsbin/976584016-comment_from_post_iframe.js
この数字部分が固定か変動かわからなかったので、正規表現で抽出した。
スクリプトタグの中身BLOG_CMT_createIframe('<data:post.appRpcRelayPath/>');
は
<data:post.cmtfpIframe/>
のあとに実行される必要があるようなので、onload
属性で実行させた。
コメントがある場合
<b:includable id='threaded-comment-form' var='post'>を検索
コメントがない場合と同様の処理をする。
以下は異なる部分。
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='' width='100%'/>
が、<div id='comment-holder'>
の<data:post.commentHtml/>
の下?に挿入される
<div id='comment-holder'>
<data:post.commentHtml/>
</div>
<data:post.cmtfpIframe/>
とスクリプトタグをコメントアウトすると、このiframe
要素のsrc
に今開いているページのURLが挿入されてしまう。
(<b:includable id='threaded_comment_js' var='post'>
のJavaScriptがからんでいるっぽい)
このままだとボタンクリックの前に今開いているページが読み込まれるので、iframe
要素のsrc
にabout:blank
を設定した。
<iframe>...
src='about:blank'
...
</iframe>
(setAttribute("src", "")
をつかってsrc
を空欄にした場合、デベロッパーツールをみると今開いているページの読み込みがキャンセルされる模様)
javascript - Is an empty iframe src valid? - Stack Overflow
また、このiframe
要素は、そのままだと要素を取得できなかったのでDOMContentLoaded
を使用して要素を取得した。
/**
* iframe要素を非表示にする関数
* DOMContentLoadedで実行する
*/
function iframeElementsInitialSetting() {
/** iframe要素を非表示 */
iframeElement.style.display = "none";
}
document.addEventListener("DOMContentLoaded", iframeElementsInitialSetting);
各返信リンクにクリックイベントを設定。
ボタンや返信リンクがクリックされたらクリックイベントを解除。
返信リンク
(返信でない)コメントを追加するとsrcの値は
https://www.blogger.com/comment/frame/7578384715165747647?po=4589374603246402768&hl=ja&blogspotRpcToken=6614768...
のようなかたち。
返信の場合はこの値に&parentID=数字
が必要。
https://www.blogger.com/comment/frame/7578384715165747647?po=4589374603246402768&hl=ja&blogspotRpcToken=8342520&parentID=3892762108755540327...
parentIDの数字はiframe親要素のidの数字部分
<div class="comment-replybox-single" id="c3892762108755540327-ce">
<iframe ... src='https://www.blogger.com/comment/frame/7578384715165747647?po=4589374603246402768&hl=ja&blogspotRpcToken=8342520&parentID=3892762108755540327...' ...>
</iframe></div>
blogspotRpcToken=数字
を正規表現で抽出。
iframeの親要素のidを取得。
c数字-ce
の数字部分を正規表現で抽出。
replace関数でblogspotRpcToken=数字
を
blogspotRpcToken=数字
+ &parentID=
+ c数字-ceの数字部分
に置き換え。
/** 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
);
メモ
コメントフォームを読み込むとコンテンツがずれるのはデフォルト。(仕様みたい)
(<b:includable id='threaded_comment_js' var='post'>
が関係していそう)
iframe要素のheightの初期値は250px、コメントフォームを読み込むと67pxになる。
初期値を67pxにするには
iframeElement.setAttribute("height", "67");
をiframeElementsInitialSetting関数とreplyAnchor関数に追加。
クリックイベントを解除しない。
/*
for (let index = 0; index < replyAnchors.length; index++) {
// 各返信リンクのクリックイベントを解除
replyAnchors[index].removeEventListener("click", fromAnchor);
}
*/
メモ2(個人的)
QooQをwidget version2に換装したものは、コメントがある時、iframeにdisplay:block;
が設定され、display:none;
が設定されなかった。
iframeElement.style.display = "none";
が効いていないと思ったが、console.logではstyle="display:none;"
となっていたので、styleが上書きされている様子。
読み込むタイミングを変更してもダメだった。
window.addEventListener("load", iframeElementsInitialSetting);
ただCSSで{display:none !important;}
とすると効いたので、styleタグを動的にhead内に生成した。
/** iframeを非表示にする */
const style = document.createElement("style");
style.textContent = "#comment-editor {display: none !important;}";
document.head.appendChild(style);
ボタンや返信リンクがクリックされたらdisplay: block !important
を設定する
/**
* iframe要素を表示する関数
*/
function showIframe() {
// iframe要素を表示
const style = document.createElement("style");
style.textContent = "#comment-editor {display: block !important;}";
document.head.appendChild(style);
}
createScript関数とreplyAnchor関数でshowIframe関数を実行
// iframe要素を表示する
showIframe();
参考サイト
data:posts[i].cmtfpIframe (Blog) - Blogger Data Documentation - Blogger Code PE
コメントなし:
コメントを投稿