jquery在contenteditable div中设置光标位置

Posted

技术标签:

【中文标题】jquery在contenteditable div中设置光标位置【英文标题】:jquery Setting cursor position in contenteditable div 【发布时间】:2011-02-21 16:48:41 【问题描述】:

问题的旧版本如下,经过更多研究,我决定改写问题。和以前一样的问题是,我需要在不突出显示文本的情况下聚焦一个 contenteditable div,直接向上聚焦会突出显示 Chrome 中的文本。

我意识到人们通过重置文本区域中的插入符号位置来解决文本区域中的这个问题。如何使用 contenteditable 元素做到这一点?我尝试过的所有插件都只适用于 textareas。谢谢。

问题的旧措辞:

我有一个 contenteditable 元素 我想集中注意力,但仅限于 将光标放在前面 元素,而不是选择 一切。

elem.trigger('focus'); 与 jquery 选择整个文本中的所有文本 铬元素。 Firefox 的行为 正确地,将插入符号设置在 正文前面。我怎样才能得到 Chrome 以我想要的方式行事,或者是 关注也许不是我在看的东西 为。

谢谢大家。

【问题讨论】:

这个previous question 可能有助于光标定位。 你确定那些在 contenteditable 上工作吗?我无法让这些工作。 @Mark:我已将代码更新为最新的 jquery,并修改了演示以处理丰富的内容。 【参考方案1】:

也许我误读了这个问题,但以下不是(假设一个可编辑的<div> id 为“editable”)?计时器在那里是因为在 Chrome 中,选择整个元素的本机浏览器行为似乎在 focus 事件之后触发,从而覆盖选择代码的效果,除非推迟到焦点事件之后:

var div = document.getElementById("editable");

div.onfocus = function() 
    window.setTimeout(function() 
        var sel, range;
        if (window.getSelection && document.createRange) 
            range = document.createRange();
            range.selectNodeContents(div);
            range.collapse(true);
            sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
         else if (document.body.createTextRange) 
            range = document.body.createTextRange();
            range.moveToElementText(div);
            range.collapse(true);
            range.select();
        
    , 1);
;

div.focus();

【讨论】:

敬畏!,这是一件美丽的事情!谢谢蒂姆。 天哪,蒂姆,你是怎么做到的。谢谢。 这很好,但是如何将焦点放在 div 的末尾而不是前面? jsfiddle.net/bq6jQ/1***.com/questions/22599694/… @Squirrl:将range.collapse(true); 的两个实例更改为range.collapse(false);【参考方案2】:

演示:http://so.lucafilosofi.com/jquery-setting-cursor-position-in-contenteditable-div/

      <div id="editable" contentEditable="true">
            <h2>Lorem</h2> <p>ipsum dolor <i>sit</i> 
               amet, consectetur <strong>adipiscing</strong> elit.</p> Aenean.
        </div>

    <script type="text/javascript">
        $(function () 
            $('[contentEditable="true"]').on('click', function (e) 
                if (!$(this).hasClass('editing')) 
                    var html = $(this).html();
                    if (html.length) 
                        var range = rangy.createRange();
                        $(this).toggleClass('editing').html('<span class="content-editable-wrapper">' + html + '</span>');
                        var $last = $(this).find('.content-editable-wrapper');
                        range.setStartAfter($last[0]);
                        range.collapse(false);
                        rangy.getSelection().setSingleRange(range);
                    
                
            ).on('blur', function () 
                $(this).toggleClass('editing').find('.content-editable-wrapper').children().last().unwrap();
            );
        );
    </script>
注意: 使用 rangy.js https://code.google.com/p/rangy/

【讨论】:

这是一个有趣的技巧,实际上是个好主意。谢谢你。但是 contenteditable 是一个所见即所得的编辑器,所以我不能只替换一个文本字段。 一个有趣的想法,我敢肯定对某些人来说很有价值,但这并不能回答如何在可内容编辑的 div 上设置克拉位置的问题。添加“假”输入框并不是真正的解决方案;如果我想使用输入,我会使用输入。 没有回答这个问题。更好的答案***.com/questions/1181700/… 我已将代码更新为最新的 jQuery 版本,并修改了演示,使其能够按预期工作,并且内容丰富。无需添加额外的输入或文本区域。【参考方案3】:

是的,因为你使用过

elem.trigger('focus'); 

尝试使用类或识别要触发触发事件的元素。

【讨论】:

【参考方案4】:

在对 DOM 进行了一番探索之后,我设法解决了这个问题。

elm.focus();
window.getSelection().setPosition(0);

它可能只适用于 WebKit 浏览器,但由于它是问题的唯一来源,我添加了一个条件(使用 jQuery)

if(!$.browser.webkit) 
    elm.focus();
 else 
    elm.focus();
    window.getSelection().setPosition(0);

希望这能解决您的问题。

【讨论】:

嗯,不知道为什么,这对我不起作用。 Tim Down 的回答确实如此。【参考方案5】:

在pre或div标签中设置指针位置:

function setCursor(pos) 
    var el = document.getElementById("asd");
    var range = document.createRange();
    var sel = window.getSelection();
    range.setStart(el.childNodes[0], pos);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    el.focus();


$('button').click(function () 
    setCursor(5);
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="asd" contenteditable="true" >
asd
two
</div>
<button>Set caret position</button>

来源:https://social.msdn.microsoft.com/Forums/en-US/f91341cb-48b3-424b-9504-f2f569f4860f/getset-caretcursor-position-in-a-contenteditable-div?forum=winappswithhtml5

【讨论】:

以上是关于jquery在contenteditable div中设置光标位置的主要内容,如果未能解决你的问题,请参考以下文章

jquery在contenteditable div中设置光标位置

使用 jquery 和 contenteditable="true" 更新值 [重复]

Vue.js 删除渲染函数中的 contenteditable 属性

jquery localStorage for contenteditable content以记住编辑的内容

contentEditable div 中的粗体选定文本,使用纯 JavaScript,不使用 jQuery 等库

如何避免从 jQuery 中的 contenteditable <p> 中删除键入的文本