Highlight.js применяется к шаблону knockoutjs

У меня есть веб-страница, которая использует highlight.js в этом случае:

<link rel="stylesheet" href="http://yandex.st/highlightjs/8.0/styles/vs.min.css">
<script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

Используя Knockoutjs, мне нужно связать некоторые шаблоны скриптов, как это:

<section>
   <div data-bind="with: selectedTable">
       <div data-bind="template: { name: 'plugin-template' }"></div>
   </div>
</section>

<script type="text/html" id="plugin-template">
   <div id="plugin-view-content" data-bind="with: selectedPlugin, visible: selectedPlugin">
      <pre><code><p data-bind="text: code"></p></code></pre>
   </div>
</script>

Моя проблема в том, что когда шаблон отображается, текст не выделяется. В чем дело?

1 ответ

Решение

В документации по highlight.js довольно четко указано, что вам нужно делать, если вы хотите выделить текст, который добавляется динамически. Это указано под заголовком Custom Initialization на http://highlightjs.org/usage/.

В нем говорится, что вы должны позвонить hljs.highlightBlock функция, передавая элемент, который содержит код, который вы хотите выделить.

В мире KnockoutJS вам, вероятно, следует создать bindingHandler, который изменяет текст вашего поля, а затем вызывает метод highlight.js, который правильно выделяет текст. Простая версия такого bindingHandler может выглядеть примерно так:

ko.bindingHandlers.highlightedCode = {
    update: function(element, valueAccessor){
        var code = ko.unwrap(valueAccessor());
        element.innerText = code;
        hljs.highlightBlock(element);
    }
};

Учитывая следующий вид модели установки:

function ViewModel(code){
    var self = this;

    self.code = ko.observable(code);
}

var viewModel = new ViewModel('public static void Main()\n{\n    var name = Console.ReadLine();\n    Console.WriteLine("Hello " + name + "!");\n}');
ko.applyBindings(viewModel);

Вы можете использовать bindingHandler со следующим HTML:

<pre>
    <code data-bind="highlightedCode: code"></code>
</pre>
<textarea data-bind="value:code" rows="20" cols="100"></textarea>

Я создал jsfiddle, содержащий этот код, на случай, если вы захотите попробовать его вживую. Вы можете найти JSFiddle на http://jsfiddle.net/zY52s/

Другие вопросы по тегам