人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

サイドバーの関連記事や注目記事、人気記事にはてなスターを表示させたく、スクリプトを組んでいます。
最新記事と関連記事にはスターが表示されるのを確認できるのですが、人気記事には表示されません。
表示されない理由(スクリプトの間違い)に関してご教授・ご指摘頂けると幸いです。
尚、人気記事、注目記事、関連記事はタブ化しております。(関係してるのか不明ですが、一応記させて頂きます。)

スクリプトは以下です。
<script>
$(function(){
var htmlstr = "";
var urEntry = "";
var href = "";

var bb = function(aa){
var urEntries = $(aa).find(".urllist-item-inner");
var i=0;
urEntries.each(function(){
urEntry = $(this);
var entryTitleLink = urEntry.find(".urllist-title");
href = entryTitleLink.attr("href");
htmlstr = "";
htmlstr +='<p class="star-counts"><img src="http://s.st-hatena.com/entry.count.image?uri=';
htmlstr +=href;
htmlstr +='" alt="" class="star-count"></p>';
urEntry.after(htmlstr);
});
}
bb(".hatena-module-entries-access-ranking");
bb(".hatena-module-recent-entries");
bb(".hatena-module-related-entries");
});
</script>
宜しくお願い致します。

●質問者: ぬる太
●カテゴリ:コンピュータ
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● a-kuma3
●100ポイント ベストアンサー

「インスペクタ」ではなく、「ソースを見る」なんかでページを見ると表示されない理由が分かります。
「最新記事」や「関連記事」は、最初のレスポンスで中身がありますが、「人気記事」は枠だけで中身(一覧)がありません。
その後に動くスクリプトで動的に中身が作られているようです。
質問に書かれているスクリプトが、「人気記事」の一覧を作るスクリプトよりも早く動いてしまうので、「人気記事」だけ空振りしているように見えます。

setTimeout で、適当な時間遅らせて実行するというのがお手軽な対応ですが、はてなブログはただでさえ重たいので確実性に欠けるきらいがあります。
古いブラウザだと動きませんが、MutationObserver というのを使うのが確実です。
質問にあるコードを活かすと、こんな感じになります。

$(function(){
 var bb = function(aa){
 var urEntries = $(aa).find(".urllist-item-inner");
 var i=0;
 urEntries.each(function(){
 var urEntry = $(this);
 var entryTitleLink = urEntry.find(".urllist-title");
 var href = entryTitleLink.attr("href");
 var htmlstr = "";
 htmlstr +='<p class="star-counts"><img src="http://s.st-hatena.com/entry.count.image?uri=';
 htmlstr +=href;
 htmlstr +='" alt="" class="star-count"></p>';
 urEntry.after(htmlstr);
 });
 }
// bb(".hatena-module-entries-access-ranking"); こいつは中身が未だできてない
 bb(".hatena-module-recent-entries");
 bb(".hatena-module-related-entries");


 var MutationObserver = window.MutationObserver || window.WebkitMutationObserver; // Safari 対策
 var observer = new MutationObserver(function (records) {
 records.forEach(function (record) {
 setTimeout(function() {
 bb(".hatena-module-entries-access-ranking");
 }, 0);
 });
 observer.disconnect(); // 多分、一回だけで良い
 });
 observer.observe(document.querySelector(".hatena-module-entries-access-ranking"), {childList: true});
});



追記です。
前のコードは確認の仕方がまずかったです。
少しコードを見直しました。

こちらを試してみてください。

$(function() {
 var bb = function(aa){
 var urEntries = $(aa).find(".urllist-item-inner");
 var i=0;
 urEntries.each(function(){
 var urEntry = $(this);
 var entryTitleLink = urEntry.find(".urllist-title");
 var href = entryTitleLink.attr("href");
 var htmlstr = "";
 htmlstr +='<p class="star-counts"><img src="http://s.st-hatena.com/entry.count.image?uri=';
 htmlstr +=href;
 htmlstr +='" alt="" class="star-count"></p>';
 urEntry.after(htmlstr);
 console.log(htmlstr)
 });
 }
 var MutationObserver = window.MutationObserver || window.WebkitMutationObserver; // Safari 対策
 var observer = new MutationObserver(function (records) {
 records.forEach(function (record) {
 if (record.target.classList.contains("hatena-module-body")) { // 念のため
 observer.disconnect(); // 先に監視を止める
 bb(".hatena-module-entries-access-ranking");
 }
 });
 });
 var ranking = document.querySelector(".hatena-module-entries-access-ranking");
 observer.observe(ranking, {childList: true, subtree: true});
});

ぬる太さんのコメント
回答ありがとうございます。 中身が作られる前に走ってしまうというのは盲点でした。 頂いたコードを実行したところ、残念ながら表示できなかったのですが、これはもう構造上(?)の問題として諦めるべきでしょうか…。(chromeで実行しています) もう少し考えてみます。

a-kuma3さんのコメント
>> 頂いたコードを実行したところ、残念ながら表示できなかったのですが、これはもう構造上(?)の問題として諦めるべきでしょうか…。 << いや、できます。 ちょっと手抜きをして、コンソールからの実行で動作を確認したのですが、それが良くなかったんです。 # 遅延時間ゼロの setTimeout なんかを呼び出している辺りは、その辺りの迷いが出てます ぼくが回答で書いたコードは、.hatena-module-entries-access-ranking の中に変化があったときに、一発だけ bb 関数を呼び出して監視を止めてしまう、という動作をします。 .hatena-module-entries-access-ranking の中が徐々に作られていくのでしょう。 A.urllist-title が作られる前に DOM に変化が起きていて、MutationObserver の監視を止めてしまっているのが駄目なんだと思います。 「人気記事」の仕様に依存しますが、項目が10個できるまでは監視を続けるとか。 ああ、注目記事の表示個数って設定で変えられるのか (´・ω・`) でも、何かやりようはありますよ。 ちょっと考えてみます。

a-kuma3さんのコメント
いろいろと勘違いしてました。 見直したコードを回答に追記したので、試してみてください。

ぬる太さんのコメント
出来ました!! ありがとうございました。 お陰様で思った通りのブログになりました。

a-kuma3さんのコメント
>|javascript| var ranking = document.querySelector(".hatena-module-entries-access-ranking"); observer.observe(ranking, {childList: true, subtree: true}); observer.observe(ranking, {childList: true, subtree: true}); // これ ||< MutationObserver の observe メソッド呼び出しを2回やってます。 最初の一回目で監視を止めちゃうから問題ないのかもしれませんが、悪さをしないとも限らないので、ひとつ削除しておいてください。

ぬる太さんのコメント
はてぶ数の方でも表記させようと思い、追加してみたのですが、拙かったでしょうか。

a-kuma3さんのコメント
あっ、そういう意図でしたか。 でも、はてぶの方は、スターついてないですよね。ちょっとお待ちを。

ぬる太さんのコメント
表示される時とされない時がありますね。 ちょっと見直してみます。

a-kuma3さんのコメント
お待たせしました。 こんな感じです。 >|javascript| $(function() { var bb = function(aa){ var urEntries = $(aa).find(".urllist-item-inner"); var i=0; urEntries.each(function(){ var urEntry = $(this); var entryTitleLink = urEntry.find(".urllist-title"); var href = entryTitleLink.attr("href"); var htmlstr = ""; htmlstr +='<p class="star-counts"><img src="http://s.st-hatena.com/entry.count.image?uri='; htmlstr +=href; htmlstr +='" alt="" class="star-count"></p>'; urEntry.after(htmlstr); console.log(htmlstr) }); } var MutationObserver = window.MutationObserver || window.WebkitMutationObserver; // Safari 対策 $(".hatena-module-entries-access-ranking").each(function() { var hatena_module = this; var observer = new MutationObserver(function (records) { records.forEach(function (record) { if (record.target.classList.contains("hatena-module-body")) { // 念のため observer.disconnect(); // 先に監視を止める bb(record.target); } }); }); observer.observe(hatena_module, {childList: true, subtree: true}); }); }); ||< 後半を変えてます。 ふたつのエリアを監視するので、MutationObserver のインスタンスもふたつ作ります。 また、関数 bb() も、クラスセレクタの文字列を指定すると先頭の方を 2回とも処理してしまうので、MutationObserver の監視に引っかかった要素を渡しています。

ぬる太さんのコメント
僕の想定通りの動きをしています。 凄すぎです。 二重に書くだけだと、文字列が同じこともあって処理のタイミングの誤差かなにかで表示されたり・表示されなかったりとなっていたのですね。 重ね重ね、御礼申し上げます。 誠にありがとうございました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ