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光标位置添加字符的更多相关文章

  1. 2017-02-20 可编辑div中如何在光标位置添加内容

    之前做了一个可编辑div需要在里面插入内容,搜了好多代码,就这个能实现我的功能,记录一下,以备以后用 <!DOCTYPE HTML> <html> <head> & ...

  2. js获取输入框中当前光标位置并在此位置插入字符串的方法(angularjs+ts)

    一半是参照别人代码,一半是自己代码,略笨拙,如果有更好的方法希望分享. 获取当前光标位置的方法 getCaretPosition (obj:any) { //获取输入框中当前光标的位置,obj为此输入 ...

  3. js获取可编辑区域光标位置

    请到简书中看,地址: http://www.jianshu.com/p/19a507cd5fd7 github测试例子 https://github.com/Stevenzwzhai/plugs/tr ...

  4. textarea 根据光标位置添加内容

    // 获取焦点 let txt = document.getElementById("countRule"); let temp = txt.value; txt.focus(); ...

  5. js 截取字符串,取指定位置的字符(完善中)

    1.获取字符串的最后一位或第一位 str.charAt(str.length - 1);    str.charAt(0);

  6. div contenteditable 代替Textarea,做成Vue属性动态绑定

    前言 一般都是用Textarea 文本来编辑,但发现可以用 div contenteditable = “true”,这个属性来搞定 <div contenteditable=true plac ...

  7. textarea在光标位置插入文字

    最近开发类似计算器界面,需要在textarea中编辑公式,涉及到 在光标位置插入 字符. 效果如下: + - * / 添加文字 // html代码如下: <!doctype html> & ...

  8. js控制使div自动适应居中

    一直都在想怎么样使弹出的DIV能在任何时候都是居中显示的,刚开始的时候是用CSS样式直接定义好层的位置,但是当页面很长的时候,或是浏览器窗口大小不是固定的时候就不能正确的显示,所以只好用JS来控制DI ...

  9. Python 字符串指定位置替换字符

    指定位置替换字符 def replace_char(old_string, char, index): ''' 字符串按索引位置替换字符 ''' old_string = str(old_string ...

随机推荐

  1. Spring Boot属性配置&自定义属性配置

    一.修改默认配置 例1.spring boot 开发web应用的时候,默认tomcat的启动端口为8080,如果需要修改默认的端口,则需要在application.properties 添加以下记录: ...

  2. 机器学习 - 算法 - SVM 支持向量机 Py 实现 / 人脸识别案例

    SVM 代码实现展示 相关模块引入 %matplotlib inline import numpy as np import matplotlib.pyplot as plt from scipy i ...

  3. 原生app是什么意思?

    原生的就是用 Android 和ios 写的 完全符合手机系统 其他的都是通过各种工具对代码转换为手机系统可以识别

  4. 使用editplus等编程工具时UTF-8编码去掉BOM头方法(转载备查)

            Unicode规范中有一个BOM的概念.BOM——Byte Order Mark,就是字节序标记.在这里找到一段关于BOM的说明: 在UCS 编码中有一个叫做"ZERO WI ...

  5. com.alibaba.fastjson.JSONObject;的使用

    转: com.alibaba.fastjson.JSONObject;的使用 2018-11-04 23:51:23 mameng1998 阅读数 6404更多 分类专栏: java   1  POM ...

  6. 阶段5 3.微服务项目【学成在线】_day18 用户授权_04-方法授权-方法授权实现

    2.3 方法授权实现 2.3.1资源服务添加授权控制 1.要想在资源服务使用方法授权,首先在资源服务配置授权控制 1)添加spring-cloud-starter-oauth2依赖. 2)拷贝授权配置 ...

  7. LeetCode_21. Merge Two Sorted Lists

    21. Merge Two Sorted Lists Easy Merge two sorted linked lists and return it as a new list. The new l ...

  8. 安卓 adb命令

    获取包名 aapt d badging C:\Users\600844\Desktop\beijingtoon.apk "package launchable-activity" ...

  9. 解决Windows7下virtualbox安装ubuntu出现的0x00000000指令引用0x00000000内存,该内存不能为written问题

    公司电脑只能用Windows7,不能用10,也没WSL用,最近想跑个Linux环境,因为之前装docker toolbox装了virtualbox,没道理再装vmware,遂用vbox开始折腾,没想到 ...

  10. 洛谷 题解 UVA10048 【噪音恐惧症 Audiophobia】

    [题意] 输入一个\(C\)个点\(S\)条边 \((C<=100)\) \((S<=1000)\)的无向带权图,边权表示该路径上的噪声值.当噪声太大时,耳膜可能会收到损伤,所以当你从某点 ...