在content-editable div中设置光标位置 [英] Set cursor position in content-editable div

查看:200
本文介绍了在content-editable div中设置光标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结:



我试图在用户键入 [在内容可编辑 div 中,第二个] 是自动插入的,并且插入符号位于它们中的两个之间,即






FIDDLE



输入 - 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;


注意:


  1. < div> 将包含子元素(大多数为< ;
  2. 仅使用vanilla JS支持Chrome支持

我的问题:


  1. 为什么上述功能不能正常工作?

  2. 它如何工作?

我花了几个小时寻找这个东西,没有发现什么有用的东西。有些是关于在小孩的开始或结束时设置 div ,但对我而言,它可以是任何位置,任何地方。

更新



感谢大家终于完成开发 解决方案

这是一个简单得多的方法。有几点需要注意:


  • 按键是唯一的关键事件您可以可靠地检测到输入了哪个字符。 keyup keydown 不会。

  • 代码处理插入通过防止 keypress 事件的默认操作,手动/手动括号/括号。

  • 使用DOM方法时,选择/ 。 这在IE <= 8中不起作用,它们具有不同的范围和选择API。如果您需要支持这些浏览器,我建议使用我自己的 Rangy 库。它可能没有它,但我真的不想写额外的代码。



演示:



http://jsfiddle.net/HPeb2/

代码:

  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 ).


FIDDLE

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:

  1. <div> will have child elements (mostly <br>s).
  2. Only Chrome support required using vanilla JS

My question:

  1. Why doesn't the above function work?
  2. 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 and keydown 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:

http://jsfiddle.net/HPeb2/

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屋!

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