JavaScript实现自定义短信模板

自定义短信模板,要求:可以插入关键字,当然是可以在点击到文本域中的任意位置,关键字以中括号包裹的形式出现【关键字】,删除关键字要整个关键都删掉,而不是自己全删除。

效果图

a.png

这里说下我的思路,要完成这样一个功能,分为以下几点:
1.在指定位置插入关键字
2.删除关键字要整个删除掉,并且关键字是不可编辑的,用户也是不可以输入中文中括号的

首先我们列一下难点

1.在任意位置插入,那肯定要拿到位置坐标,如果获取这个位置?
2.关键字是用中文中括号包裹的,那么用户就不可以去使用中文中括号,怎么阻止用户输入呢?
3.既然是关键字自然是不可以编辑的,怎么让它不可编辑?
4.中文中括号可英文中括号keyCode是一样的,怎么处理?
5.当编辑区域失去焦点的时候,我们立即点关键字肯定就是要插入,但是点击其他地方怎么处理?
6.删除关键字的时候,如何一次按键就整个都删掉?

现在我们来把上面的难点一一解答

1.关于光标位置,我上一篇文章中有写到,这里就不多说了,http://www.jianshu.com/p/19a507cd5fd7.
2.关于第2,3,4一起来说。首先为了防止我们识别关键字出问题,那么就要阻止用户自己输入中括号,说道阻止输入某个字符,大家很容想到,那就是在输入的瞬间就把它删除掉,这个没错。我们在判断按键为左中括号时候去删除的时候,会发现并不能完成整个中括号的删除,因为落下一个右中括号。没错,第一个坑出现了,这是为什么,大家有没有注意到,每次你输入中文中括号的时候,其实只需要按左边中括号就会左右都出现,大括号小括号都是这样。

【】按下左,左右一起出现

好,我们知道了问题所在,那就在右括号按下的时候删掉两个字符,可是,你会发现,如果只按右中括号的时候,他就真的只出现右中括号,所以呢,分开处理。
这次没问题了吧,可是你会发现依然是剩下右边的括号没删除,而且还把前面的括号前的一个字符删掉了,坑吧?这就是第二个坑,你在判断keyCode的时候其实会有三次,第一次是左中括号keyCode,第二次是右中括号,第三次是左箭头。而第二次第三次并不是你按下的,是第一按下之后自动带出的。所以当你按下左中括号之后,其实最后光标是跑到了括号中。

【|】

 obj.addEventListener('keyup', function(e) {
//每次在文本域中输入的时候都要获取其光标位置,以便于其他操作
cursorIndex = getFocus(obj);

//由于我们是禁止输入中文中括号的,而中文中括号输入左右情况不同,需要分别处理
if (e.keyCode == 219) {
    e.preventDefault();
    //这里获取到光标左侧的内容
    var leftChar = obj.value.slice(cursorIndex - 1, cursorIndex);

    //只有输入结束的是右中括号,而且它的前一个字符是左中括号才把它删除,防止把关键字删除掉
    if (/\】/g.test(leftChar) && obj.value.charAt(cursorIndex - 2) === '【') {
        obj.value = obj.value.slice(0, cursorIndex - 2) + obj.value.slice(cursorIndex, obj.value.length);
    }

} else if (e.keyCode == 221) {
    e.preventDefault();
    //右中括号就好办多了,因为它不会自动带出左中括号
    var leftChar = obj.value.slice(cursorIndex - 1, cursorIndex);
    if (/\】/g.test(leftChar)) {
        obj.value = obj.value.slice(0, cursorIndex - 1) + obj.value.slice(cursorIndex, obj.value.length);
    }
}
//防止上下左右键移动光标进入关键字中
if ((e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 38 || e.keyCode == 40) && lastKeyCode !== 219) {
    dealFocusMove(obj, cursorIndex);
} else if (e.keyCode == 8) {
    //backspace删除的时候删除整个关键字
    dealFocusL(obj, cursorIndex, allKeyWords);
} else if (e.keyCode == 46) {
    //delete删除的时候也是删除整个关键字
    dealFocusR(obj, cursorIndex, allKeyWords)
}
if (e.keyCode !== 37 && e.keyCode !== 39) {
    //这里防止手动按得左右键影响左中括号判断
    lastKeyCode = e.keyCode;
}
}, false);

那这咋搞,还要分别删除么?不用的,我们只要不让他跑到中间就可以了,对就是preventDefault()。有疑问了吧?没错,这个无法阻止中文按键。
关键字不可编辑,但是文本怎么能不编辑啊?编辑的关键是什么,就是有光标啊,那我们不让光标进入关键字不就行了,这里还顺带解决了的防止鼠标点击关键字中间。我想的思路是,关键字的中括号是成对出现的,那么光标进入了,光标前面的内容中中括号自然不是成对的,这就是判断条件,把它挪出来就可以了。当然从按左右键要分别处理,因为是向不同方向越过整个关键字,上下键就简单了,都放把光标设置在关键字左边就可以了。

if ((e.keyCode == 37 || e.keyCode == 39) && lastKeyCode === 219) {
    //这里是防止按下中文中括号左键的时候带动左右键的按下,这样保证光标一直在最后
    e.preventDefault();
}
b.jpg

3.怎么处理点击文本域,立即点击关键字是插入,点击其他地方之后再点击关键字不可插入?这里我定义了一个参数存储光标位置,当点击其他位置的时候就让光标置空,而点击关键字的时候判断一下光标位置是否存在就可以了

if (cursorIndex !== null) {
    //这里判断是否是我们要点击的是不是关键字
    if (e.target.tagName !== "TEXTAREA" && e.target.getAttribute('isFocus')) {
        //插入关键字

    } else if (e.target.tagName == "TEXTAREA" && e.target.getAttribute('isFocus')) {
        //点击文本区域操作
    } else {
        //点击其他地方要将光标位置置空,防止点击关键字添加
        cursorIndex = null;
    }
}

4.删除整个关键字,这里还是用关于如何防止光标进入关键字的方式。只要发现不成对,就把最近的另一半到光标之间的删除

【关键字| 或者 |关键字】

就是backspace和delete两种,当然在处理的时候用了一些小技巧,就是正则表达式的RegExp.lastIndex,最后一次匹配到的位置,还有其他,看代码吧。

代码地址地址https://github.com/Stevenzwzhai/plugs/tree/master/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A8%A1%E6%9D%BF-template

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容

  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,217评论 9 467
  • dpkg 学习 安装mysql apt-get install mysql-server-5.6 apt-get ...
    sharonji阅读 434评论 0 0
  • Vim几句话介绍Vim是Unix系统上的文本编辑软件(你该不会不知道什么是文本编辑软件吧!),在windows上也...
    何必遠方阅读 3,132评论 0 3
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,885评论 25 707
  • 秋风渐起,落叶萧瑟,硕果累累,这个季节,是成熟与别离的季节。 叶子开始慢慢变黄,变红,并逐渐枯萎。也许是从一场秋风...
    别山举水阅读 2,152评论 73 106