html元素contenteditable属性如何定位光标和设置光标
最近在⼭寨⼀款⽹页的产品,对于div⽤contenteditable属性做的编辑框有不少⼼得,希望可以帮到⼊坑的同学。
废话不多说了,我们先来理解⼀下HTML的光标对象是如何⼯作的,后⾯我会贴完整的DEMO代码,不⽤急,先去理解,才能做出更加好的输⼊体验。
在HTML⾥⾯,光标是⼀个对象,光标对象是只有当你选中某个元素的时候才会出现的。
当我们去点击⼀个输⼊框的时候,实际上它会产⽣⼀个选中对象-selection(就是我们可以看到的⽂字变成蓝⾊的那个区域),selection在⽕狐浏览器可以直接⽤ Selection()获取,在HTML⾥⾯,selection只有⼀个的,并且selection是⼀个区域,你可以想象成⼀个长⽅形,它是有开始和结束的
当你点击⼀个输⼊框,或者你切换到别的输⼊框,selection是会跟着变化的。光标就是在selection⾥⾯,光标叫做range,是⼀个⽚段区域,和selection⼀样,有开始点,和结束点,当我们对⽂字按下左键向右拉的时候,就看到了⽂字变成蓝⾊,那个就是光标的开始和结束,当我们直接点⼀下的时候,光标在闪,其实只是开始和结束点重叠了。
OK,现在我们来实际操作光标了。直接看完整的代码,然后看效果吧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>#edit{height:500px;width:500px;border:1px solid red;}</style>
</head>
<body>
<div id="edit" contenteditable></div>
<input type="text" id="emojiInput">
<button id="sendEmoji">发送表情</button>
<script>
var sendEmoji = ElementById('sendEmoji')
// 定义最后光标对象
var lastEditRange;
// 编辑框点击事件
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = RangeAt(0)
}
/
/ 编辑框按键弹起事件
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = RangeAt(0)
}
// 表情点击事件
// 获取编辑框对象
var edit = ElementById('edit')
/
/ 获取输⼊框对象
var emojiInput = ElementById('emojiInput')
// 编辑框设置焦点
edit.focus()
// 获取选定对象
var selection = getSelection()
// 判断是否有最后光标对象存在
// 判断是否有最后光标对象存在
if (lastEditRange) {
// 存在最后光标对象,选定对象清除所有光标并添加最后光标还原之前的状态                veAllRanges()
selection.addRange(lastEditRange)
}
// 判断选定对象范围是编辑框还是⽂本节点
if (deName != '#text') {
// 如果是编辑框范围。则创建表情⽂本节点进⾏插⼊
var emojiText = ateTextNode(emojiInput.value)
if (edit.childNodes.length > 0) {
// 如果⽂本框的⼦元素⼤于0,则表⽰有其他元素,则按照位置插⼊表情节点                    for (var i = 0; i < edit.childNodes.length; i++) {
if (i == selection.anchorOffset) {
edit.insertBefore(emojiText, edit.childNodes[i])
}
}
} else {
// 否则直接插⼊⼀个表情元素
edit.appendChild(emojiText)
}
// 创建新的光标对象
var range = ateRange()
// 光标对象的范围界定为新建的表情节点
range.selectNodeContents(emojiText)
// 光标位置定位在表情节点的最⼤长度
range.setStart(emojiText, emojiText.length)
// 使光标开始和光标结束重叠
// 清除选定对象的所有光标对象
// 插⼊新的光标对象
selection.addRange(range)
} else {
// 如果是⽂本节点则先获取光标对象
var range = RangeAt(0)htmlbutton属性
// 获取光标对象的范围界定对象,⼀般就是textNode对象
var textNode = range.startContainer;
// 获取光标位置
var rangeStartOffset = range.startOffset;
// ⽂本节点在光标位置处插⼊新的表情内容
textNode.insertData(rangeStartOffset, emojiInput.value)
// 光标移动到到原来的位置加上新内容的长度
range.setStart(textNode, rangeStartOffset + emojiInput.value.length)
// 光标开始和光标结束重叠
// 清除选定对象的所有光标对象
// 插⼊新的光标对象
selection.addRange(range)
}
// ⽆论如何都要记录最后光标对象
lastEditRange = RangeAt(0)
}
</script>
</body>
</html>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。