上篇文章分享了如何用面向对象思想编写选项卡,在文章最后留了一个拖拽的例子,希望大家可以试着写一下,现在我就谈谈我在这过程中遇到的一些问题和解决方法。(本文主要是想和js初学者分享经验,代码中的更改this指向,事件绑定均采用的比较初级的方法,也希望能有大神能指导,分享一下经验)。

现在我们来看看面向过程式的编程的代码,HTML只有一个div元素,设置宽高和背景颜色。

#div1{width: 100px;height: 100px;background: red;position: absolute;}
<body><div id='div1'></div>
</body>
window.onload=function(){var oDiv=document.getElementById('div1');var disX=0;var disY=0;oDiv.onmousedown=function(ev){var ev=ev || window.event;disX=ev.clientX-oDiv.offsetLeft;disY=ev.clientY-oDiv.offsetTop;document.onmousemove=function(ev){var ev=ev || window.event;oDiv.style.left=ev.clientX-disX+'px';oDiv.style.top=ev.clientY-disY+'px';};document.onmouseup=function(){document.onmousemove=null;document.onmouseup=null;}return false;}}

还是用上一篇文章提到的方法,先将变量和方法提取出来,不要出现函数的嵌套,出现嵌套的将其中的函数提取出来。变量为oDiv,disX和disY,我将代码中的三个事件绑定的函数命名为fnDown,fnMove,fnUp,因此将上面的代码改为如下格式:

var oDiv,disX,disY;window.onload=function(){oDiv=document.getElementById('div1');disX=0;disY=0;oDiv.onmousedown=fnDown();}function fnDown(ev){var ev=ev || window.event;disX=ev.clientX-oDiv.offsetLeft;disY=ev.clientY-oDiv.offsetTop;document.onmousemove=fnMove();document.onmouseup=fnUp();return false;}function fnMove=function(ev){var ev=ev || window.event;oDiv.style.left=ev.clientX-disX+'px';oDiv.style.top=ev.clientY-disY+'px';};function fnUp=function(){document.onmousemove=null;document.onmouseup=null;}

然后用面向对象的思想将属性和方法添加到对象中,并在属性和方法前面加上this,因此改变的代码如下:

window.onload=function(){var d1=new Drag('div1');d1.init();};function Drag(id){this.oDiv=document.getElementById(id);this.disX=0;this.disY=0;};Drag.prototype.init=function(){this.oDiv.onmousedown=this.fnDowm();};Drag.prototype.fnDowm=function(ev){var ev=ev || window.event;this.disX=ev.clientX-this.oDiv.offsetLeft;this.disY=ev.clientY-this.oDiv.offsetTop;document.onmousemove=this.fnMove();document.onmouseup=this.fnUp();return false;};Drag.prototype.fnMove=function(ev){var ev || window.event;this.oDiv.style.left=ev.clientX-this.disX+'px';this.oDiv.style.top=ev.clientY-this.disY+'px';};Drag.prototype.fnMove=function(){document.onmousemove=null;document.onmouseup=null;};

和前面一样,找出其中this的指向错误并改正。但是除了this指向问题,上面还有一个关于事件的问题。document.onmousemove=this.fnMove();,向这样在事件上添加方法的方式是不正确的,正确的调用方式是这样:document.onmousemove=function(ev){};,因此将方法改为以下形式。

Drag.prototype.init=function(){this.oDiv.onmousedown=function(ev){var ev=ev || window.event;this.fnDown(ev);return false;};};Drag.prototype.fnDown = function(ev){this.disX = ev.clientX - this.oDiv.offsetLeft;this.disY = ev.clientY - this.oDiv.offsetTop;document.onmousemove = function(ev){var ev = ev || window.event;this.fnMove(ev);};document.onmouseup=function(){this.fnUp();}};Drag.prototype.fnMove=function(ev){this.oDiv.style.left=ev.clientX-this.disX+'px';this.oDiv.style.top=ev.clientY-this.disY+'px';};Drag.prototype.fnUp=function(){document.onmousemove=null;document.onmouseup=null;};

最后要找到错误的this指向,并改正。关于this指向,我认为最简单的方法就是看函数是怎么调用的,函数名 '.' 左边的就是this的指向。下面我们来举个例子:

Drag.prototype.init=function(){this.oDiv.onmousedown=function(ev){var ev=ev || window.event;this.fnDown(ev);return false;};};

原型上面的init()方法的调用方式是d1.init(),因此函数内的this指向就是d1,那么this.oDiv指向就是正确的,但是onmouseover()的调用方式是this.oDiv.onmousedown,其内部this指向就是this.oDiv,而在该函数内部,this.fnDown(ev)语句this指向是oDiv,而oDiv是没有方法和属性的,因此这里的this指向就是错误的,需要修正。
下面的几个方法中this也这来来分析,并将其改为正确的指向。修改this的指向还是和上一篇修改的方法一样。因此改完后代码为:

window.onload=function(){var d1=new Drag('div1');d1.init();};function Drag(id){this.oDiv=document.getElementById(id);this.disX=0;this.disY=0;}Drag.prototype.init=function(){var This=this;this.oDiv.onmousedown=function(ev){var ev=ev || window.event;This.fnDown(ev);return false;};};Drag.prototype.fnDown = function(ev){var This = this;this.disX = ev.clientX - this.oDiv.offsetLeft;this.disY = ev.clientY - this.oDiv.offsetTop;document.onmousemove = function(ev){var ev = ev || window.event;This.fnMove(ev);};document.onmouseup=function(){This.fnUp();}};Drag.prototype.fnMove=function(ev){this.oDiv.style.left=ev.clientX-this.disX+'px';this.oDiv.style.top=ev.clientY-this.disY+'px';};Drag.prototype.fnUp=function(){document.onmousemove=null;document.onmouseup=null;};

这样就可以正常运行了。


作为一名小白,就应该多动脑,多动手。在这过程中你会学到很多。通过以上方法来训练面向对象的编程思想,多练习,以后写出面向对象思想的代码就很简单了。

因为以上代码也是我通过看视频学的,所以还有点疑问,希望有人能解答一下。上面只有onmousedown时间是绑定在oDiv上,后面的时间都是绑定在document上,我试着将后面的事件也绑定在oDiv中,程序也能运行,但是快速拖动就会产生停顿的问题,而在document上就没有类似的情况,这是为什么?

前端小白用面向对象思想实现元素拖拽相关推荐

  1. dom 元素拖拽实现

    文章目录 原生 JS 实现 div 拖拽 HTML 拖拽 API REF   之前找实习的时候,面试官出了道 "原生 JS 实现 div 元素拖拽",当时实现了个大概,不过很多细节 ...

  2. jquery回弹_创意网页DOM元素拖拽弹性反弹和变形动画特效

    这是一款非常有创意的HTML网页DOM元素拖拽弹性反弹和变形动画特效.这个特效中有两种效果:第一种是弹性模态窗口效果,第二种是弹性幻灯片效果.这两种效果均可以拖拽DOM元素,然后释放它们时生成非常震撼 ...

  3. 实现元素拖拽放大缩小_Vue实战067:DOM元素拖拽效果的实现

    DOM元素拖拽效果: 当鼠标选中目标元素之后可以将其拖放至指定区域的任意位置,实现的思路主要是通过鼠标事件按下.移动.抬起,摁下鼠标时记录鼠标位置以及元素位置并算出鼠标相对元素的位置,在拖拽时记下当前 ...

  4. svg实现多个元素拖拽

    下面使用到的index.css path{stroke:black;stroke-width:3;fill:none;stroke-linecap: round; } svg {} p{text-al ...

  5. 原生js实现元素拖拽onmousedown/onmousemove/onmouseup

    文章目录 前言 一.实现思路 二.具体步骤 1.鼠标在元素上按下时 2.鼠标拖拽元素时 3.鼠标抬起事件 4.完整代码 总结 前言 我们在网页操作的时候,经常用到鼠标拖拽元素的行为.本篇文章就来讨论一 ...

  6. 图片img或者含有img元素拖拽时,或者scale缩放时产品的阴影效应问题

    图片img或者含有img元素拖拽时,或者用scale缩放时产品的阴影效应问题 html中有图片img或者含有img元素拖拽时,或者scale缩放时产品的阴影效应问题,也就是图片重影, 另外使用scal ...

  7. 前端基础进阶(十):面向对象实战之封装拖拽对象

    https://segmentfault.com/a/1190000012646488  https://yangbo5207.github.io/wutongluo/ 说明:此处只是记录阅读前端基础 ...

  8. 移动端实现元素拖拽效果插件_基于自然流布局的可视化拖拽搭建平台设计方案...

    LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...

  9. 前端项目中常用的工具包(拖拽排序表格、打印导出表格、文本复制等)【持续更新~~~】

    表格类: cdn库 cdn vxe-table[开源的多功能表格] 简介 一个基于 vue 的 PC 端表格组件,支持增删改查.虚拟滚动.懒加载.快捷菜单.数据校验.树形结构.打印导出.表单渲染.数据 ...

最新文章

  1. 如何给“物联网小白”讲清楚什么是无线通信模块?很简单,会打电话就行~
  2. 一个通用的任务管理模型-golang
  3. 11.python并发入门(part4 死锁与递归锁)
  4. PaddlePaddle——手写数字识别DEMO
  5. android 修改菜单大小,如何在NavigationView中更改菜单项图标的大小?
  6. API---有意思的API
  7. Docker Hello World容器运行报错的解决办法
  8. “玩转课堂”基本构想
  9. Linux下执行程序出现 Text file busy 时的解决办法。
  10. linux-关机与重启命令
  11. 幼儿园计算机课程心得,幼儿主题式课程教学心得体会
  12. 行业发展 | 雷达信号处理领域面临的重大问题
  13. 车用总线技术 | 从另一种视角了解CAN FD
  14. 【游戏开发创新】自学Blender建模,自制孔明灯,在Unity中点亮整个星空,愿新年,胜旧年(Unity | 建模 | 粒子系统 | 预设)
  15. 薅羊毛 | 揭秘闲鱼方案,一部手机,实现随时随地薅羊毛
  16. 本悟法师:信仰,让孤独走开
  17. OpenCV函数remap详解
  18. 计量模型 | 时间固定效应与时间趋势项
  19. 基于eNSP的企业PON入云网络模拟
  20. 快过年了,用五种不同的JS特效带你看烟花

热门文章

  1. cordova ios的问题
  2. c++设计一个不能被继承的类
  3. JS中的prototype
  4. ArcGIS JS 学习笔记4 实现地图联动
  5. Mysql性能优化二
  6. android RadioGroup设置某一个被选中
  7. nginx 403 forbidden 二种原因
  8. Oracle\MS SQL Server的数据库多表关联更新UPDATE与多表更新
  9. h5网页水印SDK的实现代码示例
  10. MicroPython技术及应用定义