前端小白用面向对象思想实现元素拖拽
上篇文章分享了如何用面向对象思想编写选项卡,在文章最后留了一个拖拽的例子,希望大家可以试着写一下,现在我就谈谈我在这过程中遇到的一些问题和解决方法。(本文主要是想和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上就没有类似的情况,这是为什么?
前端小白用面向对象思想实现元素拖拽相关推荐
- dom 元素拖拽实现
文章目录 原生 JS 实现 div 拖拽 HTML 拖拽 API REF 之前找实习的时候,面试官出了道 "原生 JS 实现 div 元素拖拽",当时实现了个大概,不过很多细节 ...
- jquery回弹_创意网页DOM元素拖拽弹性反弹和变形动画特效
这是一款非常有创意的HTML网页DOM元素拖拽弹性反弹和变形动画特效.这个特效中有两种效果:第一种是弹性模态窗口效果,第二种是弹性幻灯片效果.这两种效果均可以拖拽DOM元素,然后释放它们时生成非常震撼 ...
- 实现元素拖拽放大缩小_Vue实战067:DOM元素拖拽效果的实现
DOM元素拖拽效果: 当鼠标选中目标元素之后可以将其拖放至指定区域的任意位置,实现的思路主要是通过鼠标事件按下.移动.抬起,摁下鼠标时记录鼠标位置以及元素位置并算出鼠标相对元素的位置,在拖拽时记下当前 ...
- svg实现多个元素拖拽
下面使用到的index.css path{stroke:black;stroke-width:3;fill:none;stroke-linecap: round; } svg {} p{text-al ...
- 原生js实现元素拖拽onmousedown/onmousemove/onmouseup
文章目录 前言 一.实现思路 二.具体步骤 1.鼠标在元素上按下时 2.鼠标拖拽元素时 3.鼠标抬起事件 4.完整代码 总结 前言 我们在网页操作的时候,经常用到鼠标拖拽元素的行为.本篇文章就来讨论一 ...
- 图片img或者含有img元素拖拽时,或者scale缩放时产品的阴影效应问题
图片img或者含有img元素拖拽时,或者用scale缩放时产品的阴影效应问题 html中有图片img或者含有img元素拖拽时,或者scale缩放时产品的阴影效应问题,也就是图片重影, 另外使用scal ...
- 前端基础进阶(十):面向对象实战之封装拖拽对象
https://segmentfault.com/a/1190000012646488 https://yangbo5207.github.io/wutongluo/ 说明:此处只是记录阅读前端基础 ...
- 移动端实现元素拖拽效果插件_基于自然流布局的可视化拖拽搭建平台设计方案...
LowCode 是高效.高性能的拖拽式低代码开发平台. 也是笔者最近一直在研究的方向, 对于可视化搭建平台的实现方案笔者之前写过很多文章, 这里带大家探索一个新方向--基于自然流布局的可视化搭建平台. ...
- 前端项目中常用的工具包(拖拽排序表格、打印导出表格、文本复制等)【持续更新~~~】
表格类: cdn库 cdn vxe-table[开源的多功能表格] 简介 一个基于 vue 的 PC 端表格组件,支持增删改查.虚拟滚动.懒加载.快捷菜单.数据校验.树形结构.打印导出.表单渲染.数据 ...
最新文章
- 如何给“物联网小白”讲清楚什么是无线通信模块?很简单,会打电话就行~
- 一个通用的任务管理模型-golang
- 11.python并发入门(part4 死锁与递归锁)
- PaddlePaddle——手写数字识别DEMO
- android 修改菜单大小,如何在NavigationView中更改菜单项图标的大小?
- API---有意思的API
- Docker Hello World容器运行报错的解决办法
- “玩转课堂”基本构想
- Linux下执行程序出现 Text file busy 时的解决办法。
- linux-关机与重启命令
- 幼儿园计算机课程心得,幼儿主题式课程教学心得体会
- 行业发展 | 雷达信号处理领域面临的重大问题
- 车用总线技术 | 从另一种视角了解CAN FD
- 【游戏开发创新】自学Blender建模,自制孔明灯,在Unity中点亮整个星空,愿新年,胜旧年(Unity | 建模 | 粒子系统 | 预设)
- 薅羊毛 | 揭秘闲鱼方案,一部手机,实现随时随地薅羊毛
- 本悟法师:信仰,让孤独走开
- OpenCV函数remap详解
- 计量模型 | 时间固定效应与时间趋势项
- 基于eNSP的企业PON入云网络模拟
- 快过年了,用五种不同的JS特效带你看烟花