在contentEditable div中获取插入位置

我find了很多很好的关于如何在contentEditable DIV中设置光标或插入符的位置的交叉浏览器,但没有find如何获取或查找位置的信息。

我想要做的是在键盘上知道插入符号的位置。

所以,当用户input文本时,我可以在任何时候知道它的光标在div中的位置。

编辑:我正在寻找div内容(文本)内的INDEX,而不是光标坐标。

<div id="contentBox" contentEditable="true"></div> $('#contentbox').keyup(function() { // ... ? }); 

以下代码假定:

  • 在可编辑的<div>总是有一个文本节点,没有其他节点
  • 可编辑的div没有将CSS white-space属性设置为pre

码:

 function getCaretPosition(editableDiv) { var caretPos = 0, sel, range; if (window.getSelection) { sel = window.getSelection(); if (sel.rangeCount) { range = sel.getRangeAt(0); if (range.commonAncestorContainer.parentNode == editableDiv) { caretPos = range.endOffset; } } } else if (document.selection && document.selection.createRange) { range = document.selection.createRange(); if (range.parentElement() == editableDiv) { var tempEl = document.createElement("span"); editableDiv.insertBefore(tempEl, editableDiv.firstChild); var tempRange = range.duplicate(); tempRange.moveToElementText(tempEl); tempRange.setEndPoint("EndToEnd", range); caretPos = tempRange.text.length; } } return caretPos; } 
 #caretposition { font-weight: bold; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div id="contentbox" contenteditable="true">Click me and move cursor with keys or mouse</div> <div id="caretposition">0</div> <script> var update = function() { $('#caretposition').html(getCaretPosition(this)); }; $('#contentbox').on("mousedown mouseup keydown keyup", update); </script> 

尝试这个:

Caret.js获取插入位置并从文本字段中偏移

https://github.com/ichord/Caret.js

演示: http : //ichord.github.com/Caret.js

 $("#editable").on('keydown keyup mousedown mouseup',function(e){ if($(window.getSelection().anchorNode).is($(this))){ $('#position').html('0') }else{ $('#position').html(window.getSelection().anchorOffset); } }); 
 body{ padding:40px; } #editable{ height:50px; width:400px; border:1px solid #000; } #editable p{ margin:0; padding:0; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script> <div contenteditable="true" id="editable">move the cursor to see position</div> <div> position : <span id="position"></span> </div> 
 //global savedrange variable to store text range in var savedrange = null; function getSelection() { var savedRange; if(window.getSelection && window.getSelection().rangeCount > 0) //FF,Chrome,Opera,Safari,IE9+ { savedRange = window.getSelection().getRangeAt(0).cloneRange(); } else if(document.selection)//IE 8 and lower { savedRange = document.selection.createRange(); } return savedRange; } $('#contentbox').keyup(function() { var currentRange = getSelection(); if(window.getSelection) { //do stuff with standards based object } else if(document.selection) { //do stuff with microsoft object (ie8 and lower) } }); 

注意:范围对象的自我可以存储在一个variables中,并且可以在任何时候重新select,除非contenteditable div的内容改变。

IE 8及更低版本的参考: http : //msdn.microsoft.com/en-us/library/ms535872(VS.85).aspx

标准(所有其他)浏览器的参考: https : //developer.mozilla.org/en/DOM/range (它的Mozilla文档,但代码工作在铬,Safari浏览器,歌剧和IE9)

这个为我工作:

 function getCaretCharOffsetInDiv(element) { var caretOffset = 0; if (typeof window.getSelection != "undefined") { var range = window.getSelection().getRangeAt(0); var preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } else if (typeof document.selection != "undefined" && document.selection.type != "Control") { var textRange = document.selection.createRange(); var preCaretTextRange = document.body.createTextRange(); preCaretTextRange.moveToElementText(element); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; } 

呼叫线路取决于事件types,对于键盘事件使用这个:

 getCaretCharOffsetInDiv(e.target) + ($(window.getSelection().getRangeAt(0).startContainer.parentNode).index()); 

对于鼠标事件使用这个:

 getCaretCharOffsetInDiv(e.target.parentElement) + ($(e.target).index()) 

在这两种情况下,我通过添加目标索引来照顾分界线

 function getCaretPosition() { var x = 0; var y = 0; var sel = window.getSelection(); if(sel.rangeCount) { var range = sel.getRangeAt(0).cloneRange(); if(range.getClientRects()) { range.collapse(true); var rect = range.getClientRects()[0]; if(rect) { y = rect.top; x = rect.left; } } } return { x: x, y: y }; }