cke点击时初始化编辑器后光标恢复的方法

摘要:
$:$. 父母如果{endContainer2=item;break;}}}}returnendContainer2;}5.恢复光标:您需要在此处添加延迟,否则光标尚未初始化为开头的CKEDITOR。实例[id]一次;6.坑:到目前为止,我们已经实现了光标恢复,但我们会发现光标将在开始时闪烁一次,然后到达我们单击的位置。作为强迫症的前端,我们不能容忍这种操作。我们可以使用样式来处理这一点:在开始单击时向目标div添加隐藏的光标样式,然后在恢复光标时将其删除。

业务场景

1、使用了CKEDITOR编辑器
2、文本是使用contenteditable="true"的div容器
3、点击文本时才初始化编辑器
4、问题:编辑器初始化后光标会重置到开始处,如何将光标重置到点击处
cke点击时初始化编辑器后光标恢复的方法第1张

解决方案

1、在点击文本的时候,在点击文本的时候,获取range信息和 endContainerendOffset;

      try {
          range = window.getSelection().getRangeAt(0);
          var endContainer = range.endContainer;
          var endOffset = range.endOffset;         
        } catch (e) {
          console.log(e);
        }

2、坑:直接点击图片,无法获取到range,需要把图片加入到range中;

       // 把图片加进选区
        if (e.target.nodeName === 'IMG') {
          var range2 = document.createRange();
          var selectTion = window.getSelection();
          selectTion.removeAllRanges();
          range2.selectNode(e.target);
          selectTion.addRange(range2);          
        }

3、在初始化编辑器后,在它的instanceReady方法回调中进行光标恢复操作

CKEDITOR.instances[id].once('instanceReady', () => {
 ...          
});

听起来很美好,对不对,但是在实际操作中发现,之前存储的endContainer已经被替换成新的range信息了。如何获取我们原来存储的endContainer呢?博主试了深拷贝,浅拷贝都不行,于是才用了遍历寻找的方法~~~

4、找到原来的endContainer 的方法

// 获取新的endContainer
  getEndContainer(endContainer, tag, endContainer2) {
    let childNodes = self.getAllChildNodes(tag);
    if (childNodes && childNodes.length > 0) {
      for (let i = 0, len = childNodes.length; i < len; i++) {
        let item = childNodes[i];
        if (
          (item.data && item.data === endContainer.data) ||
          (item.wholeText && item.wholeText === endContainer.wholeText) ||
          (item.innerHTML && item.innerHTML === endContainer.innerHTML)
        ) {
          // 为了避免有重复片段,必须其父亲也要相同,我这里的每行父级元素都有类名cut-check
          let $endContainerParent = $(endContainer).hasClass('cut-check') ? $(endContainer) : $(endContainer).parents('.cut-check');
          let $itemParent = $(item).hasClass('cut-check') ? $(item) : $(item).parents('.cut-check');

          if ($endContainerParent.attr('data-value') === $itemParent.attr('data-value')) {
            endContainer2 = item;
            break;
          }
        }
      }
    }
    return endContainer2;
  }

5、恢复光标:这里需要再加个延迟,不然光标还没有初始化到开头处

CKEDITOR.instances[id].once('instanceReady', () => {
            setTimeout(() => {
              try {
                var newRange = document.createRange();
                var set = window.getSelection();

                // 找到与 endContainer 一样的节点
                let endContainer2 = null;
                endContainer2 = self.getEndContainer(endContainer, tag, endContainer2);
                newRange.setEnd(endContainer2, endOffset);
                newRange.collapse(false);
                set.removeAllRanges();
                set.addRange(newRange);    
                
              } catch (e) {
                console.log(e)
              }              
            }, 500)
          });

6、坑:到这里,我们已经实现了光标恢复,但是会发现光标会现在起始处闪一下,再闪到我们点击处。作为有强迫症的前端肯定不能容忍这种操作了,这个我们使用样式就可以处理了:在开始点击的时候给目标div添加一个隐藏光标的样式,然后恢复光标的时候移除即可。
cke点击时初始化编辑器后光标恢复的方法第2张

.hide-caret {
  caret-color: transparent;
}

让我们再看下效果:
cke点击时初始化编辑器后光标恢复的方法第3张

结束语

至此,完成了我们的业务需求,当然第一次点击的时候会有不可见的1-2s的延迟,但是没办法,编辑器的初始化就需要1s多的时间。如果你有更好的想法,希望能跟我留言~

免责声明:文章转载自《cke点击时初始化编辑器后光标恢复的方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作关于Linux下conio头文件的实现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

DIV常见任务(下) 变身为编辑器

      自从HTML5中新引入了contentEditalbe属性以后,div就与textarea一样,可以作为最常用的编辑器使用。 1.启用div作为编辑器       让div进入编辑状态很简单,只需要: div.contentEditable=true; 这样就可以进入编辑状态。当然你直接在html中设置contenteditable也是可以的。...

Jenkins+pipeline+参数构建+人工干预确定

  Jenkins+pipeline+参数构建+人工干预 实现了以下功能 1. 可以选择环境,单选;可以选择需要发布的项目,多选 2.发布过程可视化 3. 可以人工干预是否继续发布。 初始化配置需要很久,比如拉镜像这些事情,我可以提前操作。配置做好之后,等到下班时间,再进行发布操作。有时候会遇到,我初始化配置做好之后,测试通知还有变动。我可以人工干预,...

OneNote无法打开链接出现错误:你的组织策略阻止我们为你完成此操作

首先打开注册表编辑器,按键盘win+r,调出运行窗口,输入regedit打开注册表编辑器 打开HKEY_CURRENT_USERSoftware 打开Classes 最后选中.html,在默认选项那右键点击修改 将里面的数值数据修改成“Htmlfile”,点击确定后退出,重启下电脑,如果不重启电脑,office onenote也要重新打开...

vi编辑器的三种模式

vi编辑器的三种模式通常来说,vi编辑器有三种模式,分别是一般指令模式、编辑模式与指令行命令模式。 这三种模式的作用分别是: 一般指令模式(command mode) 以 vi 打开一个文件就直接进入一般指令模式了(这是默认的模式,也简称为一般模式)。在这个模式中, 你可以使用上下左右按键来移动光标,你可以使用删除字符或删除整行来处理文件内容, 也可以使用...

SuperSocket源码解析之会话生命周期

一 基本概念    会话(Session)是客户端与服务器进行通信的基本单元,也是一个Socket的封装,在http协议中也有Session机制,其主要作用封装一个通信单元socket,负责服务器与客户端消息发送与接收,会话之间相互独立互不干扰且拥有唯一SessionId标识,维护着客户与服务器通信的生命周期。 二 SocketSession Socket...

mysql8下载安装及配置

mysql8下载和安装 一、下载 官网地址:https://dev.mysql.com/downloads/mysql/8.0.html 选择“downloads”-->"mysql community server",如下图所示: 向下滑动页面,找到你电脑适配的版本,点击“download”,如下图: 页面跳转,不需要注册和登陆,点击“No t...