在 contenteditable 中插入一个跨度,然后用户无法在刚插入的跨度之后继续输入
insert a span in a contenteditable, and then user can not continue input after and out the span that just be insert
- 代码目标:当用户按下space,自动输入一个跨度,然后用户可以继续输入,
- 当我在开发工具中跟踪它们时,range.setEnd(lasttextnode, 0);和 range.collapse() 运行 以正确的方式,
- 但是键盘输入不对,我在文本上设置了插入符号,想在span之后插入字符,但是输入出现在刚刚插入的前一个span中。
这是我的代码:
editor.onkeydown = editinput;
var sel = window.getSelection();
function editinput(e) {
var range = sel.getRangeAt(0);
if (e.isComposing || e.keyCode === 229) { //imk
return;
}
if (e.keyCode == 32) { //space
var tnode = range.commonAncestorContainer;
var start = range.startOffset;
var text = tnode.textContent;
var span = document.createElement('span');
span.innerHTML = '------span------';
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, lasttextnode);
tnode.replaceWith(fragment);
range.setEnd(lasttextnode, 0); // here is problem,
range.collapse();
e.stopPropagation(); //bubble
e.preventDefault(); //default.
}
}
[contenteditable=true] {
display: inline-block;
white-space: pre-wrap;
width: 400px;
height: 100%;
}
div, textarea, span {
border: 1px solid rgba(122, 206, 143, 0.966);
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div id="editor" contenteditable="true" class="Weave" tabIndex="1">
samelinesamelinesamelinesamelinesamelinesamelinesame
<span>deerge span</span>oaeueouaoeu <span>disange span</span>
</div>
你可以看到:键盘输入会在刚刚插入的范围内。
但如果我将 range.setEnd(lasttextnode, 0);
更改为 range.setEnd(lasttextnode, 1)
,它将 运行 正确;
我尝试了很多方法:
- range.collapse();
- range.setStart(lasttextnode,0)
- sel.removeAllRanges();
- sel.collapse(lasttextnode,0)
- range.setStart之前(lasttextnode);
- range.setStart之后(跨度);
所有这些都不起作用。只需在 lasttextnode 之前插入一个 space 就可以部分解决问题,但这不是我的目标,我想在跨度之后输入一些内容。
您可以尝试添加另一个节点,只有 space,然后在该节点上设置结束。
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var emptyNode = document.createTextNode(' ');
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, lasttextnode, emptyNode);
tnode.replaceWith(fragment);
range.setEnd(emptyNode, 1);
range.collapse();
https://jsfiddle.net/63s1tgyw/
它将聚焦在跨度之外。这是你想要达到的目标吗?
您可以尝试在跨度和最后一个文本节点之间插入一个空字符(例如 \u200B
)。然后,当您将光标移到最后一个文本节点之前时,它位于 span 标签之外。但记得在将结果插入数据库之前从结果中删除空字符。
editor.onkeydown = editinput;
var sel = window.getSelection();
function editinput(e) {
var range = sel.getRangeAt(0);
if (e.isComposing || e.keyCode === 229) { //imk
return;
}
if (e.keyCode == 32) { //space
var tnode = range.commonAncestorContainer;
var start = range.startOffset;
var text = tnode.textContent;
var span = document.createElement('span');
span.innerHTML = '------span------';
var emptyNode = document.createTextNode('\u200B');
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, emptyNode, lasttextnode);
tnode.replaceWith(fragment);
range.setEnd(lasttextnode, 0); // here is problem,
range.collapse();
e.stopPropagation(); //bubble
e.preventDefault(); //default.
}
}
[contenteditable=true] {
display: inline-block;
white-space: pre-wrap;
width: 400px;
height: 100%;
}
div, textarea, span {
border: 1px solid rgba(122, 206, 143, 0.966);
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div id="editor" contenteditable="true" class="Weave" tabIndex="1">
samelinesamelinesamelinesamelinesamelinesamelinesame
<span>deerge span</span>oaeueouaoeu <span>disange span</span>
</div>
- 代码目标:当用户按下space,自动输入一个跨度,然后用户可以继续输入,
- 当我在开发工具中跟踪它们时,range.setEnd(lasttextnode, 0);和 range.collapse() 运行 以正确的方式,
- 但是键盘输入不对,我在文本上设置了插入符号,想在span之后插入字符,但是输入出现在刚刚插入的前一个span中。
这是我的代码:
editor.onkeydown = editinput;
var sel = window.getSelection();
function editinput(e) {
var range = sel.getRangeAt(0);
if (e.isComposing || e.keyCode === 229) { //imk
return;
}
if (e.keyCode == 32) { //space
var tnode = range.commonAncestorContainer;
var start = range.startOffset;
var text = tnode.textContent;
var span = document.createElement('span');
span.innerHTML = '------span------';
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, lasttextnode);
tnode.replaceWith(fragment);
range.setEnd(lasttextnode, 0); // here is problem,
range.collapse();
e.stopPropagation(); //bubble
e.preventDefault(); //default.
}
}
[contenteditable=true] {
display: inline-block;
white-space: pre-wrap;
width: 400px;
height: 100%;
}
div, textarea, span {
border: 1px solid rgba(122, 206, 143, 0.966);
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div id="editor" contenteditable="true" class="Weave" tabIndex="1">
samelinesamelinesamelinesamelinesamelinesamelinesame
<span>deerge span</span>oaeueouaoeu <span>disange span</span>
</div>
你可以看到:键盘输入会在刚刚插入的范围内。
但如果我将 range.setEnd(lasttextnode, 0);
更改为 range.setEnd(lasttextnode, 1)
,它将 运行 正确;
我尝试了很多方法:
- range.collapse();
- range.setStart(lasttextnode,0)
- sel.removeAllRanges();
- sel.collapse(lasttextnode,0)
- range.setStart之前(lasttextnode);
- range.setStart之后(跨度);
所有这些都不起作用。只需在 lasttextnode 之前插入一个 space 就可以部分解决问题,但这不是我的目标,我想在跨度之后输入一些内容。
您可以尝试添加另一个节点,只有 space,然后在该节点上设置结束。
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var emptyNode = document.createTextNode(' ');
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, lasttextnode, emptyNode);
tnode.replaceWith(fragment);
range.setEnd(emptyNode, 1);
range.collapse();
https://jsfiddle.net/63s1tgyw/
它将聚焦在跨度之外。这是你想要达到的目标吗?
您可以尝试在跨度和最后一个文本节点之间插入一个空字符(例如 \u200B
)。然后,当您将光标移到最后一个文本节点之前时,它位于 span 标签之外。但记得在将结果插入数据库之前从结果中删除空字符。
editor.onkeydown = editinput;
var sel = window.getSelection();
function editinput(e) {
var range = sel.getRangeAt(0);
if (e.isComposing || e.keyCode === 229) { //imk
return;
}
if (e.keyCode == 32) { //space
var tnode = range.commonAncestorContainer;
var start = range.startOffset;
var text = tnode.textContent;
var span = document.createElement('span');
span.innerHTML = '------span------';
var emptyNode = document.createTextNode('\u200B');
var firsttextnode = document.createTextNode(text.substring(0, start));
var lasttextnode = document.createTextNode(text.substring(start));
var fragment = new DocumentFragment();
fragment.append(firsttextnode, span, emptyNode, lasttextnode);
tnode.replaceWith(fragment);
range.setEnd(lasttextnode, 0); // here is problem,
range.collapse();
e.stopPropagation(); //bubble
e.preventDefault(); //default.
}
}
[contenteditable=true] {
display: inline-block;
white-space: pre-wrap;
width: 400px;
height: 100%;
}
div, textarea, span {
border: 1px solid rgba(122, 206, 143, 0.966);
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div id="editor" contenteditable="true" class="Weave" tabIndex="1">
samelinesamelinesamelinesamelinesamelinesamelinesame
<span>deerge span</span>oaeueouaoeu <span>disange span</span>
</div>