本帖最后由 KevinChen 于 2020-12-28 18:05 编辑
如上图所示,以上两个提示信息是SpreadJS原生实现的,体验上类似Excel的Formula Helper的tip,曾经有很多用Spread JS的朋友希望能够自定义这个Tip,那从本文开始,我就帮咱们尝试分析、实现一下这个需求功能。
注意:
此功能不是SpreadJS产品原生功能。
本文思路仅供参考,请详细阅读文章、源码,并仔细评估后再决定要不要做到产品中。
如遇到问题欢迎交流,但如因此方案不满足需求,版主和技术团队没有完善的义务。
需求分析:
要实现自定制Formula Helper Tips,到底要实现什么?这里建议有此想法的小伙伴,可以先打开一个SpreadJS,输入公式后仔细查看Tips的UI逻辑。我总结了几点,如下所示:
1、能够在光标处根据当前输入内容,自动模糊检索可能的公式条目;
2、当输入公式参数时,会自动判断参数输入的是公式,还是值(或引用),如果是公式,回到1,如果是值(或引用),弹出参数提示以及公式详情;
3、当遇到多层嵌套公式时,Helper Tip会随鼠标点击(光标停留)的位置判断所在位置的公式,并结合1、2的逻辑给出对应的提示信息。
以上3点,是基于UI层面的逻辑拆解,看起来不复杂,但进一步拆解为技术点时会发现,里面有很多难点,比如:
1、怎么获得输入框的光标位置?
2、当光标更改时,如何拆解出对应的公式,并修改Tip的内容给出对应的提示?
3、怎么判断输入、点击、光标变更的事件,如何在合适的时机弹出Helper Tips?
这几个问题都是大坑,我会把这个话题分三个部分,把这些问题一一处理掉。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
一、解决问题3——如何在合适的时机弹出Helper Tips ?
这个问题,如果正面强攻,会非常麻烦,不过好在我们只需要“重写”SpreadJS现有的内容,而不需要自己再造一套轮子。因此我们可以通过MutationObserver监听SpreadJS的弹窗,再修改原有的内容为自定义内容即可。
注:MutationObserver监听是异步的,但它是微任务,优先级高于Dom渲染,不用担心会出现原界面“闪现”的问题。
代码如下:
- // 监听host更改,修改func helps内容(依赖SpreadJS自己的逻辑)
- function observeChange(formulaHelper){
- const targetNode = document.getElementById('ss');
- const config = { childList: true };
- const callback = function(mutationsList, observer) {
- for(let mutation of mutationsList) {
- if (mutation.type === 'childList') {
- if(mutation.addedNodes && mutation.addedNodes.length > 0){
- let addedNodes = mutation.addedNodes;
- for(let i=0; i<addedNodes.length; i++){
- let node = addedNodes[i];
- // gcsj-func-help-popup 是参数提醒
- // gcsj-func-ac-popup 是函数提醒
- if(node.classList[0] === "gcsj-func-help-popup" || node.classList[0] === "gcsj-func-ac-popup" ){
- const nodeObserver = new MutationObserver((mutationsList, observer) => {
- mutationsList.forEach((mutationRecord) => {
- nodeObserver.disconnect();
- // console.log(node);
- mutationRecord.target.innerText = formulaHelper.showForCasual(node);
- nodeObserver.observe(node, {attributes: true, childList: true});
- });
- });
- nodeObserver.observe(node, {attributes: true, childList: true})
- }
- }
- }
- }
- }
- };
- const observer = new MutationObserver(callback);
- observer.observe(targetNode, config);
- return observer;
- }
复制代码
关于其它的问题,请关注后续的Part II和Part III
完整代码参考附件。
|
|