Javascript 使用contenteditable div获取并设置光标位置

Javascript 使用contenteditable div获取并设置光标位置,javascript,jquery,html,Javascript,Jquery,Html,我有一个contenteditable div,我希望能够让用户插入链接、图像或YouTube视频等内容。目前,这就是我所拥有的: 函数addLink(){ var link=$('#url').val(); $(“#编辑器”).focus(); document.execCommand('createLink',false,link); } 提交现场有大量相关信息。这个对我和我的客户都有效 函数setCaret(行,列){ var ele=document.getElementByI

我有一个contenteditable div,我希望能够让用户插入链接、图像或YouTube视频等内容。目前,这就是我所拥有的:

函数addLink(){
var link=$('#url').val();
$(“#编辑器”).focus();
document.execCommand('createLink',false,link);
}


提交
现场有大量相关信息。这个对我和我的客户都有效

函数setCaret(行,列){
var ele=document.getElementById(“可编辑”);
var rng=document.createRange();
var sel=window.getSelection();
rng.setStart(元素子节点[行],列);
rng.崩溃(真);
选择removeAllRanges();
选择添加范围(rng);
ele.focus();
}
//https://stackoverflow.com/a/6249440/2813224
变量行=document.getElementById('ln')。值;
var col=document.getElementById('cl')。值;
var btn=document.getElementById('btn');
btn.addEventListener('click',函数(事件){
var lineSet=parseInt(第10行);
var colSet=parseInt(col,10);
setCaret(行集、列集);
},对)


文本
文本
文本

集中
我试图找到一个解决方案

只要一点帮助,它就可以变得完美。 这是我在SO上找到的答案和我的经验的结合

这很棘手,很混乱。。。但如果必须,您可以使用它,但它需要一些工作来支持内部链接(如果光标位于锚点上,它将在锚点内创建锚点)

以下是JS:

var lastPos;
var curNode = 0;
function setCaret() {
  curNode=0;
  var el = document.getElementById("editor");
  var range = document.createRange();
  var sel = window.getSelection();

  console.log(el.childNodes);
  if (el.childNodes.length > 0) {
      while (lastPos > el.childNodes[curNode].childNodes[0].textContent.length) {
      lastPos = lastPos - el.childNodes[curNode].childNodes[0].textContent.length;
      curNode++;

      }
      range.setStart(el.childNodes[curNode].childNodes[0], lastPos);
      range.collapse(true);
      sel.removeAllRanges();
      sel.addRange(range);
  }
  el.focus();
};


function savePos() {
  lastPos = getCaretCharacterOffsetWithin(document.getElementById('editor'));
}

function addLink() {
  console.log(lastPos);

  setCaret();
  console.log(getCaretCharacterOffsetWithin(document.getElementById('editor')));

  console.log('focus');

  // $("#editor").focus();
  var link = $('#url').val();
  document.execCommand('createLink', false, link);

}

function getCaretCharacterOffsetWithin(element) {
  var caretOffset = 0;
  var doc = element.ownerDocument || element.document;
  var win = doc.defaultView || doc.parentWindow;
  var sel;
  if (typeof win.getSelection != "undefined") {
    sel = win.getSelection();
    if (sel.rangeCount > 0) {
      var range = win.getSelection().getRangeAt(0);
      var preCaretRange = range.cloneRange();
      preCaretRange.selectNodeContents(element);
      preCaretRange.setEnd(range.endContainer, range.endOffset);
      caretOffset = preCaretRange.toString().length;
    }
  } else if ((sel = doc.selection) && sel.type != "Control") {
    var textRange = sel.createRange();
    var preCaretTextRange = doc.body.createTextRange();
    preCaretTextRange.moveToElementText(element);
    preCaretTextRange.setEndPoint("EndToEnd", textRange);
    caretOffset = preCaretTextRange.text.length;
  }
  return caretOffset;
}

一个好的富文本编辑器是目前最难做的事情之一,而且它本身就是一个项目(不友好的API、大量的角点情况、跨浏览器差异等等)。我强烈建议您尝试并找到现有的解决方案

可以使用的一些库包括:

  • 羽毛笔()
  • WYSGIHTML()
  • 代码镜像库()

这就是您在赏金中所要求的:在以下示例中,您可以看到如何检测您单击鼠标的实际点的确切字符数:

   <!-- Text Editor -->
   <div id="editor" class="divClass" contenteditable="true">type here some text</div>


    <script>



   document.getElementById("editor").addEventListener("mouseup", function(key) {

alert(getCaretCharacterOffsetWithin(document.getElementById("editor")));

}, false);


 function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
    sel = win.getSelection();
    if (sel.rangeCount > 0) {
        var range = win.getSelection().getRangeAt(0);
        var preCaretRange = range.cloneRange();
        preCaretRange.selectNodeContents(element);
        preCaretRange.setEnd(range.endContainer, range.endOffset);
        caretOffset = preCaretRange.toString().length;
    }
} else if ( (sel = doc.selection) && sel.type != "Control") {
    var textRange = sel.createRange();
    var preCaretTextRange = doc.body.createTextRange();
    preCaretTextRange.moveToElementText(element);
    preCaretTextRange.setEndPoint("EndToEnd", textRange);
    caretOffset = preCaretTextRange.text.length;
 }
 return caretOffset;
}
 </script>

在这里键入一些文本
document.getElementById(“编辑器”).addEventListener(“鼠标”,函数(键){
警报(getCaretCharacterOffsetWithin(document.getElementById(“编辑器”)));
},假);
函数getCaretCharacterOffsetWithin(元素){
var caretofset=0;
var doc=element.ownerDocument | | element.document;
var win=doc.defaultView | | doc.parentWindow;
var-sel;
if(typeof win.getSelection!=“未定义”){
sel=win.getSelection();
如果(选择范围计数>0){
var range=win.getSelection().getRangeAt(0);
var precretange=range.cloneRange();
预重排列。选择节点内容(元素);
precretange.setEnd(range.endContainer,range.endOffset);
CareTofset=precretange.toString().length;
}
}如果((选择=文件选择)&&sel.type!=“控制”){
var textRange=sel.createRange();
var precarteTextRange=doc.body.createTextRange();
PrecretTextRange.moveToElementText(元素);
setEndPoint(“EndToEnd”,textRange);
CareTofset=PrecretTextRange.text.length;
}
返回caretofset;
}

您链接的解决方案确实有一个适用于所有浏览器的解决方案,只需阅读超出公认的解决方案即可。至于获取光标位置,请尝试以下操作:@SunKnight0我尝试了您提供的解决方案中的以下代码,但它始终返回0
console.log(getCaretCharacterOffsetWithin(编辑器))
我使用了这个答案中的函数Use
getElementById('editor')
。您将普通JavaScript与JQuery混合使用。@SunKnight0抱歉,这是评论中的一个错误。即使使用
getElementById('editor')
插入符号位置也是0。感谢您的回答,但是我想要一个简单的文本编辑器,而不是像code mirror这样的代码编辑器。感谢您添加Quill和WYSIHTML。这些似乎更适合您在问题中概述的内容。