前言:前几天没事干写了个小网站,打算用原生的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. python if条件判断语句

    if的基本格式 if语句用来做判断,并选择要执行的语句分支.基本格式如下: if CONDITION1: code_block(1) elif CONDITION2: code_block(2) el ...

  2. 部署vmware-vcsa 6.5

    介绍一下vcsa vsphere的两个最重要的组件是esxi和vcenter server,esxi是虚拟化主机管理软件,而vcenter server则是管理.组织多台esxi主机的管理中心. es ...

  3. 安装LoadRunner时提示缺少vc2005_sp1_with_atl_fix_redist解决方案

    操作系统重装后,安装LoadRunner11时,会报缺少vc2005_sp1_with_atl_fix_redist错误,类似下图所示: LR自动安装失败,在网上下载此组件安装后依然提示此信息,最终解 ...

  4. Packet for query is too large (12238 > 1024). You can change this value

    MySQL max_allowed_packet 设置过小导致记录写入失败 mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_packet 参 ...

  5. vb.net 使用NPO各種格式設定

    '導入命名空間Imports System.IO Imports NPOI.HSSF.UserModelImports NPOI.HPSFImports NPOI.POIFS.FileSystem P ...

  6. 人类阅读的优越方式打印php数组

    在程序开发过程中:打印数据进行查看调试是非常频繁的:如果没有一种易于阅读的样式那是相当痛苦的:先定义一个数组: $array=array( 't0'=>'test0', 't1'=>'te ...

  7. 带你使用JS-SDK自定义微信分享效果

    前言 想必各位在写wap端时都遇到过这样的场景吧 ----自定义分享标题.图片.描述 接下来小编给大家讲解下分享相关操作 预期效果 原始的分享效果: 使用微信JS-SDK的分享效果: 可以看出缩略图, ...

  8. 记录微信小程序报错 Unexpected end of JSON input;at pages/flow/checkout page getOrderData function

    微信小程序报错 Unexpected end of JSON input;at pages/flow/checkout page getOrderData function 这个报错是在将数组对象通过 ...

  9. 浅谈css中的盒模型(框模型)

    css中的盒模型是css的基础,盒模型的理解可以帮助我们进行对样式进行修改.废话不多说,进入正题: 在w3c中,CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边框.边框 和 外边 ...

  10. 洛谷P1792 [国家集训队]种树(链表 贪心)

    题意 题目链接 Sol 最直观的做法是wqs二分+dp.然而还有一种神仙贪心做法. 不难想到我们可以按权值从大到小依次贪心,把左右两边的打上标记,但这显然是错的比如\(1\ 231\ 233\ 232 ...