猿问

语法荧光笔无法更新文本

我正在尝试使用 HTML 制作一个代码编辑器:


<!DOCTYPE html>

<html>

<head>

    <meta charset='UTF-8'>

    <meta http-equiv='X-UA-Compatible' content='IE=Edge'>

    <meta name='viewport' content='width=device-width, initial-scale=1'>

    <link rel='stylesheet' href='style.css'>

</head>


<body>

    <pre id='editor'><code contenteditable='true'></code></pre>

    

    <script type='module'>

        import { highlight } from './highlighter.js';

        import { Caret } from './caret.js';

        (() =>

        {

            const editor = document.querySelector('#editor code');

            const caret = new Caret(editor);

            highlight(editor);

            editor.addEventListener('input', e =>

            {

                highlight(editor);

                e.preventDefault();

            });

            editor.addEventListener('keydown', e =>

            {

                const TAB   = 9;

                const ENTER = 13;

                switch (e.keyCode)

                {

                    // ...

                }

            });

        })();

    </script>

</body>

</html>

荧光笔.js:


import { Caret } from './caret.js';

export function highlight(editor)

{

    // ...

    const NORM = '#E6E6FA';

    // ...

    const Highlighter = {

        source: editor.innerText,

        start: 0,

        curr: 0,

        // ...

        fin()

        {

            return this.curr >= this.source.length;

        },

        advance()

        {

            return this.source[this.curr++];

        },

        // ...

        scan()

        {

            let result = '';

            this.start = this.curr;

            if (this.fin())

            {

                return null;

            }


基本上,它获取用户代码的文本内容,扫描它以生成带有颜色数据的词素,将这些词素拆分为字符,并将其放入带有颜色的 <span> 标签中,然后将这些 <span> 附加到字符串中编辑器的innerHTML更新为,最后用户的光标放回到正确的位置;这是根据输入完成的。但有一个问题:如果用户输入速度太快,他们输入的文本可能会加倍。我尝试使用其他类型的事件侦听器来解决此问题,并尝试简单地使用 setInterval,但效果并不好。


临摹微笑
浏览 191回答 1
1回答

守着一只汪

从你所描述的情况来看如果用户输入太快并看到在元素highlight()的每次更改时都会调用计算量大的函数inputeditor.addEventListener('input', e => {  highlight(editor); // <--  e.preventDefault();});我建议取消该调用以突出显示。尝试这样的事情:// Vanilla debounce: https://gist.github.com/peduarte/7ee475dd0fae1940f857582ecbb9dc5ffunction debounce(func, wait = 100) {  let timeout;  return function(...args) {    clearTimeout(timeout);    timeout = setTimeout(() => {      func.apply(this, args);    }, wait);  };}// ...// adjust delay to find a balance between responsiveness and performanceconst delay = 500; const runHighlight = () => highlight(editor);const debouncedHighlight = debounce(runHighlight, delay);editor.addEventListener('input', e => {  e.preventDefault();  debouncedHighlight();});
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答