js之向div contenteditable光标位置添加字符
js之向div contenteditable光标位置添加字符
原理:
在HTML里面,光标是一个对象,光标对象是只有当你选中某个元素的时候才会出现的。
当我们去点击一个输入框的时候,实际上它会产生一个选中对象-selection(就是我们可以看到的文字变成蓝色的那个区域),selection在火狐浏览器可以直接用 window.getSelection()获取,在HTML里面,selection只有一个的,并且selection是一个区域,你可以想象成一个长方形,它是有开始和结束的
当你点击一个输入框,或者你切换到别的输入框,selection是会跟着变化的。光标就是在selection里面,光标叫做range,是一个片段区域,和selection一样,有开始点,和结束点,当我们对文字按下左键向右拉的时候,就看到了文字变成蓝色,那个就是光标的开始和结束,当我们直接点一下的时候,光标在闪,其实只是开始和结束点重叠了。
代码:
<!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 edit = document.getElementById('edit')
var emojiInput = document.getElementById('emojiInput')
var sendEmoji = document.getElementById('sendEmoji') // 定义最后光标对象
var lastEditRange; // 编辑框点击事件
edit.onclick = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
} // 编辑框按键弹起事件
edit.onkeyup = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
} // 表情点击事件
sendEmoji.onclick = function() {
// 编辑框设置焦点
edit.focus()
// 获取选定对象
var selection = getSelection()
// 判断是否有最后光标对象存在
if (lastEditRange) {
// 存在最后光标对象,选定对象清除所有光标并添加最后光标还原之前的状态
selection.removeAllRanges()
selection.addRange(lastEditRange)
}
// 判断选定对象范围是编辑框还是文本节点
if (selection.anchorNode.nodeName != '#text') {
// 如果是编辑框范围。则创建表情文本节点进行插入
var emojiText = document.createTextNode(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 = document.createRange()
// 光标对象的范围界定为新建的表情节点
range.selectNodeContents(emojiText)
// 光标位置定位在表情节点的最大长度
range.setStart(emojiText, emojiText.length)
// 使光标开始和光标结束重叠
range.collapse(true)
// 清除选定对象的所有光标对象
selection.removeAllRanges()
// 插入新的光标对象
selection.addRange(range)
} else {
// 如果是文本节点则先获取光标对象
var range = selection.getRangeAt(0)
// 获取光标对象的范围界定对象,一般就是textNode对象
var textNode = range.startContainer;
// 获取光标位置
var rangeStartOffset = range.startOffset;
// 文本节点在光标位置处插入新的表情内容
textNode.insertData(rangeStartOffset, emojiInput.value)
// 光标移动到到原来的位置加上新内容的长度
range.setStart(textNode, rangeStartOffset + emojiInput.value.length)
// 光标开始和光标结束重叠
range.collapse(true)
// 清除选定对象的所有光标对象
selection.removeAllRanges()
// 插入新的光标对象
selection.addRange(range)
}
// 无论如何都要记录最后光标对象
lastEditRange = selection.getRangeAt(0)
}
</script>
</body>
</html>
vue使用:
1.将lastEditRange(最后光标对象)定义为公共变量
2.在div输入框绑定click和keyup时间,然后在添加的点击事件运行函数
转载自:https://segmentfault.com/a/1190000005869372
js之向div contenteditable光标位置添加字符的更多相关文章
- 2017-02-20 可编辑div中如何在光标位置添加内容
之前做了一个可编辑div需要在里面插入内容,搜了好多代码,就这个能实现我的功能,记录一下,以备以后用 <!DOCTYPE HTML> <html> <head> & ...
- js获取输入框中当前光标位置并在此位置插入字符串的方法(angularjs+ts)
一半是参照别人代码,一半是自己代码,略笨拙,如果有更好的方法希望分享. 获取当前光标位置的方法 getCaretPosition (obj:any) { //获取输入框中当前光标的位置,obj为此输入 ...
- js获取可编辑区域光标位置
请到简书中看,地址: http://www.jianshu.com/p/19a507cd5fd7 github测试例子 https://github.com/Stevenzwzhai/plugs/tr ...
- textarea 根据光标位置添加内容
// 获取焦点 let txt = document.getElementById("countRule"); let temp = txt.value; txt.focus(); ...
- js 截取字符串,取指定位置的字符(完善中)
1.获取字符串的最后一位或第一位 str.charAt(str.length - 1); str.charAt(0);
- div contenteditable 代替Textarea,做成Vue属性动态绑定
前言 一般都是用Textarea 文本来编辑,但发现可以用 div contenteditable = “true”,这个属性来搞定 <div contenteditable=true plac ...
- textarea在光标位置插入文字
最近开发类似计算器界面,需要在textarea中编辑公式,涉及到 在光标位置插入 字符. 效果如下: + - * / 添加文字 // html代码如下: <!doctype html> & ...
- js控制使div自动适应居中
一直都在想怎么样使弹出的DIV能在任何时候都是居中显示的,刚开始的时候是用CSS样式直接定义好层的位置,但是当页面很长的时候,或是浏览器窗口大小不是固定的时候就不能正确的显示,所以只好用JS来控制DI ...
- Python 字符串指定位置替换字符
指定位置替换字符 def replace_char(old_string, char, index): ''' 字符串按索引位置替换字符 ''' old_string = str(old_string ...
随机推荐
- SVG-概述/容器与通用属性
参考: SVG 图像入门教程 MDN SVG SVG教程 SVG入门-踏得 工具: svg在线编辑 概述 SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector ...
- python中关于shutdown 和closesocket的彻底理解!
关于shutdown 和closesocket的彻底理解! shutdown 和closesocket 来,咱们彻底的来讨论一下这个shutdown 和closesocket 从函数调用上来分析(ms ...
- osgViewer::Viewer::Windows
osg自带窗口去掉边框 #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include<iostream> #incl ...
- cookie和session-csrf防护-中间件
cookie概念: 是由服务器生成,保存在浏览器端的一小段文本信息. cookie特点: 1) cookie是以键值对进行存储的. 2) 浏览器访问网站时,会将本地保存的跟网站相关的所有cookie发 ...
- LeetCode_67. Add Binary
67. Add Binary Easy Given two binary strings, return their sum (also a binary string). The input str ...
- UIImagePickerController的用法
在实际的APP开发中,我们经常会见到应用的这样的功能 :需要选取手机相册的照片,还有选取视频,拍视频和照相的操作. 在iOS开发中,实现以上的功能就需要用到 UIImagePickerControll ...
- Apache Commons Net中FTPClient设置成以二进制进行传输
代码: ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- vue启动时报 This relative module was not found
This relative module was not found: * ../../vue-temp/vue-editor-bridge in ./node_modules/babel-loade ...
- 综合练习1,划分vlan,单臂路由,DHCP服务及其限制网段、租期,设置根桥,OSPF路由通告综合练习
实验要求: 1.在LSW1上分别给vlan10和vlan20做DHCP网段分别为192.168.10.0/24.192.168.20.0/24禁用192.168.10.200-253,192.168. ...
- php5.6安装及php-fpm优化配置
1,安装依赖包: yum install -y gcc gcc-c++ zlib zlib-devel pcre pcre-devel gd libjpeg libjpeg-devel libpn ...