可通过标签进行可编辑的环绕元素;无法将光标移出新包围的选择 [英] Contenteditable surround element by tag; can't get cursor out of newly surrounded selection

查看:88
本文介绍了可通过标签进行可编辑的环绕元素;无法将光标移出新包围的选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的学校项目网站上有一个div,它被用作用户友好的文本编辑器.但是,如果我选择了编辑器中的所有文本,并尝试用<code> tags </code>包围它,则无法使光标离开它,它会继续将我键入的任何内容添加到同一标签中,即<code>.

I have a div which is being used as a user-friendly text editor on my school-project website. However if I select all of the text inside the editor and attemp to surround it with <code> tags </code> I can not get the cursor out of it, it keeps adding whatever i type into the same tag, which is <code>.

一段时间后我放弃了,但是后来我找到了答案,并尝试修改了提到那里是为了让它正常工作.但没有运气.

After some time I gave up on it, but then I found this answer and tried to modify the jsfiddle that is mentioned there in the hopes of getting it to work. But no luck.

如果我可以说,选择任意一行中的最后一个单词并用<code>标记将其包围,那么我可以将光标移到没有非环绕文本的地方,但是最后没有明文可以跳到上面,使光标停留在<code>

If I, lets say, select the last word in any line and surround it with <code> tags, I am able to get the cursor out of it where there is non-surrounded text but on the end there's no plaintext to jump onto so the cursor is stuck in <code>

如何确保光标不会卡在添加的标签中? 也许是将光标移出的一种方法?

jsFiddle

How can I make sure that the cursor doesn't get stuck in added tags? maybe a way to move the cursor out of it?

jsFiddle

function surroundSelection() {
    var code = document.createElement("code");
    code.style.fontStyle = "italic";
    code.style.color = "#333";
    code.style.background = "#ddd";
    
    if (window.getSelection) {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var range = sel.getRangeAt(0).cloneRange();
            range.surroundContents(code);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
}

div, input {
  padding:10px; 
  
}

div {border:1px solid;}

<input type="button" onclick="surroundSelection()" value="Surround">
<div contenteditable="true">One two three four</div>

推荐答案

此处有些古怪的解决方法.不再使用环绕声,而是将内容复制到新节点中.然后,我们在末尾添加一个空格.现在,即使选择了所有文本,也可以在代码块之后单击.

A slightly quirky workaround here. No longer using surround but instead copying contents into the new node. We then add a space at the end. It it now possible to click after the code block, even if all text was selected.

添加了sel.collapseToEnd();根据评论(谢谢).通过直接将用户置于正常的键入上下文中,它改善了体验.但是,仍然需要该空间,没有它就无法工作.

Added sel.collapseToEnd(); as per comment (thanks). It improves the experience by putting the user straight into normal typing context. However, the space is still required, it does not work without it.

现在在开始和结束处添加空间.

Now adds space to the start and end.

删除用于发送到服务器的分隔符.

Remove spacers for send to server.

function surroundSelection() {
  let code = document.createElement("code");
  code.style.fontStyle = "italic";
  code.style.color = "#333";
  code.style.background = "#ddd";
  const newSpan = () => {
    let span = document.createElement('span');
    span.classList.add('codespacer');
    span.innerHTML = '&nbsp;';
    return span;
  }

  if (window.getSelection) {
    let sel = window.getSelection();
    if (sel.rangeCount) {
      let range = sel.getRangeAt(0).cloneRange();
      code.innerHTML = range.toString();
      range.deleteContents();
      range.insertNode(newSpan());
      range.insertNode(code);
      range.insertNode(newSpan());
      sel.removeAllRanges();
      sel.addRange(range);
      sel.collapseToEnd();
    }
  }
}


function getContentForSave() {
  let codeSection = document.querySelector('#codeSection');
  // Copy into a temporary element (otherwise the text will change in the UI)
  let tempSection = document.createElement('div');
  tempSection.innerHTML = codeSection.innerHTML;
  console.log(`Before: ${tempSection.innerHTML}`);
  
  // Remove all codespacers 
  let spacers = tempSection.querySelectorAll('.codespacer');
  for(let space of spacers) {
    tempSection.removeChild(space);
  }
  console.log(`After: ${tempSection.innerHTML}`);
  
  return tempSection.innerHTML;
}

div,
input {
  padding: 10px;
}

div {
  border: 1px solid;
}

<input type="button" onclick="surroundSelection()" value="Surround">
<div contenteditable="true" id="codeSection">One two three four</div>
<input type="button" onclick="getContentForSave();" value="Test For Save">

这篇关于可通过标签进行可编辑的环绕元素;无法将光标移出新包围的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆