Angular 实现输入框中显示文章标签的实例代码


Posted in Javascript onNovember 07, 2018

很多网站发帖的时候标签输入框看起来像是在 <input> 元素中直接显示标签. 比如这种

Angular 实现输入框中显示文章标签的实例代码

Angular 实现输入框中显示文章标签的实例代码

一开始以为是把 <span> 放在 <input> 中, 看了下 Stack Overflow 和 SegmentFault 的实现方式, 原来是用一个 <div> 把 <span> 和 <input> 包起来, 然后让 <div> 模仿出输入框的样式. 再给 <div> 加上eventListensor, 点击 <div> 时, 使 <input> 获得焦点.

StackBlitz 上的 Demo

在 Angular 中的实现

将各个tag用 <span> 显示, 在同一行放一个 <input> 用来输入新的标签, 然后用一个 <div> 将它们包起来

<div>
 <span *ngFor="let tag of tags">{{tag}}</span>
 <input type="text">
</div>

之后给 <div> 加上一个事件监听器, 点击 <div> 的时候, 激活 <input> . 为了能够获取 <input> 元素, 使用 Angular的 Template reference variables 来命名 <input> .

<div (click)="focusTagInput()">
 <span *ngFor="let tag of tags">{{tag}}</span>
 <input #tagInput type="text">
</div>

在component中获得 <input> 元素

export class EditorComponent {
 // 用 @ViewChild 获得 DOM 元素
 @ViewChild('tagInput') tagInputRef: ElementRef;

 focusTagInput(): void {
  // 让 input 元素获得焦点
  this.tagInputRef.nativeElement.focus();
 }
}

到此基本上整体思路就实现了. 接下来就是完善一下细节. 比如

输入完一个标签后, 按逗号或者空格自动将输入的标签添加到前面的标签列表中
给标签加上一个删除按钮

当输入框是空的时候, 按键盘的退格键可以删除标签列表中最后一个标签
我们一步一步来.

自动将标签加入标签列表

给 <input> 元素添加一个事件监听, 可以监听键盘按下了哪个键. 和键盘按键有关的事件有 keydown , keypress , keyup .

根据 MDN 上的解释, keydown 和 keypress 都是在按键按下之后触发, 不同点在于, 所有按键都可以触发 keydown , 而 keypress 只有按下能产生字符的键时才触发, shift , alt 这些按键不会触发 keypress . 而且 keypress 从 DOM L3 之后就弃用了.

keyup 就是松开按键的时候触发.

首先给 <input> 标签添加事件监听 (这里用的 keyup , 后面会解释为什么不用 keydown ).

<input #tagInput type="text" (keyup)="onKeyup($event)">

component 中对接收到的 KeyboardEvent 进行处理

onKeyup(event: KeyboardEvent): void {
 // 这里将标签输入框作为 FormGroup 中的一个 control
 const inputValue: string = this.form.controls.tag.value;

 // 检查键盘是否按下了逗号或者空格, 而且得要求
 if (event.code === 'Comma' || event.code === 'Space') {
  this.addTag(inputValue);
  // 将新输入的标签加入标签列表后, 把输入框清空
  this.form.controls.tag.setValue('');
 }
}

addTag(tag: string): void {
 // 去掉末尾的逗号或者空格
 if (tag[tag.length - 1] === ',' || tag[tag.length - 1] === ' ') {
  tag = tag.slice(0, -1);
 }
 // 有可能什么也没输入就直接按了逗号或者空格, 如果已经在列表中, 也不添加
 // 这里使用了 lodah 的 find
 if (tag.length > 0 && !find(this.tags, tag)) {
  this.tags.push(tag);
 }
}

使用 keyup 而不是 keypress 的原因:

一开始我是用的 keypress , 但是 keypress 触发的时候, <input> 还没接收到按键的值, 所以就会出现标签添加到列表, 并且清空输入框后, 输入框才接收到按下的逗号, 于是刚刚清空的输入框中就出现了一个逗号.

keyup 是在释放按键之后才触发, 此时输入框已经接收到按下的逗号的值, 再清空输入框的时候就能把逗号一起清除掉

给标签加上一个删除按钮

就在每个标签旁边添加一个叉号 × , 点击的时候, 把标签从列表中移除就行了

<div (click)="focusTagInput()">
 <span *ngFor="let tag of tags">
  {{tag}}
 <span (click)="removeTag(tag)">×</span>
 </span>
 <input #tagInput type="text" (keyup)="onKeyup($event)">
</div>
removeTag(tag: string): void {
 this.tags.splice(-1);
}

按下退格键删除最后一个标签

不需要给DOM添加别的事件监听, 只需要对component中的方法稍加修改即可

onKeyUp(event: KeyboardEvent): void {
 const inputValue: string = this.form.controls.tag.value;
 // 按下退格键, 且输入框是空的时候, 删除最后一个标签
 if (event.code === 'Backspace' && !inputValue) {
  this.removeTag();
  return;
 } else {
  if (event.code === 'Comma' || event.code === 'Space') {
   this.addTag(inputValue);
   this.form.controls.tag.setValue('');
  }
 }
}

// 修改参数为可选参数, 当没有参数时, 删除列表中最后一个,
// 有参数时, 删除传入的标签
removeTag(tag?: string): void {
 if (!!tag) {
  // 这里使用了 lodash 的 pull
  pull(this.tags, tag);
 } else {
  this.tags.splice(-1);
 }
}

接下来就是调整样式了. 就略过了

不足之处

  • 使用中文输入法输入完一个词按下空格时, 会直接把输入的内容加到列表里
  • 使用中文输入法时, 按下退格键, 如果输入框里没有别的内容, 会直接删除列表中最后一个标签

总结

以上所述是小编给大家介绍的Angular 实现输入框中显示文章标签的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript实现了照片拖拽点击置顶的照片墙代码
Apr 03 Javascript
javascript实现检验的各种规则
Jul 31 Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 Javascript
一起学写js Calender日历控件
Apr 14 Javascript
Javascript自执行匿名函数(function() { })()的原理浅析
May 15 Javascript
vue打包后显示空白正确处理方法
Nov 01 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
Jul 20 Javascript
浅析Vue实例以及生命周期
Aug 14 Javascript
Vue2.0生命周期的理解
Aug 20 Javascript
JS编写兼容IE6,7,8浏览器无缝自动轮播
Oct 12 Javascript
小程序关于请求同步的总结
May 05 Javascript
Layui 动态禁止select下拉的例子
Sep 03 Javascript
VueCli3构建TS项目的方法步骤
Nov 07 #Javascript
vue调试工具vue-devtools安装及使用方法
Nov 07 #Javascript
vue+webpack中配置ESLint
Nov 07 #Javascript
利用jqgrid实现上移下移单元格功能
Nov 07 #Javascript
React 源码中的依赖注入方法
Nov 07 #Javascript
监听angularJs列表数据是否渲染完毕的方法示例
Nov 07 #Javascript
详解react native页面间传递数据的几种方式
Nov 07 #Javascript
You might like
php中通过虚代理实现延迟加载的实现代码
2011/06/10 PHP
利用浏览器的Javascript控制台调试PHP程序
2014/01/08 PHP
PHP中预定义的6种接口介绍
2015/05/12 PHP
在Mac OS上编译安装Nginx+PHP+MariaDB开发环境的教程
2016/02/23 PHP
PHP封装类似thinkphp连贯操作数据库Db类与简单应用示例
2019/05/08 PHP
Sample script that displays all of the users in a given SQL Server DB
2007/06/16 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
JS判断表单输入是否为空(示例代码)
2013/12/23 Javascript
高性能JavaScript DOM编程(1)
2015/08/11 Javascript
轻松实现JavaScript图片切换
2016/01/12 Javascript
浅谈js构造函数的方法与原型prototype
2016/07/04 Javascript
React Native之TextInput组件解析示例
2017/08/22 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
2019/09/27 jQuery
javascript设计模式 ? 命令模式原理与用法实例分析
2020/04/20 Javascript
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
python判断、获取一张图片主色调的2个实例
2014/04/10 Python
使用Python求解最大公约数的实现方法
2015/08/20 Python
浅谈python中scipy.misc.logsumexp函数的运用场景
2016/06/23 Python
详解django中自定义标签和过滤器
2017/07/03 Python
Python实现的删除重复文件或图片功能示例【去重】
2019/04/23 Python
python实现微信小程序用户登录、模板推送
2019/08/28 Python
浅谈Python中re.match()和re.search()的使用及区别
2020/04/14 Python
浅谈Python爬虫原理与数据抓取
2020/07/21 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
迟到检讨书900字
2014/01/14 职场文书
给面试官的感谢信
2014/02/01 职场文书
高等教育学自荐书范文
2014/02/10 职场文书
岗位职责风险点
2014/03/12 职场文书
超市创意活动方案
2014/08/15 职场文书
列车乘务员工作不细心检讨书
2014/10/07 职场文书
政风行风评议工作总结
2014/10/21 职场文书
医生见习报告范文
2014/11/03 职场文书
党校培训学习心得体会
2016/01/06 职场文书
Python 中random 库的详细使用
2021/06/03 Python
JVM的类加载器和双亲委派模式你了解吗
2022/03/13 Java/Android
大脑的记忆过程在做数据压缩,不同图形也有共同的记忆格式
2022/04/29 数码科技