LoginSignup
2
0

はじめに

これまで大きなZendeskカスタマイズの受託を2件ほど経験してきました。あまりZendeskのカスタマイズについて、個別具体的に解説している記事がないので、我流のカスタマイズで恐縮ですがここに残したいと思います。

「Zendeskとは?」 という方へ

私自身ZendeskのGuide機能しか取り扱っていないのですが、ざっくり説明すると「企業のヘルプセンターがノーコード(カスタマイズ等を実施する場合はローコード) で構築できるよ!」というSaaSです。もっと詳しく知りたい方はこちらを読んでみてください。

Zendeskで目次機能を実装する

最終的に目指している状態

記事内の任意の場所に<Toc/>と記述することで、記事内のヘッダー要素を取得して下記のような目次を作成する。(前提としてjQueryを使用しています。)変数名の前に「$」を付けることで、その変数がjQueryオブジェクトを格納していることを明示しています。

記事の状態

記事内の任意の場所に<Toc/>と記述してみた

image.png

記事のソースコードのようす

image.png

画面描写の様子

image.png

実際のソースコード解説

記事中の<Toc/>を取得して、HTMLタグに変換する

<Toc/>のままだと何も変換されないので、まずHTMLタグに変換します。

$('p:contains("<Toc/>")').replaceWith('<div id="toc"></div>');

.article-body中のヘッダー要素を取得する

h6タグくらいまでのヘッダー要素を取得します。

var $headers = $('.article-body').find('h1, h2, h3, h4, h5, h6');

目次のベースとなるリスト要素を準備する

ヘッダー要素が複数確認できた場合にベースのHTML要素を設置します。
これらの処理は$(document).ready(function () {})内に設置します。

if ($headers.length > 1) {
    var $toc = $('<div class="toc">');
    var $firstUl = $('<ul>');
    var $currentUl = $firstUl;
    var previous_level = 1;
    $firstUl.appendTo($toc);
    $('#toc').append($toc);
    insertHeadings($headers);
}

ヘッダー要素を繰り返しチェックしてネストさせていく

insertHeadingsではヘッダー要素をネストさせています。

function insertHeadings(headers) {
    headers.each(function(index, heading) {
        var $heading = $(heading);
        var current_level = headingLevel(heading);
        if (current_level === 1) {
            newLi($heading, $firstUl);
            $currentUl = $firstUl;
        } else if (current_level === previous_level) {
            newLi($heading, $currentUl);
        } else if (current_level > previous_level) {
            nestUl();
            newLi($heading, $currentUl);
        } else {
            while (current_level < previous_level) {
                $currentUl = $currentUl.parent().closest('ul');
                previous_level--;
            }
            newLi($heading, $currentUl);
        }
        previous_level = current_level;
    });
}

nestUlでは追加のulタグを設置しています。

function nestUl() {
    var $newUl = $('<ul>');
    $newUl.appendTo($currentUl);
    $currentUl = $newUl;
}

headingLevelではヘッダーに対応する番号をリターンしています。

function headingLevel(heading) {
    switch (heading.nodeName) {
        case 'H1':
            return 1;
        case 'H2':
            return 2;
        case 'H3':
            return 3;
        case 'H4':
            return 4;
        case 'H5':
            return 5;
        case 'H6':
            return 6;
        case 'H7':
            return 7;
        case 'H8':
            return 8;
        case 'H9':
            return 9;
        case 'H10':
            return 10;
        default:
            return 0;
    }
}

newLi では渡された要素をli要素として設置しています。

function newLi(heading, $list) {
    var $heading = $(heading);
    var $wrapper = $('<li></li>');
    var $link = $('<a>').prop('href', '#' + $heading.prop('id'));
    $link.html($heading.text());
    $link.appendTo($wrapper);
    $wrapper.appendTo($list);
}

おわりに

当初は「どうやって実装するんだよ」状態だったんですが、ゴリゴリ実装してみると意外と実現できたので嬉しかったです。このカスタマイズに対して、もっとこうしたほうがいいとかアドバイスがあればよろしくお願いします!

ここまで読んでいただきありがとうございました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0