IT the Best

はてなブログのカスタマイズ情報を中心に、WEBデザインからJavaScriptまでWEB系の開発情報を発信します。便利ツールや暇つぶしのゲームなど開発物も公開します。

はてなブログのカテゴリーとパンくずリストを階層化表示にする -SEOに効果あり- #階層カテゴリーパンくずリストの表示

f:id:Surprisedblog:20190619185106j:plain

 

初期Scriptファイルのため、不備などがありあまり参考になりません。

 

新しく、カテゴリー・パンくずリストを階層化表示にする機能を作成しました。こちらの方が扱いやすく、不具合が起こる可能性も低いと思われます。

www.it-the-best.com

ほとんどの機能変更はありませんが、パンくずリストの区切り文字や階層化させるカテゴリーリストの選択など新たに独自カスタマイズができるようになりました。すべてのコードを見直し約5千行省略したためほんの少しですが軽くなりました。
しかし、大きな変更点として新しいScriptコード(ファイル)では、最初に表示されているカテゴリーをパンくずリストに表示するようにしました。
また、新しく投稿した記事の方がスマホからのカスタマイズも容易です。

 

 

当記事は、階層カテゴリーを表示するために開発したJavaScriptファイルの説明になります。#階層カテゴリーパンくずリストの表示

https://cdn.it-the-best.com/js/category/2.2/category.min.jsの説明

 

www.it-the-best.com

階層カテゴリーパンくずリストの表示

//パンくずリストを表示
function create_breadcrumblist() {
    //記事のカテゴリーをすべて取得
    var mlist = [], slist = [], list = []
    $(".entry-categories.categories .entry-category-link").each(function (index, element) {
        if (element.innerText.match(/^[\w].*-|^[\W].*[\W].*-/)) {
            mlist.push(element.innerText)
        } else {
            slist.push(element.innerText)
        }
        list.push(element.innerText)
    })
    //カテゴリーが存在しない
    if (list == "") { return }
    var breadcategoryname
    if (mlist == "") {
        breadcategoryname = slist[0]
    } else {
        //先頭に置かれたカテゴリーが階層カテゴリーの一部である
        var breadcategoryname_flag = false
        Organize_mcl(mlist)
        for (var m of mlist) {
            var cname_list = sorting_categories(m)
            for (var cname of cname_list) {
                if (cname == list[0]) {
                    breadcategoryname = m
                    breadcategoryname_flag = true
                    break
                }
            }
            if (breadcategoryname_flag) {
                break
            }
        }
        if (!breadcategoryname_flag) {
            breadcategoryname = slist[0]
        }
    }
    var bc_list = sorting_categories(breadcategoryname)
    /*パンくずリストを表示*/
    var ol = document.createElement("ol")
    ol.setAttribute("itemscope", "")
    ol.setAttribute("itemtype", "https://schema.org/BreadcrumbList")
    //homeを追加
    var li = document.createElement("li")
    li.setAttribute("itemprop", "itemListElement")
    li.setAttribute("itemscope", "")
    li.setAttribute("itemtype", "https://schema.org/ListItem")
    ol.append(li)
    var a = document.createElement("a")
    a.setAttribute("itemtype", "https://schema.org/Thing")
    a.setAttribute("itemprop", "item")
    a.setAttribute("href", location.origin)
    li.append(a)
    var span = document.createElement("span")
    span.setAttribute("itemprop", "name")
    span.innerText = "トップ"
    a.append(span)
    var meta = document.createElement("meta")
    meta.setAttribute("itemprop", "position")
    meta.setAttribute("content", 1)
    li.append(meta)
    var span = document.createElement("span")
    span.innerText = ">"
    span.classList.add("breadcrumb-gt")
    ol.append(span)
    //jsonデータ作成
    var breadcrumb_json = {}
    breadcrumb_json["@context"] = "https://schema.org"
    breadcrumb_json["@type"] = "BreadcrumbList"
    breadcrumb_json["itemListElement"] = []
    var json = {}
    //jsonデータ追加
    json["@type"] = "ListItem"
    json["position"] = 1
    json["name"] = "トップ"
    json["item"] = location.origin
    breadcrumb_json["itemListElement"].push(json)
    for (let i = 0; i < bc_list.length; i++) {
        var bc = bc_list[0]
        if (i !== 0) {
            for (let k = 1; k < i + 1; k++) {
                bc = bc + "-" + bc_list[k]
            }
        }
        var li = document.createElement("li")
        li.setAttribute("itemprop", "itemListElement")
        li.setAttribute("itemscope", "")
        li.setAttribute("itemtype", "https://schema.org/ListItem")
        ol.append(li)
        //Myblog情報
        var a = document.createElement("a")
        a.setAttribute("itemtype", "https://schema.org/Thing")
        a.setAttribute("itemprop", "item")
        a.setAttribute("href", location.origin + "/archive/category/" + bc)
        li.append(a)
        var span = document.createElement("span")
        span.setAttribute("itemprop", "name")
        span.innerText = bc_list[i]
        a.append(span)
        var meta = document.createElement("meta")
        meta.setAttribute("itemprop", "position")
        meta.setAttribute("content", i + 2)
        li.append(meta)
        var span = document.createElement("span")
        span.innerText = ">"
        span.classList.add("breadcrumb-gt")
        ol.append(span)
        //jsonデータ追加
        var json = {}
        json["@type"] = "ListItem"
        json["position"] = i + 2
        json["name"] = bc_list[i]
        json["item"] = location.origin + "/archive/category/" + bc
        breadcrumb_json["itemListElement"].push(json)
    }
    try {
        var bc = document.getElementsByClassName("breadcrumb")
        bc[0].innerText = null
        bc[0].append(ol)
    } catch (error) {
        var div = document.createElement("div")
        div.classList.add("breadcrumb")
        div.style.marginBottom = "0px"
        div.append(ol)
        $("#main-inner article").each(function (i, e) {
            e.insertBefore(div, e.firstChild);
        })
    }
    //scriptデータ追加
    var script_ele = document.createElement("script")
    script_ele.setAttribute("type", "application/ld+json")
    script_ele.innerText = JSON.stringify(breadcrumb_json)
    ol.parentNode.insertBefore(script_ele, ol.nextSibling);
    /*パンくずリストを表示*/
}
//カテゴリーを整理する
function Organize_mcl(destination_list) {
    var list = destination_list
    var num = []
    for (var i of list) {
        var i_clist = sorting_categories(i)
        for (var i2 of list) {
            var len = i_clist.length
            var len_list = i
            if (i == i2) { continue }
            var i2_clist = sorting_categories(i2)
            if (i_clist.length > i2_clist.length) {
                len = i2_clist.length
                len_list = i2
            }
            var push_flag = false
            for (let k = 0; k < len; k++) {
                if (i_clist[k] === i2_clist[k]) {
                    push_flag = true
                } else {
                    push_flag = false
                    break
                }
            }
            if (push_flag) {
                if (num.indexOf(len_list) < 0) {
                    num.push(len_list)
                }
            }
        }
    }
    for (let n of num) {
        list.splice(list.indexOf(n), 1)
    }
}
// カテゴリーを仕分けする
function sorting_categories(str) {
    var cs_list = [], cs = ""
    var flag = true
    for (var s of str) {
        if (s == "'" || s == '"') {
            flag = !flag
        }
        if (flag && s == "-") {
            cs_list.push(cs)
            cs = ""
        } else {
            cs = cs + s
        }
    }
    cs_list.push(cs)
    return cs_list
}

 

はてなブログのカテゴリーとパンくずリストを階層化表示にする -SEOに効果あり- #カテゴリーの表示を変える

f:id:Surprisedblog:20190619185106j:plain


初期Scriptファイルのため、不備などがありあまり参考になりません。

 

新しく、カテゴリー・パンくずリストを階層化表示にする機能を作成しました。こちらの方が扱いやすく、不具合が起こる可能性も低いと思われます。

www.it-the-best.com

ほとんどの機能変更はありませんが、パンくずリストの区切り文字や階層化させるカテゴリーリストの選択など新たに独自カスタマイズができるようになりました。すべてのコードを見直し約5千行省略したためほんの少しですが軽くなりました。
しかし、大きな変更点として新しいScriptコード(ファイル)では、最初に表示されているカテゴリーをパンくずリストに表示するようにしました。
また、新しく投稿した記事の方がスマホからのカスタマイズも容易です。

 

 

当記事は、階層カテゴリーを表示するために開発したJavaScriptファイルの説明になります。#カテゴリーの表示を変える

https://cdn.it-the-best.com/js/category/2.2/category.min.jsの説明

 

www.it-the-best.com

カテゴリーの表示を変える 

 カテゴリーが表示される主な場所

・カテゴリータグ:記事一覧、記事内

・カテゴリーリスト:カテゴリー一覧、パンくずリスト

カテゴリー情報を取得する

 ほとんどのページで表示されるカテゴリーの要素は、クラスに"category-[カテゴリー名]"というクラス名を持っています。例)class="category-HTML"

var categories_list=$("[class*='category-']")

階層化カテゴリータグを表示させない

 記事にサブカテゴリーを追加しただけでは、ハイフンを含めたカテゴリータグが表示されてしまうので、カテゴリーの表示全てを変更します。

var categories_list=$("[class*='category-']")//カテゴリー要素を取得
    for (var element of categories_list) {
        if (element.tagName !== "BODY" && element.className.match(/ category-[\w].*-| category-[\W].*[\W].*-/)) {//"、'などの記号で始まるものは対象外
            element.style.display="none"//階層化カテゴリーを非表示にする
        }
    }

簡略

$("[class*='category-']").each(function (index, element) {
        if (element.tagName !== "BODY" && element.className.match(/ category-[\w].*-| category-[\W].*[\W].*-/)) {
            element.style.display = "none"//階層化カテゴリーを非表示にする
        }
    })

階層化カテゴリーの表示を変える

 表示を変えるために階層化カテゴリーリストを作ります。 

  すべてのカテゴリーを取得

まず、すべてのカテゴリーを取得します。

var m_clist = [], s_clist = [], clist = [], m_clist_json = {}
//カテゴリー一覧のカテゴリー名をすべて取得・階層化カテゴリーを非表示
function getcategorylist_hiddencategory() {
    $(".hatena-module-category ul").each(function (index, element) {
        for (var e of element.children) {
            var categoryname = e.children[0].innerText
            var re = categoryname.match(/ [\W]\d*[\W]$/g)
            categoryname = categoryname.replace(re, "")
            if (clist.indexOf(categoryname) < 0) {
                add_category_list(categoryname)
            }
        }
    })
    if (m_clist == "") { return }
    Organize_mcl(m_clist)
}
//カテゴリーリストに追加する
function add_category_list(categoryname) {
    clist.push(categoryname)
    if (categoryname.match(/^[\w].*-|^[\W].*[\W].*-/)) {
        m_clist.push(categoryname)//サブカテゴリーを含むカテゴリー
    } else {
        s_clist.push(categoryname)//独立カテゴリー
    }
}
//カテゴリーを整理する
function Organize_mcl(destination_list) {
    var list = destination_list
    var num = []
    for (var i of list) {
        var i_clist = sorting_categories(i)
        for (var i2 of list) {
            var len = i_clist.length
            var len_list = i
            if (i == i2) { continue }
            var i2_clist = sorting_categories(i2)
            if (i_clist.length > i2_clist.length) {
                len = i2_clist.length
                len_list = i2
            }
            var push_flag = false
            for (let k = 0; k < len; k++) {
                if (i_clist[k] === i2_clist[k]) {
                    push_flag = true
                } else {
                    push_flag = false
                    break
                }
            }
            if (push_flag) {
                if (num.indexOf(len_list) < 0) {
                    num.push(len_list)
                }
            }
        }
    }
    for (let n of num) {
        list.splice(list.indexOf(n), 1)
    }
}

階層化カテゴリー用のjsonデータを作成

//階層化カテゴリー用のjsonデータ作成
function createjson_for_hierarchy(list, json) {
    for (let i = 0; i < list.length; i++) {
        var cn_1 = list[i]
        var cnlist_1 = sorting_categories(cn_1)
        try {
            var P = sorting_categories(json[cnlist_1[0]][0])[0]
            if (P == cnlist_1[0]) {
                continue
            }
        } catch (error) { }
        for (let k = i + 1; k < list.length; k++) {
            var cn_2 = list[k]
            var cnlist_2 = sorting_categories(cn_2)
            if (cnlist_1[0] == cnlist_2[0]) {
                if (json[cnlist_1[0]]) {
                    json[cnlist_1[0]].push(cn_2)
                } else {
                    json[cnlist_1[0]] = [cn_1, cn_2]
                }
            }
        }
    }
}
// カテゴリーを仕分けする
function sorting_categories(str) {
    var cs_list = [], cs = ""
    var flag = true
    for (var s of str) {
        if (s == "'" || s == '"') {
            flag = !flag
        }
        if (flag && s == "-") {
            cs_list.push(cs)
            cs = ""
        } else {
            cs = cs + s
        }
    }
    cs_list.push(cs)
    return cs_list
}
 カテゴリー一覧(階層化表示にする)

 カテゴリー一覧を、階層化カテゴリーリストをもとに階層化表示にします。

//カテゴリー一覧の表示を変える
function Change_display_categorylist() {
    var Pc_list = []
    for (var mc of m_clist) {
        var list = sorting_categories(mc)
        var P = list[0]
        $(".hatena-module-category ul").each(function (index, element) {
            for (var e of element.children) {
                var categoryname = e.children[0].innerText
                var re = categoryname.match(/ [\W]\d*[\W]$/g)
                categoryname = categoryname.replace(re, "")
                for (var i of list) {
                    if (i == categoryname && e.className.indexOf("descendant-li") < 0) {
                        e.style.display = "none"
                        e.style.borderTop = "0px"
                    }
                }
                //階層カテゴリの最上位と同じカテゴリ
                if (P == categoryname && Pc_list.indexOf(sorting_categories(mc)[0]) < 0) {
                    Create_Element_categorylist(mc, e, re)
                    Pc_list.push(sorting_categories(mc)[0])
                    //階層カテゴリの最上位と同じカテゴリ名のリスト項目の非表示
                    e.style.display = "none"
                }
            }
        })
    }
    hidden_categorylist_d()
}
function hidden_categorylist_d() {
    $(".hatena-module-category ul").each(function (index, element) {
        for (var e of element.children) {
            var categoryname = e.children[0].innerText
            var re = categoryname.match(/ [\W]\d*[\W]$/g)
            categoryname = categoryname.replace(re, "")
            //階層化カテゴリーを非表示にする
            if (categoryname.match(/^[\w].*-|^[\W].*[\W].*-/)) {
                e.style.display = "none"
                e.style.borderTop = "0px"
            }
        }
    })
}
// 階層化カテゴリーリストの要素を作る
function Create_Element_categorylist(categoryname, element, cnum) {
    var cn_list = sorting_categories(categoryname)
    var li = document.createElement("li")
    li.classList.add("descendant-li", "descendant-li-" + cn_list[0])
    element.parentNode.insertBefore(li, element.nextSibling);
    var a = document.createElement("a")
    a.classList.add("categoryname")
    a.innerText = cn_list[0] + cnum
    a.href = location.origin + "/archive/category/" + cn_list[0]
    li.append(a)
    var span = document.createElement("span")
    span.classList.add("icon-arrow-down")
    a.after(span)
    element = li
    var m_cname = cn_list[0]
    for (let i = 1; i < cn_list.length; i++) {
        var c = cn_list[i]
        m_cname = m_cname + "-" + c
        element = form_dc_element(c, element, m_cname)
    }
    //階層がわかれる場合
    if (m_clist_json[cn_list[0]]) {
        for (var cname of m_clist_json[cn_list[0]]) {
            element = li
            var cname_list = sorting_categories(cname)
            var m_cname = cn_list[0]
            for (let i = 1; i < cname_list.length; i++) {
                var c = cname_list[i]
                m_cname = m_cname + "-" + c
                var li_ele = document.getElementsByClassName("descendant-li-" + m_cname)
                if (li_ele.length > 0) {//すでにある場合
                    element = li_ele[0]
                } else {
                    element = form_dc_element(c, element, m_cname)
                }
            }
            try {
                bottompotch_hidden(element)
            } catch (error) {
                element.each(function (index, e) {
                    bottompotch_hidden(e)
                })
            }
        }
    } else {
        bottompotch_hidden(element)
    }
}
//リスト項目エレメントの生成
function form_dc_element(categoryname, topelement, fq_cname) {
    var num = get_contentnum(fq_cname)
    var ul = document.createElement("ul")
    ul.classList.add("descendant-ul")
    topelement.append(ul)
    var li = document.createElement("li")
    li.classList.add("descendant-li", "descendant-li-" + fq_cname)
    ul.append(li)
    var a = document.createElement("a")
    a.classList.add("categoryname")
    a.innerText = categoryname + num
    //a.style.display = "none"
    a.href = location.origin + "/archive/category/" + fq_cname
    li.append(a)
    var span = document.createElement("span")
    span.classList.add("icon-arrow-right")
    a.before(span)
    return li
}
//bottomカテゴリーのポッチをなくす
function bottompotch_hidden(element) {
    for (var e of element.children) {
        if (e.tagName == "A") {
            e.style.display = "block"
        } else {
            e.style.display = "none"
        }
    }
}
//カテゴリーの記事数を取得する
function get_contentnum(categoryname) {
    var number
    $(".hatena-module-category ul").each(function (index, element) {
        for (var e of element.children) {
            var c = e.children[0].innerText
            var re = c.match(/ [\W]\d*[\W]$/g)
            c = c.replace(re, "")
            if (categoryname == c) {
                number = re
            }
        }
    })
    return number
}

 クリック・タッチイベントの設定

//click/touch eventを設定
function set_event() {
    var ua = navigator.userAgent
    if (ua.match(/iphone|ipod|ipad|android/i)) {
        //タッチデバイスの場合
        set_event_touchdevice()   
    }
    else {
        // PCの場合
        set_event_pc()
    }
}
//pc
function set_event_pc() {
    var target = document.getElementsByClassName("icon-arrow-right")
    for (var i of target) {
        i.addEventListener("click", function (e) {
            for (var c of e.target.parentNode.children) {
                if (c.tagName == "UL") {
                    if (c.style.display == "block" && e.target.className.indexOf("icon-arrow-right") >= 0) {
                        c.style.display = "none"
                        e.target.classList.remove("icon-arrow-right-down")
                    } else {
                        c.style.display = "block"
                        e.target.classList.add("icon-arrow-right-down")
                    }
                }
            }
        })
    }
    var target = document.getElementsByClassName("icon-arrow-down")
    for (var i of target) {
        i.addEventListener("click", function (e) {
            for (var c of e.target.parentNode.children) {
                if (c.tagName == "UL") {
                    if (c.style.display == "block" && e.target.className.indexOf("icon-arrow-down") >= 0) {
                        c.style.display = "none"
                        e.target.classList.remove("icon-arrow-down-up")
                    } else {
                        c.style.display = "block"
                        e.target.classList.add("icon-arrow-down-up")
                    }
                }
            }
        })
    }
    var target = document.getElementsByClassName("descendant-li")
    for (var i of target) {
        i.addEventListener("click", function (e) {
            for (var c of e.target.children) {
                if (c.tagName == "SPAN" && c.className.indexOf("icon-arrow-down") >= 0) {
                    if (c.className.indexOf("icon-arrow-down-up") < 0) {
                        c.classList.add("icon-arrow-down-up")
                    } else {
                        c.classList.remove("icon-arrow-down-up")
                    }
                }
                else if (c.tagName == "UL") {
                    if (c.style.display == "block") {
                        c.style.display = "none"
                    } else {
                        c.style.display = "block"
                    }
                }
            }
        })
    }
    var target = document.getElementsByClassName("descendant-ul")
    for (var i of target) {
        i.addEventListener("click", function (e) {
            var ctag = ""
            for (var c of e.target.children) {
                if (c.tagName == "SPAN" && c.className.indexOf("icon-arrow-right") >= 0) {
                    ctag = c
                }
                else if (c.tagName == "UL") {
                    if (c.style.display == "block") {
                        c.style.display = "none"
                        ctag.classList.add("icon-arrow-right-down")
                    } else {
                        c.style.display = "block"
                        ctag.classList.remove("icon-arrow-right-down")
                    }
                }
            }
        })
    }
}
//touchdevice
function set_event_touchdevice() {
    var touch_flag=false
    var target = document.getElementsByClassName("descendant-li")
    for (var i of target) {
        i.addEventListener("touchstart",touch_start,false)
        i.addEventListener("touchmove",touch_move,false)
        i.addEventListener("touchend", function (e) {
            if(!touch_flag){return}
            for (var c of e.target.children) {
                if (c.tagName == "SPAN" && c.className.indexOf("icon-arrow-down") >= 0) {
                    if (c.className.indexOf("icon-arrow-down-up") < 0) {
                        c.classList.add("icon-arrow-down-up")
                    } else {
                        c.classList.remove("icon-arrow-down-up")
                    }
                }
                else if (c.tagName == "SPAN" && c.className.indexOf("icon-arrow-right") >= 0) {
                    if (c.className.indexOf("icon-arrow-right-down") < 0) {
                        c.classList.add("icon-arrow-right-down")
                    } else {
                        c.classList.remove("icon-arrow-right-down")
                    }
                }
                else if (c.tagName == "UL") {
                    if (c.style.display == "block") {
                        c.style.display = "none"
                    } else {
                        c.style.display = "block"
                    }
                }
            }
            touch_flag=false
        },false)
    }
    function touch_start(){
        touch_flag=true
    }
    function touch_move(){
        touch_flag=false
    }
}
  カテゴリータイトルの表示を変える
//カテゴリータイトル名の階層化表示
function change_categoryname_title() {
    var categoryname = false
    $(".archive-header-category h2").each(function (i, e) {
        categoryname = e.innerText
        var category_list = sorting_categories(e.innerText)
        if (category_list.length == 1) { return }
        var category_title, category_htitle, count = 0
        e.innerText = null
        for (var c of category_list) {
            count = count + 1
            if (count == 1) {
                category_htitle = c
                category_title = c
            } else {
                category_htitle = category_htitle + " > " + c
                category_title = category_title + "-" + c
            }
            var a = document.createElement("a")
            a.classList.add("archive-header-d-categoryname")
            a.href = location.origin + "/archive/category/" + category_title
            a.innerText = c
            e.append(a)
            if (category_list.length !== count) {
                var span = document.createElement("span")
                span.classList.add("archive-header-d-categoryname", "breadcrumb-gt")
                span.innerText = ">"
                e.append(span)
            }
        }
        var span = document.createElement("span")
        span.innerText = category_htitle
        span.classList.add("archive-header-categoryname")
        span.style.display = "none"
        e.insertBefore(span, e.firstChild)
        /*$("header .archive-header-d-categoryname").css({
            "display":"none"
        })*/
    })
    if (!categoryname) { return }
    /*パンくずリストを表示*/
    var breadcategoryname = categoryname
    var bc_list = sorting_categories(breadcategoryname)
    var ol = document.createElement("ol")
    ol.setAttribute("itemscope", "")
    ol.setAttribute("itemtype", "https://schema.org/BreadcrumbList")
    //homeを追加
    var li = document.createElement("li")
    li.setAttribute("itemprop", "itemListElement")
    li.setAttribute("itemscope", "")
    li.setAttribute("itemtype", "https://schema.org/ListItem")
    ol.append(li)
    var a = document.createElement("a")
    a.setAttribute("itemtype", "https://schema.org/Thing")
    a.setAttribute("itemprop", "item")
    a.setAttribute("href", location.origin)
    li.append(a)
    var span = document.createElement("span")
    span.setAttribute("itemprop", "name")
    span.innerText = "トップ"
    a.append(span)
    var meta = document.createElement("meta")
    meta.setAttribute("itemprop", "position")
    meta.setAttribute("content", 1)
    li.append(meta)
    var span = document.createElement("span")
    span.innerText = ">"
    span.classList.add("breadcrumb-gt")
    ol.append(span)
    //jsonデータ作成
    var breadcrumb_json = {}
    breadcrumb_json["@context"] = "https://schema.org"
    breadcrumb_json["@type"] = "BreadcrumbList"
    breadcrumb_json["itemListElement"] = []
    var json = {}
    //jsonデータ追加
    json["@type"] = "ListItem"
    json["position"] = 1
    json["name"] = "トップ"
    json["item"] = location.origin
    breadcrumb_json["itemListElement"].push(json)
    for (let i = 0; i < bc_list.length; i++) {
        var bc = bc_list[0]
        if (i !== 0) {
            for (let k = 1; k < i + 1; k++) {
                bc = bc + "-" + bc_list[k]
            }
        }
        var li = document.createElement("li")
        li.setAttribute("itemprop", "itemListElement")
        li.setAttribute("itemscope", "")
        li.setAttribute("itemtype", "https://schema.org/ListItem")
        ol.append(li)
        //Myblog情報
        var a = document.createElement("a")
        a.setAttribute("itemtype", "https://schema.org/Thing")
        a.setAttribute("itemprop", "item")
        a.setAttribute("href", location.origin + "/archive/category/" + bc)
        li.append(a)
        var span = document.createElement("span")
        span.setAttribute("itemprop", "name")
        span.innerText = bc_list[i]
        a.append(span)
        var meta = document.createElement("meta")
        meta.setAttribute("itemprop", "position")
        meta.setAttribute("content", i + 2)
        li.append(meta)
        if (bc_list.length - 1 !== i) {
            var span = document.createElement("span")
            span.innerText = ">"
            span.classList.add("breadcrumb-gt")
            li.append(span)
        }
        //jsonデータ追加
        var json = {}
        json["@type"] = "ListItem"
        json["position"] = i + 2
        json["name"] = bc_list[i]
        json["item"] = location.origin + "/archive/category/" + bc
        breadcrumb_json["itemListElement"].push(json)
    }
    try {
        var bc = document.getElementsByClassName("breadcrumb")
        bc[0].innerText = null
        bc[0].append(ol)
    } catch (error) { }
    /*パンくずリストを表示*/
    //scriptデータ追加
    var script_ele = document.createElement("script")
    script_ele.setAttribute("type", "application/ld+json")
    script_ele.innerText = JSON.stringify(breadcrumb_json)
    ol.parentNode.insertBefore(script_ele, ol.nextSibling);
}

【簡単】カテゴリーとパンくずリストを階層化表示にする -SEOに効果あり- | はてなブログ #説明

f:id:Surprisedblog:20190619185106j:plain

 

新しく、カテゴリー・パンくずリストを階層化表示にする機能を作成しました。こちらの方が扱いやすく、不具合が起こる可能性も低いと思われます。

www.it-the-best.com

ほとんどの機能変更はありませんが、パンくずリストの区切り文字や階層化させるカテゴリーリストの選択など新たに独自カスタマイズができるようになりました。すべてのコードを見直し約5千行省略したためほんの少しですが軽くなりました。
しかし、大きな変更点として新しいScriptコード(ファイル)では、最初に表示されているカテゴリーをパンくずリストに表示するようにしました。
また、新しく投稿した記事の方がスマホからのカスタマイズも容易です。

 

 

当記事は、階層カテゴリーを表示するために開発した機能の、おおまかな説明になります。

www.it-the-best.com

説明

階層カテゴリーについて

 ハイフンで書かれた階層カテゴリーは、「カテゴリータグ」では表示されないように処理をしています。

 

 サブカテゴリーでなくハイフンを含むカテゴリーを指定したい場合は、「"」(ダブルクォーテーション)か「'」(シングルクォーテーション)で囲みます。例)"box-shadow"
※囲まれていない場合は、それ以降にハイフンを入れてもサブカテゴリーと判断しません。

パンくずリストについて

 パンくずリストに表示されるカテゴリーは先頭に置かれたカテゴリーです。もし、そのカテゴリーが階層カテゴリーの一部であれば、パンくずリストは階層カテゴリーを表示します。先頭に置かれたカテゴリーを含む階層カテゴリーに分岐がある場合は、先に置かれている最下位までの階層カテゴリーが表示されます。

f:id:Surprisedblog:20190619191527p:plain

コチラの画像のカテゴリーの場合は、「はてなブログカスタマイズ」が先頭にあるので、「はてなブログカスタマイズ」を含む階層カテゴリーがパンくずリストに表示されます。

「はてなブログカスタマイズ」を含む最下位までの階層カテゴリーは、「はてなブログカスタマイズ-階層化カテゴリー」、「はてなブログカスタマイズ-パンくずリスト-階層化カテゴリー」の二つです。

「はてなブログカスタマイズ-階層化カテゴリー」が先に置かれているので、パンくずリストには、トップ>はてなブログカスタマイズ>階層化カテゴリー>と表示されます。

ファイルについて

CSSは、それぞれのページに対応する用に独自に設定する必要がある可能性があります。

category.min.jsがカテゴリーを階層化させるためのメインソースファイルになります。jqueryは、カテゴリーの階層化とは直接関係ありませんが、category.min.jsでコードを簡略化するために使用しているので必要です。

JavaScriptファイルの説明
  1. カテゴリーの表示を変える
  2. パンくずリストの階層化表示
    初期Scriptファイルのため、不備などがありあまり参考になりません。

 はてなブログのカスタマイズ設定について

パンくずリスト

パンくずリストの表示を設定していると、その位置に当処理で生成されたパンくずリストが表示されます。

設定していない場合は、記事の上に表示されます。

カテゴリー一覧

階層カテゴリーは最上位カテゴリーを置いた位置に表示されます。最上位カテゴリーを移動させることで階層カテゴリーの表示を移動させることができます。

 

www.it-the-best.com

【はてなブログカスタマイズ】ホーム画面におすすめ記事を表示させる

今回のはてなブログカスタマイズはコチラ

ホーム画面に独自のおすすめ記事を表示させる

 良い記事が書けたけどなかなか発信しきれていない。そんな記事は誰にでもあるとおもいます。そんなときは、ホーム画面だったりでアピールしたりと対策をしましょう。

 

  はてなブログおすすめ記事モジュール

おすすめの記事のURLを入力するだけで、おすすめ記事リストを表示させるモジュールを開発しました。
URLから記事情報を取得するScriptと、モジュール(HTMLコード)をコピペするだけで表示することができます。(jQuery必須)

www.it-the-best.com

 

記事一覧要素(HTML)をコピーする

 サイドバーに表示できる注目記事や最新記事の要素をまねして、おすすめ記事を表示させます。それらの記事の要素の中には、アイキャッチ画像のURLや記事へのリンクURL、ブックマークの数などの情報があります。

コチラの記事は要素取得の仕方が書かれています。

www.it-the-best.com

表示させたい記事に入れ替える

 コピーしたHTMLを、おすすめとして表示させたい記事の情報だけにします。

この時、クラス名などを変更していないとサイドバーように設定されているCSSが適用されてしまう恐れがあります。独自のCSSだけを適用させたい場合はクラス名の変更を行いましょう。

HTML記述欄に記入

 完成したおすすめ記事一覧の要素をHTML記述欄に記入します。

ホーム画面の記事一覧の上(#main-inner中の一番上)に表示させたい場合は、ヘッダのタイトル下に書くことをお勧めします。

このとき、ホーム画面の記事一覧と同じCSS(表示形式)ではないのでdisplay:noneなどで非表示にしておきます。

JavaScriptで要素を操作

 ホーム画面の記事一覧の中にはまだ含まれていないので、JavaScriptで#main-inner内におすすめ記事一覧を移動させます。

var main_inner=document.getElementById("main-inner")

//main-innerの最初の子要素として追加
main_inner.insertBefore(要素, main_inner.firstChild);

 移動させた後、非表示になっている場合は表示させます。

画面別動作

 ホーム画面だけで表示させたい場合は、JavaScriptで処理をさせます。

www.it-the-best.com

 

私は、ホーム画面時は#main-innerの一番最初の子要素、それ以外は最後の子要素として追加させる処理をさせています。

 

それでは、良いプログラミングライフを。

【はてなブログカスタマイズ】注目記事一覧ページを作る方法「リアルタイム」

サイドバーには表示できるけど、注目記事だけの記事を作りたいのにできないという方に役立つであろうはてなブログカスタマイズ情報です。

 

当カスタマイズははてなブログ注目記事モジュールのHTMLコードをコピーして、注目記事一覧を表示させるものですが、環境によっては正常に動作しない可能性があります。

ページに表示したい注目記事の情報を決める

まず、デザイン設定のカスタマイズからサイドバーを選びます。

f:id:Surprisedblog:20191127153207p:plain

次に、モジュール追加で注目記事を選びます。そこで、注目記事一覧の表示設定をします。

f:id:Surprisedblog:20191127153319p:plain

 

スマホのブラウザからの場合は、PC版表示にする必要があります。

はてなブログのダッシュボードからページ下部のPC版をタップします。

 

要素をコピーする

ここからは、PC環境での作業です。開発者ツールが利用できるスマホのブラウザは限られているため、スマホからの場合は、当記事にあるHTMLコードをコピーして注目記事を表示することが可能です。

注目記事モジュールの追加設定が終わり適用したら、そのモジュールのHTMLコードをコピーします。

 

コピーの仕方は、注目記事のうえにカーソルを置き右クリック、または「F12」から開発ツールを開きます。(検証を選択する)

f:id:Surprisedblog:20190924080003p:plain

 

開発ツールからHTMLファイルを見ることができますので、注目記事モジュールをコピーします。WEBページと開発ツールの関係は、ページでハイライトされているものが開発ツールのHTMLの要素にあたります。

f:id:Surprisedblog:20190531223000p:plain

 

開発ツールについて

www.it-the-best.com

 

 

記事または固定ページ(PROのみ)に貼り付ける

注目記事一覧を表示させたいページにコピーしたコードを貼り付けます。

 

箱だけ残して中身を消す

下のコードが注目記事一覧を表示させるための箱のようなものになります。

<div class="hatena-module hatena-module-entries-access-ranking" 
data-count="10" data-source="access" data-enable_customize_format="0" data-display_entry_category="0" 
data-display_entry_image="1" data-display_entry_image_size_width="130" data-display_entry_image_size_height="100" 
data-display_entry_body_length="100" data-display_entry_date="1" data-display_entry_title_length="20" 
data-restrict_entry_title_length="0" data-display_bookmark_count="1">
<div class="hatena-module-body"> </div>
</div>

<div class="hatena-module-body">のなかには<ul>タグで囲まれた注目記事がリストで存在しています。そのリストを消して(<ul>とその中身を消して)上のコードの状態にすればサイドバーのような注目記事一覧を表示させられるはずです。

このコードからでも注目記事を表示させることができます。画像の有無や記事概要の文字数などは、HTML要素のそれぞれのdataの値を変更することで設定を変えることができます。

補足

表示する情報を変える場合は、コピーしたもののなかにdataから始まる文字列がたくさん書かれたdivがあるはずです。そのdataがモジュールの表示設定に当たります。それらの値を変更することで、表示形式を変えることができます。

一部説明

data-display_entry_image="1" 
data-display_entry_image_size_width="130"
data-display_entry_image_size_height="100" data-display_entry_body_length="100"
画像の表示/非表示(1/0)
画像の横幅
画像の縦幅
一覧に表示させる記事本文か概要の文字数

 

 

 

「はてなブログカスタマイズ」 | 「PRO」だけの特典。フッターの要素を変える

 はてなブログの一番下にある本当のフッターは、はてなブログPROでないと簡単にはカスタマイズできません。(下の写真の文字がある部分)

(JavaScriptファイルを別で作成して、読み込ませる方法ではカスタマイズできる。多分)

f:id:Surprisedblog:20190528184045p:plain

 

 はてなブログPROになれば、フッターの非表示ができるため、私はそれを利用してフッターのカスタマイズをしました。

ステップ1

 まず、非表示にする前に開発者ツールを開いて<footer id="footer" ...>の要素をコピーします。開発者ツールの開き方は、クロームの場合右クリックをして検証から開けます。

 コピーしたらフッターを非表示にします。

ステップ2

 自分のブログのデザインのカスタマイズで、フッターを選択します。そこに、コピーしたフッター要素を貼り付けます。

 これで、一番下にあったフッターのカスタマイズができます。
 フッターによくあるコピーライトなどの記入がフッターにできます。

 

フッターのカスタマイズができない理由
  • はてなブログ側でフッターのカスタマイズが用意されていないこと。
  • HTML記述欄でJavaScriptで無理にカスタマイズしようとしても、HTMLが記述できるところがフッターより前に位置しているので、フッター要素の取得ができない。(※おそらくですができません。)
    //追加:2019/5/29
     フッター要素の読み込みが完了した後に処理をさせればできる。
    //
 他の方法

 別で作成したJavaScriptファイルを読み込ませれば、はてなブログPRO関係なくカスタマイズができると思います。ただ、そのファイルはインターネットに公開しなければならないので、サーバーに置くなどしなければいけません。

//訂正:2019/5/29

 別ファイルで作成したところで、ページが読み込まれる前(フッター要素が読み込まれる前)に処理をさせていたらできませんでした。

 今回のフッターをカスタマイズするというお題では、フッターが読み込まれてから処理をさせれば、はてなブログPRO関係なくカスタマイズすることができます。

 ページが読み込まれてから処理を実装する方法(JavaScript)

<script>
window.onload = function() { 
   // ページが読み込まれてから実行したい処理
}
</script>

別ファイルでもはてなブログ側で直接書く方法でも、どちらでもできます。ダメなのは、読み込まれる前に処理をさせるからでした。

もしフッターより下に書ければ、別ファイルでも直接書く方法でも、「読み込みが終わってから」という条件処理をさせなくても、フッターの要素を操作することができます。

//

 

 私は、現在HTML記述欄に直接記入しているのですが、カスタマイズ量が増えると管理が大変になるので別で用意する方がいいのかもしれません。ついでにCSSも。

  

それでは、良いプログラミングライフを。

「はてなブログカスタマイズ」 | 記事内の写真を記事タイトル下に持ってくる

 記事上に何かコンテンツを入れていると、記事内で張り付けた写真を一番上に表示させることができません。

 そこで、記事内の一番上にある写真をタイトル下に持ってくるようにカスタマイズしました。

<script>
        //記事内の一番上の写真
            var entry_top_img=document.getElementsByClassName("hatena-fotolife")[0]
            //記事タイトル
            var entry_title=document.getElementsByClassName("entry-title")[0]
            console.log(entry_top_img.src,entry_title.innerHTML)
            //要素の直後に追加
            entry_title.parentNode.insertBefore(entry_top_img, entry_title.nextSibling);
            //{追加先要素}.parentNode.insertBefore({追加要素}, {追加先要素}.nextSibling);   
</script> 

写真がないときにエラーをはかせないために 、trycatchで囲みます。

<script>
        try {
        //記事内の一番上の写真
            var entry_top_img=document.getElementsByClassName("hatena-fotolife")[0]
            //記事タイトル
            var entry_title=document.getElementsByClassName("entry-title")[0]
            console.log(entry_top_img.src,entry_title.innerHTML)
            //要素の直後に追加
            entry_title.parentNode.insertBefore(entry_top_img, entry_title.nextSibling);
            //{追加先要素}.parentNode.insertBefore({追加要素}, {追加先要素}.nextSibling);   
        } catch (error) {}
    </script>

 

 ここまででは、記事内の一番上の写真をタイトル下に持ってくるので、タイトル下に持っていきたくない写真も動かしてしまいます。

 

そこで、記事内の一番上の要素が写真の場合のみ動かすことにします。

<script>
    var entry_content=document.getElementsByClassName("entry-content")[0]
    var e_c_firstelement=entry_content.firstElementChild
    var e_c_fe_firstelement=e_c_firstelement.firstElementChild
    var flag_entry_content_phototop=false
        try {
            if (e_c_fe_firstelement.tagName=="IMG") {
                flag_entry_content_phototop=!flag_entry_content_phototop
                //記事内トップ要素(写真)
                var entry_top_img=e_c_fe_firstelement
            }
        } catch (error) {}
        if(flag_entry_content_phototop){
                //記事タイトル
                var entry_title=document.getElementsByClassName("entry-title")[0]
                //要素の直後に追加
                entry_title.parentNode.insertBefore(entry_top_img, entry_title.nextSibling);
                //{追加先要素}.parentNode.insertBefore({追加要素}, {追加先要素}.nextSibling);   
        }
</script>

 私の記事編集環境でははてなブログ側が、自動的にPタグで記事を囲むので、記事内の最初の要素を取得してから、写真かを判断します。

このとき、tagnameの返り値は大文字になるので「IMG」と大文字にして比較します。