Javascript content可编辑的标签环绕元素;can';t将光标从新包围的选择中取出

Javascript content可编辑的标签环绕元素;can';t将光标从新包围的选择中取出,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我有一个div,它在我的学校项目网站上被用作用户友好的文本编辑器。但是,如果我选择编辑器中的所有文本,并试图用标记将其包围,我无法将光标从编辑器中取出,它会继续将我键入的内容添加到同一标记中,即 过了一段时间,我放弃了它,但后来我找到了答案,并试图修改这里提到的JSFIDLE,希望它能够正常工作。但是没有运气 比如说,如果我在任何一行中选择最后一个单词并用标记将其包围,我就能够将光标从没有包围的文本中取出,但最后没有可跳转的纯文本,因此光标被卡在 如何确保光标不会卡在添加的标记中? 也许可以把光

我有一个div,它在我的学校项目网站上被用作用户友好的文本编辑器。但是,如果我选择编辑器中的所有文本,并试图用
标记将其包围,我无法将光标从编辑器中取出,它会继续将我键入的内容添加到同一标记中,即

过了一段时间,我放弃了它,但后来我找到了答案,并试图修改这里提到的JSFIDLE,希望它能够正常工作。但是没有运气

比如说,如果我在任何一行中选择最后一个单词并用
标记将其包围,我就能够将光标从没有包围的文本中取出,但最后没有可跳转的纯文本,因此光标被卡在

如何确保光标不会卡在添加的标记中? 也许可以把光标移出它

函数环绕选择(){
var代码=document.createElement(“代码”);
code.style.fontStyle=“斜体”;
code.style.color=“#333”;
code.style.background=“#ddd”;
if(window.getSelection){
var sel=window.getSelection();
如果(选择范围计数){
var range=sel.getRangeAt(0.cloneRange();
范围。周围内容(代码);
选择removeAllRanges();
选择添加范围(范围);
}
}
}
div,输入{
填充:10px;
}
div{border:1px solid;}


一二三四
这里有点古怪。不再使用环绕,而是将内容复制到新节点中。然后在末尾添加一个空格。现在,即使选择了所有文本,也可以在代码块后单击

编辑:添加了sel.collapseToEnd();根据评论(谢谢)。它通过将用户直接放入正常的键入上下文来改善体验。然而,空间仍然是必需的,没有它就无法工作

编辑:现在向起点和终点添加空间

编辑:删除发送到服务器的间隔符

函数环绕选择(){
让代码=document.createElement(“代码”);
code.style.fontStyle=“斜体”;
code.style.color=“#333”;
code.style.background=“#ddd”;
const newSpan=()=>{
设span=document.createElement('span');
span.classList.add('codespacker');
span.innerHTML='';
返回跨度;
}
if(window.getSelection){
让sel=window.getSelection();
如果(选择范围计数){
让range=sel.getRangeAt(0.cloneRange();
code.innerHTML=range.toString();
range.deleteContents();
range.insertNode(newSpan());
range.insertNode(代码);
range.insertNode(newSpan());
选择removeAllRanges();
选择添加范围(范围);
选择折叠结束();
}
}
}
函数getContentForSave(){
让codeSection=document.querySelector(“#codeSection”);
//复制到临时元素中(否则文本将在UI中更改)
让tempSection=document.createElement('div');
tempSection.innerHTML=codeSection.innerHTML;
log(`Before:${tempSection.innerHTML}`);
//拆下所有代码间隔垫圈
让间隔符=tempSection.querySelectorAll('.codespacer');
用于(让隔套的间距){
tempSection.removeChild(空间);
}
log(`After:${tempSection.innerHTML}`);
返回tempSection.innerHTML;
}
div,
输入{
填充:10px;
}
div{
边框:1px实心;
}

一二三四

这里有点古怪。不再使用环绕,而是将内容复制到新节点中。然后在末尾添加一个空格。现在,即使选择了所有文本,也可以在代码块后单击

编辑:添加了sel.collapseToEnd();根据评论(谢谢)。它通过将用户直接放入正常的键入上下文来改善体验。然而,空间仍然是必需的,没有它就无法工作

编辑:现在向起点和终点添加空间

编辑:删除发送到服务器的间隔符

函数环绕选择(){
让代码=document.createElement(“代码”);
code.style.fontStyle=“斜体”;
code.style.color=“#333”;
code.style.background=“#ddd”;
const newSpan=()=>{
设span=document.createElement('span');
span.classList.add('codespacker');
span.innerHTML='';
返回跨度;
}
if(window.getSelection){
让sel=window.getSelection();
如果(选择范围计数){
让range=sel.getRangeAt(0.cloneRange();
code.innerHTML=range.toString();
range.deleteContents();
range.insertNode(newSpan());
range.insertNode(代码);
range.insertNode(newSpan());
选择removeAllRanges();
选择添加范围(范围);
选择折叠结束();
}
}
}
函数getContentForSave(){
让codeSection=document.querySelector(“#codeSection”);
//复制到临时元素中(否则文本将在UI中更改)
让tempSection=document.createElement('div');
tempSection.innerHTML=codeSection.innerHTML;
log(`Before:${tempSection.innerHTML}`);
//拆下所有代码间隔垫圈
让间隔符=tempSection.querySelectorAll('.codespacer');
用于(让隔套的间距){
tempSection.removeChild(空间);
}
log(`After:${tempSection.innerHTML}`);
返回tempSection.innerHTML;
}
div,
输入{
填充:10px;
}
div{
边框:1px实心;
}

一二三四

我认为一种解决方法是在代码后面添加一个空白
textNode
,然后将光标移动到它的位置。这样,用户可以立即继续编写正常文本

以下是细分:

  • 使用
    document.createTextNode('\u00A0')
    创建包含空格字符的textNode。注意,在我的浏览器(Chrome 70)上,文字
    '
    不起作用<
    + function addPad() {
    +   var $input = document.querySelector('div');
    +   var pad = document.createTextNode('\u00A0');
    +   $input.appendChild(pad);
    +   return pad;
    + }
    
      function surroundSelection() {
        var sel = window.getSelection();
        if (!sel || !sel.rangeCount) return;
    
        var code = document.createElement("code");  
        var range = sel.getRangeAt(0).cloneRange();
        range.surroundContents(code);
        sel.removeAllRanges();
        sel.addRange(range);
    
    +   // create empty node + add it to div
    +   var padNode = addPad();
    
    +   // update the current range to include the empty node.
    +   // since we only add 1 space, the `offset` is set to 1.
    +   range.setEnd(padNode, 1);
    
    +   // move the cursor to very end of range
    +   sel.collapseToEnd();
      }