在content-editable div中设置光标位置 [英] Set cursor position in content-editable div
问题描述
我试图在用户键入(
或 [在内容可编辑
div
中,第二个)
或]
是自动插入的,并且插入符号位于它们中的两个之间,即(
和)
。
输入 -
s的权利,看看第一行是如何工作的,而不是在第二行。
< hr>
我的努力:
我使用这段代码(Tim Down )来突出显示文本的某些部分并设置光标位置。前者工作,但后者不会:($ / b>
$ b
函数getTextNodesIn(节点){//助手
var textNodes = [];
if(node.nodeType == 3){
textNodes.push(node);
} else {
var children = node.childNodes;
for(var i = 0,len = children.length; i< len; ++ i){
textNodes.push.apply(textNodes,getTextNodesIn(children [i]));
}
}
return textNodes;
}
函数highlightText(el,start,end){// main
if(el.tagName === ();
var textNodes = getTextNodesIn(el);
var foundStart = false;
var charCount = 0,
endCharCount;
(var i = 0,textNode; textNode = textNodes [i ++];){
endCharCount = charCount + textNode.length;
if (!foundStart&&开始> = charCount&& (start< endCharCount ||(start == endCharCount&& i< textNodes.length))){
range.setStart(textNode,start - charCount);
foundStart = true;
}
if(foundStart&& end< = endCharCount){
range.setEnd(textNode,end - charCount);
休息;
}
charCount = endCharCount;
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else {// textarea
el.selectionStart = start;
el.selectionEnd = end;
注意:
-
< div>
将包含子元素(大多数为< ;
- 仅使用vanilla JS支持Chrome支持
我的问题:
- 为什么上述功能不能正常工作?
- 它如何工作?
我花了几个小时寻找这个东西,没有发现什么有用的东西。有些是关于在小孩的开始或结束时设置 div
,但对我而言,它可以是任何位置,任何地方。
更新:
感谢大家终于完成开发! 解决方案
这是一个简单得多的方法。有几点需要注意:
按键
是唯一的关键事件您可以可靠地检测到输入了哪个字符。 keyup
和 keydown
不会。
keypress
事件的默认操作,手动/手动括号/括号。
演示:
代码:
var editableEl = document.getElementById(editable);
editableEl.addEventListener(keypress,function(e){
var charTyped = String.fromCharCode(e.which);
if(charTyped =={|| charTyped == (){
//自己处理这个案例
e.preventDefault();
var sel = window.getSelection();
if(sel。 rangeCount> 0){
//首先,删除现有的选项
var range = sel.getRangeAt(0);
range.deleteContents();
//在包含大括号/ parens的插入符处插入文本节点
var text =(charTyped =={)?{}:();
var textNode = document.createTextNode (text);
range.insertNode(textNode);
//将选择移动到插入文本节点的中间
range.setStart(textNode,1);
range.setEnd(textNode,1);
sel.removeAllRanges();
sel.addRange(range);
}
}
},false);
Summary:
I am trying to achieve the effect where when user types a (
or [
in the content-editable div
, the second )
or ]
is auto-inserted, and the caret be positioned between the two of them, that is, between (
and )
.
Type to the right of the --
s and see how in the first line it works while doesn't work in the second.
My effort:
I am using this code (by Tim Down) to both highlight some part of text and set cursor position. The former works but latter doesn't :(
function getTextNodesIn(node) { // helper
var textNodes = [];
if (node.nodeType == 3) {
textNodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; ++i) {
textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
}
}
return textNodes;
}
function highlightText(el, start, end) { // main
if (el.tagName === "DIV") { // content-editable div
var range = document.createRange();
range.selectNodeContents(el);
var textNodes = getTextNodesIn(el);
var foundStart = false;
var charCount = 0,
endCharCount;
for (var i = 0, textNode; textNode = textNodes[i++];) {
endCharCount = charCount + textNode.length;
if (!foundStart && start >= charCount && (start < endCharCount || (start == endCharCount && i < textNodes.length))) {
range.setStart(textNode, start - charCount);
foundStart = true;
}
if (foundStart && end <= endCharCount) {
range.setEnd(textNode, end - charCount);
break;
}
charCount = endCharCount;
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else { // textarea
el.selectionStart = start;
el.selectionEnd = end;
}
}
Notes:
<div>
will have child elements (mostly<br>
s).- Only Chrome support required using vanilla JS
My question:
- Why doesn't the above function work?
- How can it be made to work?
I have spent hours searching for this and found nothing much useful. Some were about setting at start or end of a child div
but for me it can be any location, anywhere.
UPDATE:
Thanks to everyone is finally finished development!
Here's a much simpler approach. There are a few things to note:
keypress
is the only key event in which you can reliably detect which character has been typed.keyup
andkeydown
won't do.- The code handles the insertion of parentheses/braces manually by preventing the default action of the
keypress
event. - The selection/caret stuff is simple when using DOM methods.
- This won't work in IE <= 8, which have different range and selection APIs. If you need support for those browsers, I'd suggest using my own Rangy library. It is possible without it but I really don't want to write the extra code.
Demo:
Code:
var editableEl = document.getElementById("editable");
editableEl.addEventListener("keypress", function(e) {
var charTyped = String.fromCharCode(e.which);
if (charTyped == "{" || charTyped == "(") {
// Handle this case ourselves
e.preventDefault();
var sel = window.getSelection();
if (sel.rangeCount > 0) {
// First, delete the existing selection
var range = sel.getRangeAt(0);
range.deleteContents();
// Insert a text node at the caret containing the braces/parens
var text = (charTyped == "{") ? "{}" : "()";
var textNode = document.createTextNode(text);
range.insertNode(textNode);
// Move the selection to the middle of the inserted text node
range.setStart(textNode, 1);
range.setEnd(textNode, 1);
sel.removeAllRanges();
sel.addRange(range);
}
}
}, false);
这篇关于在content-editable div中设置光标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!