Javascript 更新/删除传播到不同节点的文本
这个标题似乎不那么显而易见,但问题其实很简单。想象一下下面的代码:Javascript 更新/删除传播到不同节点的文本,javascript,Javascript,这个标题似乎不那么显而易见,但问题其实很简单。想象一下下面的代码: <div class="line"> Some text node here. <span>Some nodeType 3 here.</span> More text here. <span>And here as well.</span> </div> 结果是: function deleteContent(from, to) {
<div class="line">
Some text node here. <span>Some nodeType 3 here.</span>
More text here. <span>And here as well.</span>
</div>
结果是:
function deleteContent(from, to) {
// Some code to execute here
}
<div class="line">
Some text node here. <span>Some nodeType</span>
</div>
这里有一些文本节点。一些节点类型
因此,从理论上讲,它基本上就像使用slice
函数div.innerHTML.slice(from,to)
,只是这只在div中没有标记的情况下才有效。我已经考虑过创建一个文本范围并使用deleteContent删除内容,但我不知道这是否是最简单的方法。你有什么建议
附言:我希望有一个整洁、合乎逻辑的代码
编辑
作为对Felix的回应:是的,我把from和to看作两个整数。对于空格,在我的应用程序中,我必须分别理解每个空格。也就是说,
是两个字符。我正在为我的库做这件事,我几乎准备好发布它了。同时,您可以使用类似于以下的方法,这在大多数情况下都适用,但也有缺点:
- 在IE<9中不起作用
- 不考虑块元素和
s的隐式换行符 - 不要忽略不可见的文本,例如
和
元素的内容或CSS显示设置为
无的元素内部的文本
- 不会像在呈现页面上那样折叠空间
- 其他微妙之处
函数createRangeFromCharacteristics(containerEl、start、end){
var charIndex=0,range=document.createRange(),foundStart=false,stop={};
range.setStart(containerell,0);
范围。塌陷(真);
函数traverseTextNodes(节点){
if(node.nodeType==3){
var nextCharIndex=charIndex+node.length;
如果(!foundStart&&start>=charIndex&&start=charIndex&&endfrom
和two
是数字吗?如何处理更多文本之前的空格。
或此处的某个文本节点。
?折叠为一个,就像HTML正在做的那样?能否给出一个实际输入和预期输出的具体示例?@FelixKling我已经编辑了这个问题。我实际上不是指
(尽管知道这一点也很好)。我的意思是,如果你的文本中包含例如foo\uuuuuuuuuuu bar
(是一个空格)HTML将显示它为“代码>FooWixBar < /代码>。你是否考虑所有的空白区域?”菲利克斯克:是的,我会把它当作FooySuthBar感谢提姆。显然使用范围是最好的去处。@ SavasVedova:是的,我绝对同意。@ TimPress有没有考虑到断线的更新?Thanks@RafaelDiaz:这是短信Rangy 1.3中的ge模块,我仍在修复错误,但基本上可以正常工作。演示:@RafaelDiaz:我还打算链接到文档:。特别是,请参见范围方法selectCharacters()
和toCharacterRange()
。演示使用基于选择的版本。
function createRangeFromCharacterIndices(containerEl, start, end) {
var charIndex = 0, range = document.createRange(), foundStart = false, stop = {};
range.setStart(containerEl, 0);
range.collapse(true);
function traverseTextNodes(node) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && start >= charIndex && start <= nextCharIndex) {
range.setStart(node, start - charIndex);
foundStart = true;
}
if (foundStart && end >= charIndex && end <= nextCharIndex) {
range.setEnd(node, end - charIndex);
throw stop;
}
charIndex = nextCharIndex;
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
traverseTextNodes(node.childNodes[i]);
}
}
}
try {
traverseTextNodes(containerEl);
} catch (ex) {
if (ex == stop) {
return range;
} else {
throw ex;
}
}
}
function deleteBetweenCharacterIndices(el, from, to) {
var range = createRangeFromCharacterIndices(el, from, to);
range.deleteContents();
}