资讯专栏INFORMATION COLUMN

仿发微博插入话题功能 的 工具方法:textarea 获取光标坐标,获取、设置光标位置,获取所有、当

kyanag / 1381人阅读

摘要:源码获取中光标坐标获取中光标位置获取光标位置获取焦点前坐标中插入文本输入元素获取焦点获取光标位置在光标位置插入值输入元素获取焦点获取焦点前坐标获取焦点后坐标插入文字设置中光标位置设置话题颜色例如部分为红色暂未用到获取所有话题中文本

源码
// 获取 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 = "" + item + ""
        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
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104222.html

相关文章

  • 输入框插入表情实现

    摘要:还没结束上述例子中,在输入框中表情只能以文本的形式呈现。如果想在输入框中呈现输入的表情,该怎么办呢使用属性为的容器代替是必须的,因为中只能显示文本。 在普通的 textarea 中,只能显示普通的文本。如果简单的输入文本,textarea 便足以胜任。但是实际情况往往要复杂得多。 简单版本的插入表情 常见的版本一般都是使用 textarea,然后表情使用某种约定的文本格式代替,比如你好...

    TwIStOy 评论0 收藏0
  • 用Canvas实现文本编辑器(支持艺术字渲染与动画)

    摘要:项目中文字由进行渲染。待触发时,取消中文输入标记,将文字渲染到上。而其中一些有趣的细节实现如文本渲染,对中文笔画分割实现有趣的动画等并没有描写。 导言 目前富文本编辑器的实现主要有两种技术方案:一个是利用contenteditable属性直接对html元素进行编辑,如draft.js;另一种是代理textarea + 自定义div + 模拟光标实现。对于类似word的经典富文本编辑器,...

    OldPanda 评论0 收藏0
  • web 前端 @ 功能 JS 实现分析及其原理

    摘要:最近为实现一个新功能弄的焦头烂额的实现,在实现后写下些心得,供以后会跳入这坑的同志们参考。选人实现主要涉及步骤为。需要修改的代码,保存选区以及光标信息,用于获取在光标焦点离开前,光标的位置删除符号。这样就完成这一功能了。 最近为实现一个新功能弄的焦头烂额 @xxx 的实现,在实现后写下些心得,供以后会跳入这坑的同志们参考。 首先,当让是考虑使用范围,由于项目仅仅需要考虑在 WEBKIT...

    jsyzchen 评论0 收藏0
  • jQuery笔记总结篇

    摘要:希望在做所有事情之前,操作文档。不受层级限制子选择器在给定的父元素下匹配所有子元素。相邻选择器匹配所有紧接在元素后的元素。判断当前对象中的某个元素是否包含指定类名,包含返回,不包含返回下标过滤器精确选出指定下标元素获取第个元素。 原文链接 http://blog.poetries.top/2016... 首先,来了解一下jQuery学习的整体思路 showImg(https://seg...

    NoraXie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<