前言:前几天没事干写了个小网站,打算用原生的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. Unicode 是不是只有两个字节,为什么能表示超过 65536 个字符

      Unicode 目前规划的总空间是17个平面(平面0至16),0x0000 至 0x10FFFF.每个平面有 65536 个码点.你只是大致知道平面0(「Basic Multilingual Pl ...

  2. CSS语法基础

    引言:CSS语法 CSS规则由两个主要的部分构成:选择器,以及一条或者多条声明. selector { property: value; property: value; ... property: ...

  3. Python机器学习笔记——随机森林算法

    随机森林算法的理论知识 随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法.随机森林非常简单,易于实现,计算开销也很小,但是它在分类和回归上表现出非常惊人的性能,因此,随机森林被誉为“代 ...

  4. Linux comm命令求出文件的交集、差集

    A(1,2,3)和B(3,4,5),A和B的交集是3,A对B的差集是1和2,B对A的差集是4和5,A和B求差的结果是1.2.4.5. 在Linux中可以使用comm命令求出这些集. [root@xue ...

  5. [转]BTC手续费计算,如何设置手续费

    本文转自:https://blog.csdn.net/servletcome/article/details/81941334 首先BTC的交易手续费和交易金额是没有关系的.不要误认为交易的金额越大手 ...

  6. MyBatis3-配置使用log4j输出日志

    配置步骤: 1.POM的依赖引入 <!-- log4j --> <!-- https://mvnrepository.com/artifact/log4j/log4j --> ...

  7. 开发谷歌浏览器插件会上瘾,搞了一个JSONViewer,一个页面格式化多条JSON,提升工作效率

    最近写了一个谷歌浏览器插件(Chrome extension),拿出来分享下,希望能提升大家的工作效率. 一.背景 先说痛点:日常开发中,经常需要不停的把接口输出的JSON拷贝到在线JSON格式化页面 ...

  8. 使用NetDrive将虚拟机映射到本地磁盘,使用smba映射本地磁盘(替代FileZilla)

    使用NetDrive映射到本地磁盘 使用NetDrive软件来替代FileZilla,NetDrive是一个能把FTP空间虚拟成本地硬盘的软件,这样我们就不需要再使用FileZilla来来回拷贝文件了 ...

  9. Eclipse中SVN插件的安装和配置(在线安装)

    公司项目中用到了svn来管理项目,然后需要在Eclipse中进行配置.网上参考了很多资料,离线安装的方式装上了,但是导入项目后报错,可能是离线安装包的问题.然后又采用了Eclipse在线安装的方式,总 ...

  10. Mac下写博客工具MarsEdit相关资料

    参考资料: https://www.maoshu.cc/967.html 下载地址: https://www.red-sweater.com/marsedit/ 博客园的配置: http://www. ...