解决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 相关文章推荐
通用JS事件写法实现代码
Jan 07 Javascript
javascript 禁止复制网页
Jun 11 Javascript
Jquery中获取iframe的代码
Jan 11 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
Apr 08 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
Jun 15 Javascript
基于Jquery制作图片文字排版预览效果附源码下载
Nov 18 Javascript
js中创建对象的几种方式
Feb 05 Javascript
JSON生成Form表单的方法示例
Nov 21 Javascript
详解Vue demo实现商品列表的展示
May 07 Javascript
解决jquery validate 验证不通过后验证正确的信息仍残留在label上的方法
Aug 27 jQuery
jquery实现轮播图特效
Apr 12 jQuery
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
Apr 14 Javascript
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
eAccelerator的安装与使用详解
2013/06/13 PHP
PHP动态编译出现Cannot find autoconf的解决方法
2014/11/05 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
使用PHP如何实现高效安全的ftp服务器(二)
2015/12/30 PHP
php利用ffmpeg提取视频中音频与视频画面的方法详解
2017/06/07 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
基于laravel缓冲cache的用法详解
2019/10/23 PHP
JavaScript类库D
2010/10/24 Javascript
关于JavaScript定义类和对象的几种方式
2010/11/09 Javascript
基于jquery的拖动布局插件
2011/11/25 Javascript
jquery中.add()的使用分析
2013/04/26 Javascript
jquery实现checkbox 全选/全不选的通用写法
2014/02/22 Javascript
jquery 新建的元素事件绑定问题解决方案
2014/06/12 Javascript
深入理解javascript构造函数和原型对象
2014/09/23 Javascript
JavaScript代码复用模式详解
2014/11/07 Javascript
js实现滑动触屏事件监听的方法
2015/05/05 Javascript
js实现鼠标点击文本框自动选中内容的方法
2015/08/20 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
Js 获取、判断浏览器版本信息的简单方法
2016/08/08 Javascript
JQuery动态添加Select的Option元素实现方法
2016/08/29 Javascript
JS封装通过className获取元素的函数示例
2016/12/20 Javascript
vue获取form表单的值示例
2019/10/29 Javascript
[01:12]DOTA2 2015年秋季互动指南
2015/11/10 DOTA
Python实现的弹球小游戏示例
2017/08/01 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
Python3实现英文字母转换哥特式字体实例代码
2020/09/01 Python
Python爬虫之Selenium鼠标事件的实现
2020/12/04 Python
日本面向世界,国际级的免税在线购物商城:DOKODEMO
2017/02/01 全球购物
卡骆驰英国官网:Crocs英国
2019/08/22 全球购物
大学生学年自我鉴定
2014/02/10 职场文书
小学师德师风整改措施
2014/10/27 职场文书
会议开幕词
2015/01/28 职场文书
python 实现德洛内三角剖分的操作
2021/04/22 Python
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
springboot用户数据修改的详细实现
2022/04/06 Java/Android