本帖最后由 KevinChen 于 2020-12-28 18:05 编辑
二、如何解决获取光标位置?
可能有同学之前在网上搜索过这个问题,但题主确实是没有找到原生的JS事件能够直接监听光标位置的改变。所以这里采用了一些特殊的办法:通过获取“选中区域”的方式,获取到光标所在位置,如果选中区域为0,光标位置就是 selection 的 start == end的位置。
- /*
- 获取光标焦点位置
- 入参:光标HostElement
- 返回:光标所在位置(int)
- */
- static getCursortPosition(element) {
- var caretOffset = 0;
- var doc = element.ownerDocument || element.document;
- var win = doc.defaultView || doc.parentWindow;
- var sel;
- if (typeof win.getSelection != "undefined") {//谷歌、火狐
- sel = win.getSelection();
- if (sel.rangeCount > 0) {//选中的区域
- var range = win.getSelection().getRangeAt(0);
- var preCaretRange = range.cloneRange();//克隆一个选中区域
- preCaretRange.selectNodeContents(element);//设置选中区域的节点内容为当前节点
- preCaretRange.setEnd(range.endContainer, range.endOffset); //重置选中区域的结束位置
- caretOffset = preCaretRange.toString().length;
- }
- } else if ((sel = doc.selection) && sel.type != "Control") {//IE
- var textRange = sel.createRange();
- var preCaretTextRange = doc.body.createTextRange();
- preCaretTextRange.moveToElementText(element);
- preCaretTextRange.setEndPoint("EndToEnd", textRange);
- caretOffset = preCaretTextRange.text.length;
- }
- return caretOffset;
- }
复制代码
那么有了上述的方法,我们已经可以获取到输入框的光标位置了,但是在什么时机获取呢?结合Part I 中的分析,当以下两种情况出现时,我们需要更新光标位置:
1、输入框内容发生改变时;
2、鼠标点击对应位置时;
3、键盘的 上、下、左、右方向键被触发时。
本Demo实现其中两个(键盘事件参考鼠标事件自行绑定)
代码如下:
- // 鼠标点击获取焦点事件
- sheet.bind(GC.Spread.Sheets.Events.EditStarting, (sender, args) => {
- const editHost = CustomizeFormulaHelper.getInputDom(args.sheet);
- if(editHost){
- editHost.addEventListener("click", () => {
- myFormulaHelper.currentCursortPosition = CustomizeFormulaHelper.getCursortPosition(editHost);
- // console.log(editHost.textContent);
- });
- }
- });
- // 内容变更获取焦点事件
- sheet.bind(GC.Spread.Sheets.Events.EditChange, (sender, args) => {
- const editHost = CustomizeFormulaHelper.getInputDom(args.sheet);
- if(editHost){
- myFormulaHelper.currentCursortPosition = CustomizeFormulaHelper.getCursortPosition(editHost);
- // console.log(editHost.textContent);
- }
- });
- // 复位光标位置
- sheet.bind(GC.Spread.Sheets.Events.EditEnded, (sender, args) => {
- myFormulaHelper = new CustomizeFormulaHelper(args.sheet, fbx);
- observer.disconnect();
- observer = observeChange(myFormulaHelper);
- });
复制代码
完整Demo请参考附件。
|
|