- 默认键盘或者鼠标事件的动作
-
准备实现:通过Backspace按键删除节点(8),节点删除后,光标移动到上一节点最后
-
存在问题:删除节点(8)后,光标移动到上一节点了,但是上一节点的最后的文字被吃点一个,具体见图
-
原因分析: 关键是javascript的事件的默认动作问题,由于按
Backspace
的默认动作是删除字符,chrome在没有通过document.createRange()
设置range的情况下,按Backspace
的删除动作是,在本节点内容全部删除完毕后,直接到上一节点的最前端,而这时,第二个删除动作其实在新的节点上也发生了,只是由于光标已经在最前端,所以删无可删,而当通过代码将光标移动到最末端时,这个按Backspace
的删除将被执行,所以会删除最后一个字符。
-
解决办法:在设置光标移动到最后位置后,设置
e.preventDefault()
取消默认事件。
- 如何在一个使用
contenteditable
属性的div
标签中,定位光标的位置
-
光标的说明: 在HTML里面,光标是一个对象,光标对象是只有当你选中某个元素的时候才会出现的。
当我们去点击一个输入框的时候,实际上它会产生一个选中对象-selection(就是我们可以看到的文字变成蓝色的那个区域),selection在火狐浏览器可以直接用 window.getSelection()获取,在HTML里面,selection只有一个的,并且selection是一个区域,你可以想象成一个长方形,它是有开始和结束的
当你点击一个输入框,或者你切换到别的输入框,selection是会跟着变化的。光标就是在selection里面,光标叫做range,是一个片段区域,和selection一样,有开始点,和结束点,当我们对文字按下左键向右拉的时候,就看到了文字变成蓝色,那个就是光标的开始和结束,当我们直接点一下的时候,光标在闪,其实只是开始和结束点重叠了。(这段文字摘自https://segmentfault.com/a/1190000005869372 )
var getCaretPosition = function(oField) {
var iCaretPos = 0;
var doc = oField.ownerDocument || oField.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(oField);
preCaretRange.setEnd(range.endContainer, range.endOffset);
iCaretPos = preCaretRange.toString().length;
}
} else if ((sel = doc.selection) && sel.type !== 'Control') {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(oField);
preCaretTextRange.setEndPoint('EndToEnd', textRange);
iCaretPos = preCaretTextRange.text.length;
}
return (iCaretPos);
};
- 如何在一个使用
contenteditable
属性的div
标签中,移动光标的位置
- 实现步骤(仅针对chrome浏览器,其他没测试)
- 创建一个一个Range对象
- 设置Range所针对的元素对象
- 设置Range前后位置可以重叠
- 设置Range开始(开始结束一样)
- 设置Range结束(这个决定了光标移动到的具体位置)
- 设置选区
- 清除选区中的所有范围
- 将Range加入到选区中。
-
代码示例