解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
程序员文章站
2022-03-07 09:25:25
说明之前有一个angular项目,页面上表单不算多,也就一百来个(这个不固定,有的地方多,有的地方少),但是再输入的时候会造成输入延迟,反应不灵敏,对用户体验极其不好。还有一个功能就是拖拽功能(原生,...
说明
之前有一个angular项目,页面上表单不算多,也就一百来个(这个不固定,有的地方多,有的地方少),但是再输入的时候会造成输入延迟,反应不灵敏,对用户体验极其不好。还有一个功能就是拖拽功能(原生,没有使用官方中的拖拽功能),从左边拖到右边区域,拖拽区域少的时候还挺流畅,但一旦有几百上千的时候反应极其的慢
原因(?)
上面两个问题其实都和angular
的机制有关。一个双向绑定一个拖拽归根结底都是因为angular
的变化检测
angular的双向绑定主要是脏数据检查,如果大量的检查,效率比较低。(双向绑定时向zone挂载一个异步函数,对数据改变是做处理,及时将变化反馈显示在页面上)可能就会输入延迟
拖拽(也是向zone挂载异步函数)则是因为angular
对每个可移动像素的元素进行检测而且还可能涉及对dom的操作,当拖拽区域数量较为多时,绑定的函数就越多,angular
需要检测的元素区域就越来越多,处理起来就越力不从心(即使元素隐藏也不代表不会进行变化检测)
解决
- 对于双向绑定造成的输入延迟,停止使用双向绑定,改用单向绑定
- 拖拽过程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. 安装 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 中使用原生拖拽页面卡顿,表单控件输入延迟内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!