#svelte
Вопрос:
Я пытаюсь добавить чрезвычайно простую «подсветку синтаксиса» для ввода текста в svelte.
В принципе, я хочу выделить все во входных данных, которые соответствуют регулярному /{.*?}/
выражению, другим цветом, но я не могу понять, как это сделать.
мой последний эксперимент выглядит так
<script>
export let value;
let editor;
function update() {
value = editor.textContent
}
</script>
<div contenteditable="true"
bind:this={editor} on:input={update}>
{#if value}
{#each value.split(" ") as part, i}
<span class={part.match(/{.*?}/gm) ? "text-nord-12" : "text-nord-4"}
>{#if i !== 0}amp;nbsp;{/if}{part}</span
>
{/each}
{/if}
</div>
и хотя это не идеально, это вроде как работает, за исключением того, что курсор время от времени сбрасывается при редактировании, что, я полагаю, связано с тем, что содержимое редактора заменяется при обновлении.
Итак, в принципе, есть ли какой-либо способ привязать текстовое значение, сохраняя при этом возможность динамического добавления/удаления html-тегов?
Я также могу отметить, что привязка textContent
, похоже, работает либо потому, что она удаляет все выделения при монтировании… либо я просто делаю что-то не так с привязкой
Комментарии:
1. Вы можете использовать html.replace(rex, replacerFunc) для замены совпадений rex с помощью функции замены. Эта функция замены может изменить ваше соответствие в чем-то вроде <mark class=»highlicht»>{сопоставленный текст}<mark class=»highlicht»></mark> Подробнее здесь: </mark> developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Ответ №1:
Решит ли это вашу проблему с помощью use:action, on:blur и заменителя?
При размытии вам нужно оставить (потерять фокус) div, чтобы отметить текст div, но курсор не будет прыгать при каждом нажатии клавиши.
Код и повторение: Выделите соответствующий текст в удобном для просмотра div с помощью svelte
<script>
let match = "svelte|input"; // pseudo rex
let content = "Adding syntax highlight to an input in svelte using a svelte action";
let editor;
function updateContent() {
if (editor) content = editor.textContent;
}
function marker(txt, rex) {
function markTerm(term) {
let cls = "red";
return ` <mark class="no-clicks ${cls}">${term}</mark> `;
}
return txt.replace(rex, (term) => markTerm(term));
}
export function highlight(node, [val, text]) {
function action() {
console.log(text);
if (text) node.innerHTML = marker(text, new RegExp(val, "g"));
}
action();
return {
update(obj) {
[val, text] = obj;
action();
}
};
}
</script>
<div>
<div contenteditable="true" use:highlight={[match, content]}
bind:this={editor} on:blur={updateContent} />
</div>
<style>
:global(.red) {
color: red;
}
</style>