前言:前几天没事干写了个小网站,打算用原生的javascript实现元素的拖动,但是事情并没有想象的那么顺利,首先是实现了拖动的元素卡的不能再卡,简直不能够,上图~~

看见没?这就是效果,简直让人欲哭无泪啊,查了大量的资料也无济于事,根本就没有人会遇到过这个问题,但是经过N次试验,终于找到了原因——竟然是我给这个元素添加了transition属性导致的,元凶:

去掉这个属性之后,就变得完全不一样了

至于原因,我现在也不知道为什么,很无奈╮(╯▽╰)╭

接下来就是性能优化了,我原来的实现方式是给元素添加一个mousemove事件,然后判断事件对象的buttons是否为1,如果是1的话表明此时左键按下,然后记录此时鼠标的x和y的坐标,当下次触发mousemove事件的时候用当前鼠标的位置减去上次记录的鼠标的位置就是鼠标移动的距离,然后用元素当前的位置加上鼠标移动的距离就实现了拖动,代码如下:

//实现拖动
var lastClientX = 0;
var lastClientY = 0;
var count = 0;
addCommandCard.addEventListener('mousemove', function() {
if(arguments[0].buttons == 1) {
addCommandCard.style.cursor = "default";
arguments[0].preventDefault();
if(count == 0) {
lastClientX = arguments[0].clientX;
lastClientY = arguments[0].clientY;
count++;
} else {
addCommandCard.style.left = addCommandCard.offsetLeft + arguments[0].clientX - lastClientX + "px";
addCommandCard.style.top = addCommandCard.offsetTop + arguments[0].clientY - lastClientY + "px";
lastClientX = arguments[0].clientX;
lastClientY = arguments[0].clientY;
count++;
}
}
});

今天看了个实现拖动的代码,基本思路是,给元素添加mousedown事件,在这个事件处理程序中,首先记录当前鼠标的位置与元素的offsetLeft和offsetTop的差值,然后给document添加mousemove和mouseup事件,在document的mousemove事件中,将元素的left设置为当前鼠标X坐标减去上面记录的鼠标X坐标和元素offsetLeft的差值,top值设置为当前鼠标Y坐标减去上面记录的鼠标Y坐标和元素offsetTop的差值,在mouseup事件中,设置document的mousemove和mouseup为null,上面的话可能有些拗口,通俗点说就是首先记录元素的左边框和鼠标X坐标的差值,然后记录元素的上边框和鼠标Y坐标的差值,在鼠标移动的时候将元素的左边框的值设置为鼠标当前X坐标的值减去鼠标和元素左边框之间的相对距离,上边框类似,因为在元素拖动的过程中,鼠标和元素的相对位置始终没有发生变化,所以只要用鼠标当前的位置减去鼠标和元素之间的相对距离就是元素拖动后的位置,代码:

//实现拖动
addCommandCard.addEventListener('mousedown', function() {
arguments[0].preventDefault();
var disX = arguments[0].clientX - addCommandCard.offsetLeft;
var disY = arguments[0].clientY - addCommandCard.offsetTop; document.onmousemove = function() {
addCommandCard.style.left = arguments[0].clientX - disX + 'px';
addCommandCard.style.top = arguments[0].clientY - disY + 'px';
} document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
} });

总结:在chrome中测试结果表明,两种拖动方式都可以稳定在60fps,总得来说,差别不大,但是第一种有比较慢明显的缺点,首先,第一种给元素添加了mousemove事件,那就意味着不管元素当前是否拖动,只要有鼠标移动到元素上,这个事件就不断的触发,虽然只有一条判断语句,但是造成性能的白白浪费,而第二种是添加了mousedown事件,只有鼠标按下的时候才会触发,所以没有这个问题,但是,如果在别处给document指定了mousemove和mouseup事件,那么在元素拖动开始和结束之后,这些事件处理程序会变得无效,因为覆盖的原因,但是可以通过DOM2级事件处理程序来解决,不算大问题

JavaScript实现元素拖动性能优化的更多相关文章

  1. (转)Javascript的DOM操作 - 性能优化

    转载:https://my.oschina.net/blogshi/blog/198910 摘要: 想稍微系统的说说对于DOM的操作,把Javascript和jQuery常用操作DOM的内容归纳成思维 ...

  2. javascript 作用域链及性能优化

    在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象.函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性.其中一个内部属 ...

  3. 学习javascript总结下来的性能优化的小知识(一)

    http://www.cnblogs.com/ctriphire/p/4115525.html http://www.cnblogs.com/xjchenhao/archive/2012/10/22/ ...

  4. Web前端性能优化进阶——完结篇

    前言 在之前的文章 如何优化网站性能,提高页面加载速度 中,我们简单介绍了网站性能优化的重要性以及几种网站性能优化的方法(没有看过的可以狂戳 链接 移步过去看一下),那么今天我们深入讨论如何进一步优化 ...

  5. JavaScript 性能优化技巧分享

    JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上 ...

  6. JavaScript性能优化

    如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...

  7. javascript性能优化-repaint和reflow

    repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...

  8. 摘:JavaScript性能优化小知识总结

    原文地址:http://www.codeceo.com/article/javascript-performance-tips.html JavaScript的性能问题不容小觑,这就需要我们开发人员在 ...

  9. [转]JavaScript 的性能优化:加载和执行

    原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化: ...

随机推荐

  1. 第5章 Linux上管理文件系统

    5.1 机械硬盘 机械硬盘由多块盘片组成,它们都绕着主轴旋转.每块盘片上下方都有读写磁头悬浮在盘片上下方,它们与盘片的距离极小.在每次读写数据时盘片旋转,读写磁头被磁臂控制着不断的移动来读取其中的数据 ...

  2. JVM(二)—— 类加载机制

    问题 1.为什么要有类加载机制(类加载机制的意义是什么) 2.类加载机制的过程,这些步骤可以颠倒顺序么?,每个步骤的作用是什么? 3.什么情况下必须对类进行初始化 类加载的过程 加载--验证--准备- ...

  3. js_ajax模拟form表单提交_多文件上传_支持单个删除

    需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中: 问题:由于只有一个file ...

  4. [译]如何在.NET Core中使用System.Drawing?

    你大概知道System.Drawing,它是一个执行图形相关任务的流行的API,同时它也不属于.NET Core的一部分.最初是把.NET Core作为云端框架设计的,它不包含非云端相关API.另一方 ...

  5. 升级ssh到OpenSSH_7.5p1

    Redhat 6.5 x64升级SSH到OpenSSH_7.5p1 为了防止openssh安装失败导致不能远程登录,先部署telnet服务以防万一. rpm -qa telnet telnet-ser ...

  6. 理解 Python 中的可变参数 *args 和 **kwargs:

    默认参数:  Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def getSum(x,y=5): print "x:", x print "y:& ...

  7. 6.3 OrderBy 优化

    1. 创建实例 create table tblA( age int, birth TIMESTAMP not null ); insert into tblA(age,birth) values(2 ...

  8. Go实现基于WebSocket的弹幕服务

    拉模式和推模式 拉模式 1.数据更新频率低,则大多数请求是无效的 2.在线用户量多,则服务端的查询负载高 3.定时轮询拉取,实时性低 推模式 1.仅在数据更新时才需要推送 2.需要维护大量的在线长连接 ...

  9. JS命名空间模式解析

    简介 在SF上看到这样一个提问: 如题,因为不得已的原因,需要写若干个全局函数.但又不想这样: window.a = function(){} window.b = function(){} wind ...

  10. cf1136E. Nastya Hasn't Written a Legend(二分 线段树)

    题意 题目链接 Sol yy出了一个暴躁线段树的做法. 因为题目保证了 \(a_i + k_i <= a_{i+1}\) 那么我们每次修改时只需要考虑取max就行了. 显然从一个位置开始能影响到 ...