1

我如何使用一个或多个网络工作者在我的网站上突出显示多个小的源代码块?

4

3 回答 3

1

使用一位网络工作者的示例

要仅使用一个 webworker 来突出显示多个代码块,您可以使用以下代码,其中highlight_code_worker_function是 worker 函数。

<script>

    function highlight_code() {
        if (typeof (Worker) === undefined) return false;
        var workerFunction = new Blob(['(' + highlight_code_worker_function.toString() + ')()'], {type: "text/javascript"});
        var worker = new Worker(URL.createObjectURL(workerFunction));
        var codeBlocks = $('div.readme pre, div.readme code');
        worker.onmessage = function(event) {
            var data = JSON.parse(event.data);
            codeBlocks.eq(data.index).html(data.result).addClass('hljs');
        };
        worker.onerror = function() {
            // do nothing
        };
        codeBlocks.each(function(index) {
            worker.postMessage(JSON.stringify({index: index, code: $(this).text()}));
        });
        worker.postMessage(JSON.stringify({index: -1}));
    }

    function highlight_code_worker_function() {
        onmessage = function(event) {
            var data = JSON.parse(event.data);
            if (data.index === -1) {
                close(); // close worker
            }
            importScripts(''https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/highlight.min.js'');
            self.hljs.configure({tabReplace:4});
            var result = self.hljs.highlightAuto(data.code);
            postMessage(JSON.stringify({result: result.value, index: data.index}));
        }
    }

    highlight_code();

    </script>

使用多个网络工作者的示例

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/styles/monokai_sublime.min.css">

    <script type="text/javascript">

      function highlight_code()
      {
        if (typeof (Worker) === undefined) return false;
        var workerFunction = new Blob(['(' + highlight_code_worker_function.toString() + ')()'], {type: "text/javascript"});
        var localWorkerURL = URL.createObjectURL(workerFunction);
        $('div.readme pre, div.readme code').each(function() {
          var code = $(this);
          var worker = new Worker(localWorkerURL);
          worker.onmessage = function(event) { code.html(event.data).addClass('hljs'); }
          worker.postMessage(code.text()); // start worker
        });
      }

      function highlight_code_worker_function()
      {
        onmessage = function(event) {
          importScripts('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.6.0/highlight.min.js');
          self.hljs.configure({tabReplace:4});
          var result = self.hljs.highlightAuto(event.data);
          postMessage(result.value);
          close(); // close worker
        }
      }

      $(window).on('load', highlight_code);

    </script>
于 2016-09-28T13:23:12.210 回答
1

我知道这是一个老问题,但我提出的答案可以帮助任何未来的访客。

您可以在突出显示代码片段之间提供一些延迟,这将提高性能,因为所有工作人员不会同时工作。我个人在我的一个网站中使用了这种方法,我得到了巨大的性能差异。

script.js

const allPres = [...document.querySelectorAll('pre')];
for (let i = 0; i < allPres.length; i++) {
  setTimeout(() => {
    const block = allPres[i];
    var code = block.innerText,
    worker = new Worker('/worker.js');
 
    worker.onmessage = function (event) {
      var result = event.data;
      block.innerHTML = result;
      worker.terminate();
    };
 
    worker.postMessage(code);
  }, i * 500)  // putting just a delay of 500ms will make your website's performance nice than running all them together
}

worker.js

importScripts('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.3.1/highlight.min.js');
 
self.onmessage = function (event) {
    var result = hljs.highlightAuto(event.data);
    postMessage(result.value);
};

在这里一步一步执行。

于 2022-01-14T07:41:17.450 回答
0

官方文档的启发,我找到了一个强大的解决方案(我猜)。

事实上,我创建了 3 个脚本:

  1. worker_functions.js
  2. worker.js
  3. HTML 中的脚本

仅仅是因为我需要动态突出显示代码。这是我的过程:

  1. 用需要的脚本加载页面,在运行脚本之前等待 DOM 加载。
  2. 从数据库中获取一些数据,data-my_attribute在带有eye图标的按钮中插入 XML 内容。
  3. 单击这些按钮将针对模式打开(引导程序 4)
  4. 在模态显示(表示在显示之前),从按钮获取 xml 数据以将其放入我的代码块中。
  5. 在显示的模式上(表示显示,通过向工作人员发送消息来触发突出显示。

编辑:步骤 5 不是必需的,因为jQuery(this).find('#codeblock').html(xml);在开始突出显示过程之前已正确完成。


worker_functions.js

let highlight_worker;

/**
 * Start the worker in order to highlighting code block when triggering
 * @param worker_url - The javascript path of the worker
 */
function start_worker(worker_url) {
    highlight_worker = new Worker(worker_url);
}

/**
 * Start an highlighting process through the worker previously started
 * @param querySelector - The DOM element on which the highlighted content should be returned
 */
function start_highlighting(querySelector) {
    // Callback to insert the highlighted content to the expected element in DOM
    highlight_worker.onmessage = (event) => {
        querySelector.innerHTML = event.data;
    }
    
    // Post the content to be highlighted by the worker
    highlight_worker.postMessage(querySelector.textContent);
}

工人.js

我使用了一个自定义的 highlight.js 包,只包含我想要突出显示的语言。

/**
 * When worker receives a message, import highlight.js then post back the resulting highlight
 * @param event - The content to be highlighted
 */
onmessage = function (event) {
    importScripts('highlight.pack.js');
    var result = self.hljs.highlightAuto(event.data);
    postMessage(result.value);
}

HTML 中的脚本 - Django 模板

我导入worker_functions脚本,然后添加一个触发窗口加载的事件侦听器,启动工作程序,并触发模态事件的突出显示。

{% block scripts %}
    <script src="{% static 'device/js/highlight/worker_functions.js' %}"></script>
    <script type="text/javascript">
        window.addEventListener("load", function (event) {
            start_worker("{% static 'device/js/highlight/worker.js' %}");
            $('#mifContentModal').on('show.bs.modal', function (e) {
                // let xml = '<p class="text-break">' + e.relatedTarget.dataset.mif_content + '</p>'; // Before decompress
                let xml = '<xmp>' + e.relatedTarget.dataset.mif_content + '</xmp>';
                console.log(jQuery(this).find('#codeblock'));
                jQuery(this).find('#codeblock').html(xml);
                start_highlighting(codeblock); // It can be done right after adding the code in DOM
            })
            //$('#mifContentModal').on('shown.bs.modal', function (e) {
            //    let codeblock = document.getElementById("codeblock");
            //    start_highlighting(codeblock);
            //    // Then remove the xmp tag
            //    codeblock.innerHTML = jQuery(this).find('xmp').html();
            //})
        });
    </script>
{% endblock %}

然后我可以随时使用单个工作人员进行突出显示。

于 2020-11-19T15:08:47.713 回答