4

hexo でタブ付きコード ブロックを (タグ プラグインとして) 作成しようとしていますが、js 関数を配置する場所がわかりません。jsヘルパーを使用して関数をロードできると思っていましたが、ヘルパーをどこに含めるかわかりません。タグプラグインに追加しようとしましたが、失敗しました。これはタグ プラグイン コードです ( testtag.jsとして保存されます)。

hexo.extend.tag.register('testtag', function(args, content){
  var className =  args.join(' ');

  var result = '';
  result += "<\%- js('\\themes\\bootstrap-blog\\scripts\\tab.js') \%>"
  result += '<div class="tabs">';
  result += '<ul>';
  result += '<li class="li_tab1" onclick="tab(&apos;tab1&apos;)"><a>Tab 1</a></li>';
  result += '<li class="li_tab2" onclick="tab(&apos;tab2&apos;)"><a>Tab 2</a></li>';
  result += '</ul>';
  result += '<div class="contentarea">';
  result += '<div id="tab1">';
  result += '<p>' + content + '</p>';
  result += '</div>';
  result += '<div id="tab2" style="display: none;">'
  result += '<p>This is the text for tab 2.</p>'
  result += '</div>'
  result += '</div>'
  result += '</div>'

  return result;

}, {ends: true});

これは機能します。tabただし、タグの onclick イベントは、関数が見つからないというエラーを発生させるだけです。上記の最初の行はresult、ヘルパーを使用しようとして失敗したことに注意してください。

これは私のtab関数、tab.jsです:

function tab(tab) {
document.getElementById('tab1').style.display = 'none';
document.getElementById('tab2').style.display = 'none';
document.getElementById('li_tab1').setAttribute("class", "");
document.getElementById('li_tab2').setAttribute("class", "");
document.getElementById(tab).style.display = 'block';
document.getElementById('li_'+tab).setAttribute("class", "active");
}

*\themes\bootstrap-blog\scripts* フォルダーに保存されているtab.jstesttag.jsの両方。

この回答を見ましたが、役立つかもしれませんが、ビューが何であるかわかりません。Hexo docs のビューについては何も見つかりませんでした。

4

2 に答える 2

9

あなたのコードには間違いが多すぎるので、説明付きで完全な例を示したいと思います。

必要なものは次のとおりです。

  1. この複数のコードブロックの HTML 構造を構築するためのカスタム タグ
  2. コード ブロックとコードの配色をスタイル化する CSS ファイル
  3. コードブロック (タブ) をアニメーション化する JS スクリプト

カスタムタグ : m_codeblock(JS サーバー側)

ユーザーが定義できるようにする必要があります。

  • 名前またはリンク
  • このタブには複数のコードブロックがあるため、各タブを区切ってリストするタグを定義しました

構文は次のとおりです。

{% m_codeblock [name] [link] %}
    <!-- tab [lang] -->
        source_code
    <!-- endtab -->
{% endm_codeblock %}

そして例:

{% m_codeblock stack overflow https://example.fr %}
    <!-- tab html -->
        <html>
            <body>
                <h1>Hey dan</h1>
            </body>
        </html>
    <!-- endtab -->
    <!-- tab css -->
        h1 {
            color:red;
        }
    <!-- endtab -->
{% endm_codeblock %}        

これらの依存関係をブログ フォルダー (テーマ フォルダーではありません) にインストールします。

  • 走るnpm install jsdom --save
  • 走るnpm install jquery --save

このカスタム タグのソース コードは次のthemes/theme_name/scripts/m_codeblock.jsとおりです。

'use strict';

var util = require('hexo-util');
var highlight = util.highlight;
var stripIndent = require('strip-indent');
var rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i;
var rCaption = /(\S[\S\s]*)/;
var rTab = /<!--\s*tab (\w*)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;

// create a window with a document to use jQuery library
require("jsdom").env("", function(err, window) {
    if (err) {
        console.error(err);
        return;
    }

    var $ = require("jquery")(window);

    /**
     * Multi code block
     * @param args
     * @param content
     * @returns {string}
     */
    function multiCodeBlock(args, content) {
        var arg = args.join(' ');
        // get blog config
        var config = hexo.config.highlight || {};

        if (!config.enable) {
            return '<pre><code>' + content + '</code></pre>';
        }

        var html;
        var matches = [];
        var match;
        var caption = '';
        var codes = '';

        // extract languages and source codes
        while (match = rTab.exec(content)) {
            matches.push(match[1]);
            matches.push(match[2]);
        }
        // create tabs and tabs content
        for (var i = 0; i < matches.length; i += 2) {
            var lang = matches[i];
            var code = matches[i + 1];
            var $code;
            // trim code
            code = stripIndent(code).trim();
            // add tab
            // active the first tab
            if (i == 0) {
                caption += '<li class="tab active">' + lang + '</li>';
            }
            else {
                caption += '<li class="tab">' + lang + '</li>';
            }
            // highlight code
            code = highlight(code, {
                lang: lang,
                gutter: config.line_number,
                tab: config.tab_replace,
                autoDetect: config.auto_detect
            });
            // used to parse HTML code and ease DOM manipulation
            // display the first code block
            $code = $('<div>').append(code).find('>:first-child');
            if (i == 0) {
                $code.css('display', 'block');
            }
            else {
                $code.css('display', 'none');
            }

            codes += $code.prop('outerHTML');
        }
        // build caption
        caption = '<ul class="tabs">' + caption + '</ul>';
        // add caption title
        if (rCaptionUrl.test(arg)) {
            match = arg.match(rCaptionUrl);
            caption = '<a href="' + match[2] + match[3] + '">' + match[1] + '</a>' + caption;
        }
        else if (rCaption.test(arg)) {
            match = arg.match(rCaption);
            caption = '<span>' + match[1] + '</span>' + caption;
        }
        codes = '<div class="tabs-content">' + codes + '</div>';
        // wrap caption
        caption = '<figcaption>' + caption + '</figcaption>';
        html = '<figure class="highlight multi">' + caption + codes + '</figure>';
        return html;
    }

    /**
     * Multi code block tag
     *
     * Syntax:
     *   {% m_codeblock %}
     *   <!-- tab [lang] -->
     *       content
     *   <!-- endtab -->
     *   {% endm_codeblock %}
     * E.g:
     *   {% m_codeblock %}
     *   <!-- tab js -->
     *       var test = 'test';
     *   <!-- endtab -->
     *   <!-- tab css -->
     *       .btn {
     *           color: red;
     *       }
     *   <!-- endtab -->
     *   {% endm_codeblock %}
     */
    hexo.extend.tag.register('m_codeblock', multiCodeBlock, {ends: true});
});

コメントを読んでコードを理解してください。

JavaScript ファイルをscriptsフォルダーに入れるだけで、Hexo は初期化中にそれらをロードします。

コード ブロックのスタイルを設定する

デフォルトでは、最初のタブのみが表示され、他のタブは非表示になっています。カスタムタグのソースコードでそれを行いました:

$code = $('<div>').append(code).find('>:first-child');
if (i == 0) {
  $code.css('display', 'block');
}
else {
  $code.css('display', 'none');
}

したがって、ユーザー インターフェイスとコードの配色を改善するには、さらに CSS が必要です。このファイルを入れtheme/theme_name/assets/css/style.cssて、レイアウトにリンクします。

コード ブロックをアニメーション化する (JS クライアント側)

タブをアニメーション化するには JavaScript が必要です。タブをクリックすると、すべてのタブの内容が非表示になり、右側のタブのみが表示される必要があります。このスクリプトを入れtheme/theme_name/assets/js/script.jsて、レイアウトにリンクします。

$(document).ready(function() {
  $('.highlight.multi').find('.tab').click(function() {
    var $codeblock = $(this).parent().parent().parent();
    var $tab = $(this);
    // remove `active` css class on all tabs
    $tab.siblings().removeClass('active');
    // add `active` css class on the clicked tab
    $tab.addClass('active');
    // hide all tab contents
    $codeblock.find('.highlight').hide();
    // show only the right one
    $codeblock.find('.highlight.' + $tab.text()).show();
  });  
});

あなたの問題は、このカスタム タグを作成する機会であり、私が開発した hexo テーマ ( Tranquilpeak ) の次のリリースに統合する予定です。

結果は次のとおりです。 結果

JSFiddleでライブをチェック

于 2016-03-02T14:18:18.623 に答える
0

親タグによって読み取られる内部タグを作成することもできます。

{% code_with_tabs %}
  {% code js title="something" class_name="info" %}
    1. aosjaojsdoajsdoajsd
  {% endcode %}
  {% code js title="something" class_name="info" %}
    2. aosjaojsdoajsdoajsd
  {% endcode %}
{% endcode_with_tabs %}

そして、パーサーを使用して、生成された内部 HTML を読み取ります。

于 2016-06-06T08:15:18.993 に答える