javascript - 在 contentEditable <div> 上设置光标位置

标签 javascript jquery html contenteditable cursor-position

当 contentEditable='on'

重新获得焦点时,我正在寻求一个明确的跨浏览器解决方案,将光标/插入符号位置设置为最后一个已知位置。似乎内容可编辑 div 的默认功能是每次单击时将插入符号/光标移动到 div 中文本的开头,这是不可取的。

我相信当他们离开 div 的焦点时,我必须将当前光标位置存储在一个变量中,然后当他们再次将焦点放在里面时重新设置它,但我无法将它们放在一起,或者找到一个可以工作的代码示例。

如果有人有任何想法、工作代码片段或示例,我很乐意看到它们。

我还没有任何代码,但这是我所拥有的:

<script type="text/javascript">
// jQuery
$(document).ready(function() {
   $('#area').focus(function() { .. }  // focus I would imagine I need.
}
</script>
<div id="area" contentEditable="true"></div>

PS。我已经尝试过这个资源,但它似乎不适用于

。也许只适用于 textarea (How to move cursor to end of contenteditable entity)

最佳答案

此解决方案适用于所有主流浏览器:

saveSelection() 附加到 div 的 onmouseuponkeyup 事件,并将选择保存到变量 savedRange

restoreSelection() 附加到 div 的 onfocus 事件,并重新选择保存在 savedRange 中的选择。

这非常有效,除非您希望在用户单击 div 时恢复选择(这有点不直观,因为通常您希望光标移动到您单击的位置,但为了完整性而包含代码)

为了实现这一点,onclickonmousedown 事件由函数 cancelEvent() 取消,该函数是取消事件的跨浏览器函数. cancelEvent() 函数也运行 restoreSelection() 函数,因为当点击事件被取消时,div 不会获得焦点,因此除非这个函数,否则什么都不会被选中正在运行。

变量isInFocus存储是否处于焦点状态,改为“false”onblur和“true”onfocus。这允许仅当 div 未处于焦点时才取消单击事件(否则您将根本无法更改选择)。

如果您希望在通过单击聚焦 div 时更改选择,而不是恢复选择 onclick (并且仅当使用 document 以编程方式将焦点赋予元素时.getElementById("area").focus(); 或类似的,然后简单地删除 onclickonmousedown 事件。onblur在这些情况下,也可以安全地移除 onDivBlur()cancelEvent() 函数。

如果您想快速测试,如果将这段代码直接放到 html 页面的正文中,它应该可以工作:

<div id="area" style="width:300px;height:300px;" onblur="onDivBlur();" onmousedown="return cancelEvent(event);" onclick="return cancelEvent(event);" contentEditable="true" onmouseup="saveSelection();" onkeyup="saveSelection();" onfocus="restoreSelection();"></div>
<script type="text/javascript">
var savedRange,isInFocus;
function saveSelection()
{
    if(window.getSelection)//non IE Browsers
    {
        savedRange = window.getSelection().getRangeAt(0);
    }
    else if(document.selection)//IE
    { 
        savedRange = document.selection.createRange();  
    } 
}

function restoreSelection()
{
    isInFocus = true;
    document.getElementById("area").focus();
    if (savedRange != null) {
        if (window.getSelection)//non IE and there is already a selection
        {
            var s = window.getSelection();
            if (s.rangeCount > 0) 
                s.removeAllRanges();
            s.addRange(savedRange);
        }
        else if (document.createRange)//non IE and no selection
        {
            window.getSelection().addRange(savedRange);
        }
        else if (document.selection)//IE
        {
            savedRange.select();
        }
    }
}
//this part onwards is only needed if you want to restore selection onclick
var isInFocus = false;
function onDivBlur()
{
    isInFocus = false;
}

function cancelEvent(e)
{
    if (isInFocus == false && savedRange != null) {
        if (e && e.preventDefault) {
            //alert("FF");
            e.stopPropagation(); // DOM style (return false doesn't always work in FF)
            e.preventDefault();
        }
        else {
            window.event.cancelBubble = true;//IE stopPropagation
        }
        restoreSelection();
        return false; // false = IE style
    }
}
</script>

关于javascript - 在 contentEditable <div> 上设置光标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1181700/

相关文章:

javascript - 避免必须双击才能切换 Bootstrap 下拉菜单

javascript - 在xcode中使用phonegap的alert()与notification.alert()之间有区别吗?

javascript - 使用 indexOf 比较数组的第一个和下一个元素。 JavaScript

php - 在表悬停时从 WordPress 数据库获取数据

php - HTML5 地理定位第一次不起作用

javascript - 将内容放入带有图标的列中

html - 垂直对齐表格单元格元素

javascript - 根据条件在 ng-repeat 中的 HTML 元素上应用 CSS 类

javascript - 如何使用带有字符串值的变量作为另一个变量的名称。实际上尝试在 $.post 中设置它(名称 : value) data parameters

javascript - 我的动画 jQuery 不透明度不起作用