bounty将在6天内到期。回答此问题可获得+50声望奖励。Nodigap正在寻找来自信誉良好的来源的**答案 *。
我正在用简单的JavaScript为HTML/CSS/js构建一个小而最小的代码编辑器。当你在里面写文本的时候会有一个问题。问题是我没有自由在任何我想写的地方写文本,因为无论我在哪里写/编辑,鼠标指针都会自动转移到第三行,而不是停留在我写的地方。
x1c 0d1x的数据
例如,如果我将鼠标指向编辑器中的某个地方并写一个单词,鼠标指针立即返回到另一行(总是在第三行的开头)。因此,它阻止我在我想写的地方写单词,而单词会写在其他地方。就好像在某些行的某些点上有块阻止你写,我将无法在我想写的地方写。
错误:最初,我认为错误是在HTML中,然后他们指出问题是在applyColor()
函数中,也许是将光标位置设置为文本代码的结尾,我不知道。事实上,如果我删除applyColor()
函数,那么问题就解决了,但结果是文本不再着色。但我需要这段代码(或者类似的东西),因为它是给文本着色的函数的一部分。因此我推断问题出在applyColor()函数上,尽管我不是100%确定。所以这应该是JavaScript的问题:
// CHANGE COLOR
function changeColor() {
var editor = document.getElementById("html");
applyColoring(editor);
// Set cursor position to the end of text
var child = editor.children;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length - 1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
editor.focus();
}
字符串
问题演示:我会在问题发生的时候演示给你看。在每一种情况下,鼠标指针都被带到了其他地方,我将无法在我想要的地方写入。我相信通过解决applyColor()
函数中的unique问题,那么所有的问题都会自动解决,因为它们都依赖于同一个unique问题。
- 如果我试着在第三行
的开头写一个词, - 如果我试图在
</h1>
后面写一个单词, - 如果我尝试编辑
This is a Heading
,它会在<h1>
和This
之间写入一个单词 - 如果我试图在
</p>
x1c4d 1x后面写一个单词, - 如果我以前在第三行写过任何单词(例如aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
但是鼠标指针也可以在其他区域移动(在这3个五线谱内),我没有写过。当然,这一切都源于一个问题
我想要什么?**我希望当我写一个单词时(无论它写在哪里,在任何位置),鼠标指针应该保持静止/停在最后一个写的单词上(例如任何编辑器或聊天工作),并且不应该自动移动到第三行(如上面的照片)。当然,有些单词必须保持颜色(如我的代码中已经发生的那样)。例如,像这样,我想得到这样:
型
当然,如果我在HTML代码编辑器中插入新行,指针不会移动到第三行,而是会移动到第四行、第五行等等。
我怎样才能自由地在任何我想要的地方编写和修改编辑器代码,并避免将指针移动到其他行?那么,applicolor()
函数应该如何修复?
P.S:我想手动设置标签、属性和括号的颜色,所以我不想使用REGEX,但我想使用我已经在使用的代码(或类似的东西)
index.html
<div id="html" contenteditable="true" oninput="showPreview();" onchange="changeColor();"><h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</div>
<h3>PREVIEW</h3>
<div class="preview-area">
<iframe id="preview"></iframe>
</div>
</div>
型
style.css
#html {
width: 456px;
height: 267px;
padding: 10px;
background-color: #444;
color: white;
font-size: 14px;
font-family: monospace;
white-space: pre;
}
.statement {
color: orange;
}
#editor {
}
#preview {
display: block;
width: 100%;
}
型
JavaScript.js
function applyColoring(element) {
var keywords = ["DIV", "SPAN", "H1", "P"];
var keywords2 = ["CLASS", "ID"];
var newHTML = "";
// Loop through words
str = element.innerText;
(chunks = str
.split(new RegExp(keywords.map((w) => `(${w})`).join("|"), "i"))
.filter(Boolean)),
(markup = chunks.reduce((acc, chunk) => {
acc += keywords.includes(chunk.toUpperCase()) ?
`<span class="statement">${chunk}</span>` :
`<span class='other'>${chunk}</span>`;
return acc;
}, ""));
element.innerHTML = markup;
}
// CHANGE COLOR
function changeColor() {
var editor = document.getElementById("html");
applyColoring(editor);
// Set cursor position to the end of text
var child = editor.children;
var range = document.createRange();
var sel = window.getSelection();
range.setStart(child[child.length - 1], 1);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
editor.focus();
}
// PREVIEW
const elHTML = document.querySelector("#html");
//const elCSS = document.querySelector("#css");
//const elJS = document.querySelector("#js");
const elPreview = document.querySelector("#preview");
function showPreview() {
const html = elHTML.textContent;
//const css = `<style>${elCSS.textContent}</style>`;
//const js = `<scr` + `ipt>${elJS.textContent}</scr` + `ipt>`;
const dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(html);
changeColor();
elPreview.src = dataURL;
}
changeColor()
showPreview()
型
1条答案
按热度按时间axkjgtzd1#
您的主要问题在于您正在修改您正在键入的
contenteditable
DIV的内容,通过突然包含任意长度的HTML标记(突出显示SPAN元素)来更改其长度-然后试图猜测在哪里重置插入符号位置/索引。如果我可以提出一个不同的方法:
创建一个可滚动的DIV Package 器
.hilite
。在它里面放置两个DIV:
一个
contenteditable
DIV(让我们将其归类为.hilite-editor
),带有不可见的透明文本,但只有一个可见的插入符号(使用CSScaret-color
)。下面它放置另一个具有相同CSS样式的DIV(
.hilite-colors
),该DIV将纯粹用于显示色彩缤纷的语法<span>
标记突出显示器元素:字符串
这样,您的插入符号将始终在
contenteditable DIV
内,因为你的类型。然后,JS将(使用正则表达式或任何其他适当的方式)使用来自该contenteditable DIV的textContent,并动态创建突出显示的标记,该标记将在每个
"input"
事件的基础DIV.hilite-colors
中结束。上面我创建的正则表达式完全是实验性的。2请随意修改它,并为CSS和JS添加缺少的正则表达式。
创建一个语法分析器和标记化工具会更好。进一步的阅读请参见VSCode syntax highlighting optimization,看看其他人是如何用惊人的解决方案解决这个问题的。
下面是上述代码的一个例子,其中有一个轻微的变化,并实现了https://highlightjs.org/库用于突出显示:Code editor using highlight.js。
另一个库解决方案是:https://ace.c9.io/
关于more examples here