解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题


Posted in Javascript onApril 21, 2020

说明

之前有一个angular项目,页面上表单不算多,也就一百来个(这个不固定,有的地方多,有的地方少),但是再输入的时候会造成输入延迟,反应不灵敏,对用户体验极其不好。还有一个功能就是拖拽功能(原生,没有使用官方中的拖拽功能),从左边拖到右边区域,拖拽区域少的时候还挺流畅,但一旦有几百上千的时候反应极其的慢

原因(?)

上面两个问题其实都和angular的机制有关。一个双向绑定一个拖拽归根结底都是因为angular的变化检测

angular的双向绑定主要是脏数据检查,如果大量的检查,效率比较低。(双向绑定时向zone挂载一个异步函数,对数据改变是做处理,及时将变化反馈显示在页面上)可能就会输入延迟

拖拽(也是向zone挂载异步函数)则是因为angular对每个可移动像素的元素进行检测而且还可能涉及对dom的操作,当拖拽区域数量较为多时,绑定的函数就越多,angular需要检测的元素区域就越来越多,处理起来就越力不从心(即使元素隐藏也不代表不会进行变化检测)

解决

  1. 对于双向绑定造成的输入延迟,停止使用双向绑定,改用单向绑定
  2. 拖拽过程angular一直检测页面变化,所以页面卡顿。我们需要做的就是设置对某些操作不跟踪变化
this.ngZone.runOutsideAngular(() => {
  this.dragEnter = this.rd.listen(spanDom, 'dragenter', this.dragenterHandler.bind(this));
  this.dragOver = this.rd.listen(spanDom, 'dragover', (e) => {
   e.preventDefault();
  });
 this.dragLeave = this.rd.listen(spanDom, 'dragleave', this.dragLeaveHandle.bind(this));
});
this.dragDrop = this.rd.listen(spanDom, 'drop', this.dropHandler.bind(this));

对频繁的操作(如dragover)不去触发变更检测。使用NgZone中的runOutsideAngular方法,angular不会对里面的变化进行跟踪。

ps:下面看下Angular 元素拖拽

  1. 拖动元素到指定区域
  2. 拖放的同时传递数据

1. 安装 ng2-drag-drop

npm install ng2-drag-drop --save

2. 模板中配置可拖拽元素

// drag.component.html
 <div>
  <a href="javascript:;" rel="external nofollow" *ngFor="let item of sysData" draggable [dragData]="item" [dragScope]="'system'">{{ item.name }}</a>
 </div>
  • draggable - 表明此元素时可拖拽的
  • [dragData] = 'item' - 在拖动过程中将item数据从draggable到droppable
  • [dragScope]="'system'" - 拖拽范围,和第三步[dropScope]="'system'"相对应;

3. 模板中配置拖拽元素所拖拽的目的地

// drag.component.ts
 <div droppable (onDrop)="onItemDrop($event)" [dropScope]="'system'"></div>
  • droppable - 第二步中拖拽的元素都将拖拽到有droppable指令的元素内;
  • (onDrop) - 当拖拽元素至此区域内后(鼠标释放后),触发onItemDrop方法,其中$event就是第二步中[dragData] = 'item'的item参数
  • [dropScope]="'system'" - 和第二步的[dragScope]="'system'"对应,[dragScope]="'system'"的拖拽元素只能拖拽到 [dropScope]="'system'"元素内;

4. ts文件

// drag.component.ts
export class DragComponent {

 const sysData = [
  {id: '1', name: '拖动元素1'},
  {id: '2', name: '拖动元素2'},
  {id: '3', name: '拖动元素3'},
  {id: '4', name: '拖动元素4'}
 ];

}

onItemDrop(e: any) {
 // data为拖拽时传递的数据 - item
 const data = e.dragData;
}

总结

到此这篇关于angular 中使用原生拖拽页面卡顿,表单控件输入延迟的文章就介绍到这了,更多相关angular 中使用原生拖拽页面卡顿,表单控件输入延迟内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript网页制作特殊效果用随机数
May 22 Javascript
javascript replace方法与正则表达式
Feb 19 Javascript
jqGrid随窗口大小变化自适应大小的示例代码
Dec 28 Javascript
很不错的两款Bootstrap Icon图标选择组件
Jan 28 Javascript
DOM操作原生js 的bug,使用jQuery 可以消除的解决方法
Sep 04 Javascript
深入理解jquery中的each用法
Dec 14 Javascript
关于Javascript中document.cookie的使用
Mar 08 Javascript
javascript遍历json对象的key和任意js对象属性实例
Mar 09 Javascript
Vue组件实例间的直接访问实现代码
Aug 20 Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
Feb 09 Javascript
Layui数据表格 前后端json数据接收的方法
Sep 19 Javascript
Vue如何循环提取对象数组中的值
Nov 18 Vue.js
javascript设计模式 ? 策略模式原理与用法实例分析
Apr 21 #Javascript
javascript设计模式 ? 备忘录模式原理与用法实例分析
Apr 21 #Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
Apr 20 #Javascript
Vue的全局过滤器和私有过滤器的实现
Apr 20 #Javascript
深入浅析JavaScript中的in关键字和for-in循环
Apr 20 #Javascript
vue实现购物车功能(商品分类)
Apr 20 #Javascript
vue实现淘宝购物车功能
Apr 20 #Javascript
You might like
法国:浪漫之都的咖啡文化
2021/03/03 咖啡文化
初探PHP5
2006/10/09 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
php获取mysql数据库中的所有表名的代码
2011/04/23 PHP
js几秒以后倒计时跳转示例
2013/12/26 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
js中获取键盘事件的简单实现方法
2016/10/10 Javascript
详解Bootstrap各式各样的按钮(推荐)
2016/12/13 Javascript
使用vue.js实现联动效果的示例代码
2017/01/10 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
微信小程序基于picker实现级联菜单
2019/02/15 Javascript
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
微信小程序实现搜索历史功能
2020/03/26 Javascript
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
VSCode 配置uni-app的方法
2020/07/11 Javascript
Javascript实现打鼓效果
2021/01/29 Javascript
[01:03:27]Optic vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
浅要分析Python程序与C程序的结合使用
2015/04/07 Python
Python中的hypot()方法使用简介
2015/05/18 Python
Python中type的构造函数参数含义说明
2015/06/21 Python
基于Python如何使用AIML搭建聊天机器人
2016/01/27 Python
对Python的Django框架中的项目进行单元测试的方法
2016/04/11 Python
Python用户推荐系统曼哈顿算法实现完整代码
2017/12/01 Python
ubuntu系统下使用pm2设置nodejs开机自启动的方法
2018/05/12 NodeJs
django框架单表操作之增删改实例分析
2019/12/16 Python
Smashbox官网:美国知名彩妆品牌
2017/01/05 全球购物
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
优秀的毕业生的自我评价
2013/12/12 职场文书
农民工工资承诺书范文
2014/03/31 职场文书
文秘个人求职信范文
2014/04/22 职场文书
教师求职信
2014/06/17 职场文书
音乐教师求职信
2014/06/28 职场文书
初中语文教学研修日志
2015/11/13 职场文书
python 三边测量定位的实现代码
2021/04/22 Python
JPA如何使用entityManager执行SQL并指定返回类型
2021/06/15 Java/Android