找回密码
 立即注册

QQ登录

只需一步,快速开始

KevinChen 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2020-12-28 17:52  /   查看:3216  /  回复:0
本帖最后由 KevinChen 于 2020-12-28 18:05 编辑

本文是《SpreadJS 如何自定义公式提示信息》系列的第三篇,第一、二篇请参考:
SpreadJS 如何自定义公式提示信息 Part I
SpreadJS 如何自定义公式提示信息 Part III
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++




二、如何解决获取光标位置?

可能有同学之前在网上搜索过这个问题,但题主确实是没有找到原生的JS事件能够直接监听光标位置的改变。所以这里采用了一些特殊的办法:通过获取“选中区域”的方式,获取到光标所在位置,如果选中区域为0,光标位置就是 selection 的 start == end的位置。

  1. /*
  2.                 获取光标焦点位置
  3.                 入参:光标HostElement
  4.                 返回:光标所在位置(int)
  5.         */
  6.         static getCursortPosition(element) {
  7.           var caretOffset = 0;
  8.           var doc = element.ownerDocument || element.document;
  9.           var win = doc.defaultView || doc.parentWindow;
  10.           var sel;
  11.           if (typeof win.getSelection != "undefined") {//谷歌、火狐
  12.                 sel = win.getSelection();
  13.                 if (sel.rangeCount > 0) {//选中的区域
  14.                   var range = win.getSelection().getRangeAt(0);
  15.                   var preCaretRange = range.cloneRange();//克隆一个选中区域
  16.                   preCaretRange.selectNodeContents(element);//设置选中区域的节点内容为当前节点
  17.                   preCaretRange.setEnd(range.endContainer, range.endOffset);  //重置选中区域的结束位置
  18.                   caretOffset = preCaretRange.toString().length;
  19.                 }
  20.           } else if ((sel = doc.selection) && sel.type != "Control") {//IE
  21.                 var textRange = sel.createRange();
  22.                 var preCaretTextRange = doc.body.createTextRange();
  23.                 preCaretTextRange.moveToElementText(element);
  24.                 preCaretTextRange.setEndPoint("EndToEnd", textRange);
  25.                 caretOffset = preCaretTextRange.text.length;
  26.           }
  27.           return caretOffset;
  28.         }
复制代码


那么有了上述的方法,我们已经可以获取到输入框的光标位置了,但是在什么时机获取呢?结合Part I 中的分析,当以下两种情况出现时,我们需要更新光标位置:
1、输入框内容发生改变时;
2、鼠标点击对应位置时;
3、键盘的 上、下、左、右方向键被触发时。

本Demo实现其中两个(键盘事件参考鼠标事件自行绑定)
代码如下:

  1. // 鼠标点击获取焦点事件
  2.         sheet.bind(GC.Spread.Sheets.Events.EditStarting, (sender, args) => {
  3.                 const editHost = CustomizeFormulaHelper.getInputDom(args.sheet);
  4.                 if(editHost){
  5.                         editHost.addEventListener("click", () => {
  6.                                 myFormulaHelper.currentCursortPosition = CustomizeFormulaHelper.getCursortPosition(editHost);
  7.                                 // console.log(editHost.textContent);
  8.                         });
  9.                 }
  10.         });
  11.         // 内容变更获取焦点事件
  12.         sheet.bind(GC.Spread.Sheets.Events.EditChange, (sender, args) => {
  13.                 const editHost = CustomizeFormulaHelper.getInputDom(args.sheet);
  14.                 if(editHost){
  15.                         myFormulaHelper.currentCursortPosition = CustomizeFormulaHelper.getCursortPosition(editHost);
  16.                         // console.log(editHost.textContent);
  17.                 }
  18.         });
  19.         // 复位光标位置
  20.         sheet.bind(GC.Spread.Sheets.Events.EditEnded, (sender, args) => {
  21.                 myFormulaHelper = new CustomizeFormulaHelper(args.sheet, fbx);
  22.                 observer.disconnect();
  23.                 observer = observeChange(myFormulaHelper);
  24.         });
复制代码



完整Demo请参考附件。

自定义公式提示信息_V14.0.2.zip

836.27 KB, 下载次数: 173

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部