最近在山寨一款网页微信的产品,对于div用contenteditable属性做的编辑框有不少心得,希望可以帮到入坑的同学。

废话不多说了,我们先来理解一下HTML的光标对象是如何工作的,后面我会贴完整的DEMO代码,不用急,先去理解,才能做出更加好的输入体验。

在HTML里面,光标是一个对象,光标对象是只有当你选中某个元素的时候才会出现的。

当我们去点击一个输入框的时候,实际上它会产生一个选中对象-selection(就是我们可以看到的文字变成蓝色的那个区域),selection在火狐浏览器可以直接用 window.getSelection()获取,在HTML里面,selection只有一个的,并且selection是一个区域,你可以想象成一个长方形,它是有开始和结束的

当你点击一个输入框,或者你切换到别的输入框,selection是会跟着变化的。光标就是在selection里面,光标叫做range,是一个片段区域,和selection一样,有开始点,和结束点,当我们对文字按下左键向右拉的时候,就看到了文字变成蓝色,那个就是光标的开始和结束,当我们直接点一下的时候,光标在闪,其实只是开始和结束点重叠了。

OK,现在我们来实际操作光标了。直接看完整的代码,然后看效果吧。

发送表情

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)

}

html光标自动定位到文本框,html元素contenteditable属性如何定位光标和设置光标相关推荐

  1. html输入框的属性,文本框以及input的属性及功能

    属性:text(文本) 默认 password(保密密码) input type="text" 密码: input type="password" 选项按钮: ...

  2. [图解]在输入框和文本框中获取和设置光标位置,以及选中文本和获取选中文本值的方法 --- 详解,兼容所有浏览器。...

    为什么80%的码农都做不了架构师?>>>    写在前面 最近在segmentfault上看到它的日期输入控件,感觉挺有意思.好吧,动手写一个,加到自己的代码库里吧. 然后问题来了, ...

  3. VBS使文本框的光标位于所有字符后

    有时候在文本框里会显示一部分提示信息,用户在这些提示信息后面输入文本,但是将焦点设置于文本框后,光标总是在文本框的最前面, 用户输入的时候需要按"-->"键将光标移到最后才能 ...

  4. uniapp光标自动定义到文本框_特检自动化行吊静力检测方案

    主要测量功能使用徕卡测量开发的Windows版数据传输软件,通过蓝牙连接徕卡DISTO,经过简单的测量周期设置,即可实现自动化的距离检测.测量数据还可以输出Excel,甚至可以实时发送至PC运行的第三 ...

  5. html文本框光标位置,html的文本框显示光标 如何在htmlText文本框光标处插入字符...

    HTML 如何设置文本框中光标位置和光标居中 我写样式,把文本框的宽度加大了.但是光标位置在上面. html怎么让文本框的光标出现在内容最后 HTML如何在打开页面时将光标定位在某个文本框 HTML5 ...

  6. html5 文本框限制,html中input禁止输入(禁止获得焦点)多种方法及input限制数字和长度...

    input禁止输入(禁止获得焦点) 1: readonly规定输入字段为只读可复制,但是,用户可以使用Tab键切换到该字段,可选择,可以接收焦点,还可以选中或拷贝其文本. 2:disabled   被 ...

  7. html 点击文本框则选中,JS事件 内容选中事件(onselect)选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行。...

    内容选中事件(onselect) 选中事件,当文本框或者文本域中的文字被选中时,触发onselect事件,同时调用的程序就会被执行. 如下代码,当选中用户文本框内的文字时,触发onselect 事件, ...

  8. 前端常用事件案例——抽名字(抽奖)/搜索下拉菜单/微博文本框

    目录 抽名字(抽奖) 搜索下拉菜单 微博文本框 进阶微博案例 抽名字(抽奖) 实现效果是:点击开始按钮,则方框不断显示名字,点击停止,抽到的人名就是谁,并且删除,继续直到抽完后禁用按钮 ①点击开始按钮 ...

  9. input如何禁止文本框输入的方法

    禁止文本框输入有以下四种方法: 1.设置input为只读状态,代码如下: <input type="text" readonly="readonly" v ...

最新文章

  1. 数据统计之日分类商品访问量
  2. 免费在线共享思维导图敏捷开发工具Leangoo
  3. linux系统的编译原理,GCC编译原理_Linux编程_Linux公社-Linux系统门户网站
  4. HBase基本概念和hbase shell常用命令用法
  5. java中没有scanner_如何使用java.util.Scanner验证输入?
  6. 【labelme】改造labelme
  7. 没有bug队——加贝——Python 练习实例 1,2
  8. python中的一个现象,db.commit和db.commit()
  9. VS快速生成JSON数据格式对应的实体
  10. CCF201903-2 二十四点(100分)【表达式计算】
  11. 如何在电脑上给视频去水印
  12. GPT磁盘如何正确分区以及UEFI引导怎么修复?
  13. 题解 P3387 【【模板】缩点】
  14. html怎么给图片加鼠标滑过效果,jquery给图片添加鼠标经过时的边框效果
  15. 购物车——js小项目实例
  16. Bugku / CTF / WEB 输入密码查看flag
  17. 使用CSS3制作小黄人动画
  18. 在正确的时间吃正确的水果
  19. 【原创】iOS开发入门教程
  20. Objects as Points 解读

热门文章

  1. 第一次搭建成功MySQL数据库
  2. 【Android 】零基础到飞升 | ExpandableListView(可折叠列表)的基本使用
  3. excel分类汇总的使用
  4. 手机里tencent文件夹能删吗_手机SD卡Tencent文件夹里面哪些可以删?
  5. android设备唯一标识符_安卓设备唯一标识,用什么来获取》?
  6. php 企业建站系统,QCMS PHP轻量级企业建站系统 v5.0.2
  7. 论面向服务的架构与其应用
  8. 电话骗局:被电信诈骗的恐惧与救赎
  9. 追女孩要用到的短信24条
  10. Jenkins pipeline 隐藏密码