サイドバーの関連記事や注目記事、人気記事にはてなスターを表示させたく、スクリプトを組んでいます。

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

スクリプトは以下です。
<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人3回まで
  • 登録:
  • 終了:2017/02/14 18:51:32
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4973ベストアンサー獲得回数2154

ポイント100pt

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

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});
});



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

  • 監視モードに subtree を追加
  • ★をつける前に監視を止める

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

$(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});
});
他8件のコメントを見る
id:a-kuma3

お待たせしました。
こんな感じです。

$(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 の監視に引っかかった要素を渡しています。

2017/02/14 21:08:08
id:nuruta

僕の想定通りの動きをしています。
凄すぎです。
二重に書くだけだと、文字列が同じこともあって処理のタイミングの誤差かなにかで表示されたり・表示されなかったりとなっていたのですね。

重ね重ね、御礼申し上げます。
誠にありがとうございました。

2017/02/14 21:17:32

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません