html元素contenteditable属性如何定位光标和设置光标
最近在山寨一款网页微信的产品,对于div用contenteditable属性做的编辑框有不少心得,希望可以帮到入坑的同学。
废话不多说了,我们先来理解一下HTML的光标对象是如何工作的,后面我会贴完整的DEMO代码,不用急,先去理解,才能做出更加好的输入体验。
在HTML里面,光标是一个对象,光标对象是只有当你选中某个元素的时候才会出现的。
当我们去点击一个输入框的时候,实际上它会产生一个选中对象-selection(就是我们可以看到的文字变成蓝色的那个区域),selection在火狐浏览器可以直接用 window.getSelection()获取,在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 = document.getElementById('sendEmoji')
// 定义最后光标对象
var lastEditRange;
// 编辑框点击事件
document.getElementById('edit').onclick = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
}
// 编辑框按键弹起事件
document.getElementById('edit').onkeyup = function() {
// 获取选定对象
var selection = getSelection()
// 设置最后光标对象
lastEditRange = selection.getRangeAt(0)
}
// 表情点击事件
document.getElementById('sendEmoji').onclick = function() {
// 获取编辑框对象
var edit = document.getElementById('edit')
// 获取输入框对象
var emojiInput = document.getElementById('emojiInput')
// 编辑框设置焦点
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>html元素contenteditable属性如何定位光标和设置光标的更多相关文章
- html -- contenteditable 属性:指定元素内容是否可编辑
所有主流浏览器都支持 contenteditable 属性 定义和用法 contenteditable 属性指定元素内容是否可编辑. 注意: 当元素中没有设置 contenteditable 属性时, ...
- 周记5——随机撒花特效、动态修改伪元素样式、contenteditable属性、手机端调试利器VConsole、浏览器端debug调试
记录一些小零碎知识点,以便日后查看~ 1.随机撒花特效 教师节快到了,公司的产品提出一个需求:在IM(即时聊天)聊天界面弹出教师节的祝福“广告”,用户点击“发送祝福”按钮,聊天界面会随机撒花.这里的重 ...
- 前端之CSS——属性和定位
一.字体属性 1.font-size(字体大小) p { font-size: 14px; } font-size 属性可设置字体的尺寸. px:像素,稳定和精确 %:把 font-size 设置为基 ...
- html5中contenteditable 光标_如何设置光标位置
在js中,光标是一个对象,当你选中某个元素的时候才会出现光标对象.比如:我们点击一个输入框,实际会产生一个选中对象-selection,这个对象我们可以通过indow.getSelection()来获 ...
- jQuery入门(2)使用jQuery操作元素的属性与样式
jQuery入门(1)jQuery中万能的选择器 jQuery入门(2)使用jQuery操作元素的属性与样式 jQuery入门(3)事件与事件对象 jQuery入门(4)jQuery中的Ajax()应 ...
- Appium学习实践(二)Python简单脚本以及元素的属性设置
1.简单的Python脚本 Appium中的设置与Appium学习实践(一)简易运行Appium中的一致 Launch后,执行脚本 #coding:utf-8 import unittest impo ...
- 浅析CSS——元素重叠及position定位的z-index顺序
多次在项目中遇到html页面元素的非期待重叠错误,多数还是position定位情况下z-index的问题.其实每次解决类似问题思路大致都是一样的,说到底还是对z-index的理解比较模糊,可以解决问题 ...
- CSS笔记(十)position属性与定位
参考:http://www.w3school.com.cn/cssref/pr_class_position.asp position属性规定了元素的定位类型.任何元素都可定位,其中,绝对或固定元素会 ...
- 元素重叠及position定位的z-index顺序
元素位置重叠的背景常识 (x)html文档中的元素默认处于普通流(normal flow)中,也就是说其顺序由元素在文档中的先后位置决定,此时一般不会产生重叠(但指定负边距可能产生重叠).当我们用cs ...
随机推荐
- k8s全方位监控中-常用rules配置
[root@VM_0_48_centos prometheus]# cat alertmanager-configmap.yaml apiVersion: v1 kind: ConfigMap met ...
- LeetCode-019-删除链表的倒数第 N 个结点
删除链表的倒数第 N 个结点 题目描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 进阶:你能尝试使用一趟扫描实现吗? 示例说明请见LeetCode官网. 来源:力扣(Leet ...
- HDFS连接JAVA,HDFS常用API
先在pom.xml中导入依赖包 <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.hadoop/ha ...
- Linux下安装Apollo (Quick Start)
一.运行时环境 1.CentOS7 2.JDK1.8+ (安装JDK可参考 https://www.cnblogs.com/sportsky/p/15973713.html) 3.MySQL 5.6. ...
- 如何使用 PuTTY 远程连接矩池云主机
PuTTY 是一款开源的连接软件,用来远程连接服务器,支持 SSH.Telnet.Serial 等协议. 矩池云的主机支持 SSH 登录,以下为使用 PuTTY 连接矩池云 GPU 的使用教程. 如您 ...
- 分布式 PostgreSQL 集群(Citus)官方示例 - 时间序列数据
在时间序列工作负载中,应用程序(例如一些实时应用程序查询最近的信息,同时归档旧信息. https://docs.citusdata.com/en/v10.2/sharding/data_modelin ...
- VB、VBA、VBS的区别与联系
概念 VB Visual Basic(简称VB)是Microsoft公司开发的一种通用的基于对象的程序设计语言,为结构化的.模块化的.面向对象的.包含协助开发环境的事件驱动为机制的可视化程序设计语 ...
- 那些年,Android开发踩过的坑
首先讲一讲环境配置吧,一般刚上手Android编程,推荐的两款软件开发工具有Eclipse和Andriod Studio,配置环境来讲呢,Android Studio配置环境要快得多,而且比起Ecli ...
- 阿里云ECS服务器(G5)安装配置docker
镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 前言 服务器配置:阿里云ECS服务器(G5服务器3年2核8G内存80G云盘),安装的是CentOS,内核信息:5.10.60-9.al8.x86_ ...
- Excel批量转Word
平时的工作中,尤其是一些文职类工作中,常会遇到这样的问题: 我们有一个Excel文件,每一行都是一个人的信息,需要将每个人的信息填写到Word表格中:一个人,一张表,一个下午,真烦恼. 也是奇想突发, ...