HTMLを使用してコードエディタを作成しようとしています。
<!DOCTYPE html>
<html lang='en'>
<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>
Highlighter.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;
}
const char = this.advance();
let color = NORM;
switch (char)
{
// ...
}
return {
color,
text: this.source.substring(this.start, this.curr),
};
},
};
let result = '';
const caret = new Caret(editor);
const save = caret.getPos();
for (;;)
{
const lexeme = Highlighter.scan();
if (lexeme === null)
{
break;
}
const chars = lexeme.text.split('').map(
x => `<span style='color: ${lexeme.color};'>${x}</span>`);
result += chars.join('');
}
editor.innerHTML = result;
caret.setPos(save);
};
基本的に、ユーザーのコードのテキストコンテンツを取得し、それをスキャンして色データを含む語彙素を生成し、それらの語彙素を文字に分割して、色付きのタグに入れ、それらのを文字列に追加します。エディターのinnerHTMLがに更新され、最後にユーザーのカーソルが適切な位置に戻されます。これは入力時に行われます。ただし、問題が1つあります。ユーザーの入力が速すぎると、入力したテキストが2倍になる可能性があります。私は他のタイプのイベントリスナーでこれを修正しようとし、setIntervalを使用してみましたが、まったくうまくいきませんでした。
あなたが説明したことから
計算コストが高いことを確認します
highlight()
関数は、への変更ごとに呼び出されますinput
素子私は提案しますデバウンスハイライトするためのその呼び出し。これがデバウンスの良い説明です。
次のようなものを試してください。