文本高亮 - 内容可编辑

3
我一直在使用JavaScript中的contenteditable字段进行实验。你可能已经猜到了,我正在尝试构建一个所见即所得的编辑器。通过拼凑我在Stack Overflow上找到的答案,我成功地构建了这个测试用例。测试用例的工作是手动和编程高亮文本并加粗它。只有一个小问题。如果你点击“加粗”按钮一次,一个子字符串就会被高亮显示,随后变成加粗字体。然而,如果你再次点击它,它会提示一个错误:
"Error: Failed to execute 'setStart' on 'Range': There is no child at offset 12.
at Error (native)
at HTMLInputElement.<anonymous> (http://run.jsbin.io/runner:15:13)
at HTMLDocument.oa (http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js:18:373)
at HTMLDocument.c.event.handle (http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js:55:307)
at HTMLDocument.j.handle.o (http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js:49:363)"

第一次按下按钮后,代表所见即所得编辑器内容的文本字段包含以下内容:
Some text he<span style="font-weight: bold;">re for y</span>ou to bold

通过测试(输出第一个子元素的长度),我的假设是它只试图突出显示第一部分 -“Some text he”。进一步测试,包括注释掉语句以加粗选择,确认了这一点,我相信。事实上,当这个被注释掉时,编辑器就可以正常工作。
我在Google和Stack Exchange上搜索过,但由于我不知道为什么会发生这种情况,所以什么也没找到。
因此,我的问题是 - 为什么会出现这个错误,我该怎么做才能避免它,并达到编程上突出和加粗这段文字的目标?

你为什么要给 range.setStartrange.setEnd 固定的数字偏移量? - mattsven
仅仅是为了手动突出显示由这些值包围的部分。仅供实验/学习目的。 - MemoNick
1个回答

0

关于您链接的演示代码,您正在使用以下代码设置范围:

range.setStart(mainDiv.firstChild, 12);
range.setEnd(mainDiv.firstChild, 20);

但是mainDiv.firstChild是主div的第一个文本节点。在初始运行时,该文本节点为

Some text here for you to bold

在第一次运行后,该文本节点被分成三个部分:粗体之前的1个,粗体内部的一个以及粗体之后的一个。
Some text he<span style="font-weight: bold;">re for y</span>ou to bold

所以你的mainDiv.firstChild变成了

Some text he

因此,对range.setEnd(mainDiv.firstChild, 20)的调用超出了范围。

为了避免这种情况,不要硬编码您对setRange的调用。相反,直接从用户选择(非常常见的情况)或在进行调用之前检查实际DOM后获取您的范围。


setEnd 不是问题,setStart 才是问题。 - Grim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接