解决 Codemirror 5 快速点击导致光标定位不准的问题

2,229 阅读2分钟

需求说明

数据浏览器对象浏览页面中,鼠标随意快(慢)速点击SQL编辑区,记住鼠标最后一次点击的位置,双击左侧表名(字段名)时自动复制表名(字段名)到最后一次点击的位置。

微信图片_20210508101104.png

解决方案

1、刚开始走了一些弯路,以为在编辑器中监听获取焦点 focus 事件记录光标最后的位置,然后在左侧双击时自动填充名称到已记录的光标处,这个的确实现了所需功能,但是在后来测试中发现如果鼠标随意快速点击编辑区,记住的最后一次光标位置并不准确,且没有任何规律性,猜测是因为点击过快 focus 监听事件无法实时记录光标位置导致的。

2、在重新查阅官方文档 codemirror.net/ 后发现应该用 cursorActivity 监听事件: Will be fired when the cursor or selection moves, or any change is made to the editor content.(当光标或选区移动或对编辑器内容进行任何更改时,将触发该事件。) 因为官方文档是全英文的,查阅起来有点困难,费了一些时间。

3、在 cursorActivity 事件中就可以实时记录光标的位置了,再也不用担心鼠标的任性快慢操作了,然后双击左侧名称就可以自动填充到最后一次光标记录的位置了,下面贴出部分代码片段仅供参考,需要根据自己项目情况有选择使用。

代码片段

codeEditor.vue 组件中:

<template>
  <div class="code-editor-container">
    <textarea ref="mycode" v-model="curCode" class="code-w"></textarea>
  </div>
</template>

<script>
import CodeMirror from 'codemirror/lib/codemirror'
import "codemirror/theme/ambiance.css"
import "codemirror/lib/codemirror.css"
require("codemirror/mode/javascript/javascript");
require("codemirror/mode/sql/sql");
require("codemirror/addon/edit/matchbrackets");
require("codemirror/addon/selection/active-line");
require("codemirror/addon/hint/show-hint");
require("codemirror/addon/hint/sql-hint");
import "codemirror/addon/hint/show-hint.css"
import sqlFormatter from "sql-formatter"
import bus from '@/utils/bus'

export default {
  components: {},
  data() {
    return {
      curCode: '',
      codeE: '',
      cmOptions: {
        value: '',
        mode: "text/x-mariadb",
        indentWithTabs: true,
        smartIndent: true,
        lineNumbers: true,
        autoRefresh: true,
        matchBrackets: true,
        styleActiveLine: true,
        lineWrapping: true,
        hintOptions: {
          completeSingle: false
        }
      }
    }
  },
  mounted() {
    this._initialize();
  },
  methods: {
    _initialize() {
      // 初始化编辑器实例,传入需要被实例化的文本域对象和默认配置
      this.codeE = CodeMirror.fromTextArea(this.$refs.mycode, this.cmOptions);
      this.codeE.on('focus', (code) => {
        // 记录光标位置的代码不写在这里
      });
      this.codeE.on('cursorActivity', (e) => {
        // console.log('eee === ', e);
        let codeData = {
          getCursor: { // 获取光标位置
            line: e.doc.getCursor().line,
            ch: e.doc.getCursor().ch
          },
          codeE: this.codeE
        };
        // console.log('codeData.getCursor === ', codeData.getCursor);
        bus.$emit('codeEditorGetCursor', codeData);
      })
    },
  }
}

对象浏览 objectBrowse.vue 组件中:

bus.$on('codeEditorGetCursor', (codeData) => { // 获取编辑器焦点
  this.codeData = codeData
});

// 双击事件函数中
let pos1 = this.codeData.getCursor;
let pos2 = {};
// console.log('setCode pos1 === ', pos1);
if (pos1) {
  pos2.line = pos1.line;
  pos2.ch = pos1.ch;
  this.codeData.codeE.setCursor(pos2); // 设置光标位置
  this.codeData.codeE.replaceRange('这里是你要填充的内容', pos2) // 替换光标位置的内容
}



至此,实现所需需求。

如有侵权,请联系我删除! 转载请注明出处!仅供学习交流!