源码

// 获取 textarea 中光标坐标
const textareaCaret = require('textarea-caret');

function getCaretCoordinates($el) {
    let caret = textareaCaret($el, $el.selectionEnd);

    return {
        top: caret.top, 
        left: caret.left, 
        height: caret.height
    }
}

// 获取 textarea 中光标位置
function getCursorPosition($el) {
    var cursorPos = 0;
    if (document.selection) {
        // IE
        var fus = document.selection.createRange(); //获取光标位置 
        fus.moveStart('character', -$el.value.length);
        cursorPos = fus.text.length;

    } 
    if ($el.selectionStart || $el.selectionStart == 0) {
        var start = $el.selectionStart;   //获取焦点前坐标 
        cursorPos = start;
    }
    return cursorPos;
}

// textarea 中插入文本
function insertCursorText($el, text) {
  var cursorPos = 0;

  if (document.selection) {
      // IE
      $el.focus(); //输入元素textara获取焦点 
      var fus = document.selection.createRange(); //获取光标位置 

      fus.moveStart('character', -$el.value.length);
      cursorPos = fus.text.length;

      fus.text = text; //在光标位置插入值 
      $el.focus(); ///输入元素textara获取焦点 
  } else if ($el.selectionStart || $el.selectionStart == 0) {
      var start = $el.selectionStart;   //获取焦点前坐标 
      var end = $el.selectionEnd;   //获取焦点后坐标 

      cursorPos = start;

      // 插入文字
      $el.value = $el.value.substring(0, start) + text + $el.value.substring(end, $el.value.length);
  } else {
      $el.value += text;
  }

  return {
      value: $el.value,
      cursorPos: cursorPos
  }
}

// 设置 textarea 中光标位置
function setCursorPosition($el, pos) {
    if($el.setSelectionRange) {
        $el.focus();
        $el.setSelectionRange(pos, pos);
    } else if ($el.createTextRange) {
        var range = $el.createTextRange();
        range.collapse(true);
        range.moveEnd('character', pos);
        range.moveStart('character', pos);
        range.select();
    }
}

// 设置 “话题” 颜色 (例如:'#123#' 部分为红色) 【暂未用到】
function setTopicStyle(value) {
    var exp = /(#|#)((?!#).)*(#|#)/g
    value = value.replace(/<[^>]*?>(.*?)/gi, '').replace(/(.*?)<\/[^>]*?>/gi, '').replace(exp, (item) => {
        let newVal = '<span style="color:red">' + item + '</span>'
        return newVal
    })
    return value
}

// 获取所有话题, src : textarea 中文本
function parse(src) {

    return src.split(/(#[^#]+#)/).reduce((res, v, i, a) => {

        if (v.length > 1 && v.startsWith('#') && v.endsWith('#')) {
            res.list.push({
                tag: v.substring(1, v.length-1),
                index: res.index,
                completed: true
            });
            
        } else {
          if (i === a.length -1) {

              const parts = v.split('#');
              if (parts.length > 1) {
                  res.list.push({
                      tag: parts.pop(),
                      index: parts[0].length + res.index,
                      completed: false
                  });
              }
          }
        }

        res.index += v.length;

        return res;

    }, {list: [], index: 0});

}

// 获取当前话题 res: parse(src); caretPos: getCursorPosition($el)
function getCurrent(res, caretPos) {

    let current = null;

    res.list.some((v, i) => {
        if (v.index < caretPos && v.index + v.tag.length + 2 > caretPos) {
            current = v;
            return true;
        }

        return false;
    });

    return current;
}

export default {
    getCaretCoordinates,
    getCursorPosition,
    setCursorPosition,
    insertCursorText,
    setTopicStyle,
    parse, 
    getCurrent
}

大白
82 声望4 粉丝