昨天写了一个元素拖拽事件的代码。但是y所有的元素的拖拽效果都是一样的,这就尴尬了。那么,有没有这没有这么一段代码,可以让每个元素都有自己的个性呢?
一段代码我倒是没有,我有两个代码块
引入的
JS
部分(文件名为DragEvent.js
)
function DragEvent(boxId){
if (boxId==undefined) {
return;
}
this.ele=document.getElementById(boxId);
var self=this;
this.ele.onmousedown=function(e) {
e.preventDefault();
self.dX=e.clientX-self.ele.offsetLeft;
self.dY=e.clientY-self.ele.offsetTop;
self.start();
document.onmouseup=function() {
document.onmousemove=null;
}
}
}
DragEvent.prototype.start=function() {
var self=this;
document.onmousemove=function(e) {
var x=e.clientX-self.dX;
var y=e.clientY-self.dY;
self.move(x,y);
}
}
DragEvent.prototype.move=function(x,y){
var self=this;
self.ele.style.left=x+"px";
self.ele.style.top=y+"px";
}
css代码和继承部分
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>拖拽加强版</title>
</head>
<body>
<style>
div {
width: 100px;
height: 100px;
background: red;
position: absolute;
}
#box2 {
background: green;
}
#box3 {
background: blue;
}
</style>
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<script src="DragEvent.js"></script>
<script>
function DragEventText(boxId){
DragEvent.call(this,boxId);
}
DragEventText.prototype=new DragEvent();
DragEventText.prototype.move=function(x,y){
DragEvent.prototype.move.call(this,x,y);
this.ele.innerHTML=x+","+y;
}
function DragEventN(boxId){
DragEvent.call(this,boxId);
}
DragEventN.prototype=new DragEvent();
DragEventN.prototype.move=function(x,y){
if(x>=0&&x<=window.innerWidth-100){
this.ele.style.left = x + "px";
}else if(x<0){
this.ele.style.left =0+"px";
}else if(x>window.innerWidth-100){
this.ele.style.left=(window.innerWidth-100+"px");
}
if(y>=0&&y<=window.innerHeight-100){
this.ele.style.top = y + "px";
}else if(y<0){
this.ele.style.top =0+"px";
}else if(y>window.innerHeight-100){
this.ele.style.top =window.innerHeight-100+"px";
}
}
new DragEvent("box3");
new DragEventText("box2");
new DragEventN("box1");
</script>
</body>
</html>
慢慢来吧,先看引入的JS
部分:
和上一篇的结果十分眼熟,能直接抄,再稍加变形。
这里需要注意的是
1.var self=this
,由于上一篇文章中的代码都包裹在一个对象函数中(不知道官方名称,姑且这么叫了),所以只需要写一次就可以了,但这里被分开了,所以须要在每一个函数中都加这么一句话,保证this
(也就是我们要处理的元素)能够正确传入;
2.if (boxId==undefined) {return;}
,这条判断姑且先放着,我在下面会解释。
为什么我觉得引入JS
部分被略过了,好吧,也没差。
第二个代码块我叫它继承部分,为啥要这么叫呢?因为它主要是负责继承对象函数DragEvent(boxId)
的内容的(关于继承的学习别找我,我真不懂)。
还是一步一步的写吧:
先创建三个对象
new DragEvent("box3");//负责最原始的移动(也就是爹)
new DragEventText("box2");//可以在元素中显示移动过程中的left和top值(大儿子)
new DragEventN("box1");//不让它移动到我们页面外边(小儿子)
实际上,到了这一步,id
名为box3
的元素就可以被拖拽了(还是爹厉害),而我们要做的就是让剩下的两个元素也能动。
但咋样能让大儿子动呢——多向它爹学学。
还是先建立一个对象函数:
function DragEventText(boxId){
DragEvent.call(this,boxId);
}
这里有一个call
,它属于对象冒充方法的一种,基本语法和参数含义如下:
语法:父辈.call(参数1,参数2,参数3,...,参数X)
参数1 | 参数2~参数X |
---|---|
函数内的this | 函数中的第一个参数到最后一个参数 |
接下来就可以继承父辈的拖拽方式了
function DragEventText(boxId){
DragEvent.call(this,boxId);
}
DragEventText.prototype=new DragEvent();
此时,我们发现,大儿子的拖拽效果和它爹一样,这就需要我们对它的拖拽效果进行更改
function DragEventText(boxId){
DragEvent.call(this,boxId);
}
DragEventText.prototype=new DragEvent();
DragEventText.prototype.move=function(x,y){
DragEvent.prototype.move.call(this,x,y);
this.ele.innerHTML=x+","+y;
}
这里直接对父辈对象中的函数进行了更改,但并不会影响父辈元素的拖拽效果(毕竟它爹和它,不是同一个人)。
是时候回答if (boxId==undefined) {return;}
的作用了,我们可以实验一下,如果对DragEventText.prototype=new DragEvent();
传入参数,则会很尴尬的发现是在接下来处理小儿子时会收到影响,但如果不传入参数,则会发生undefined
的报错(不加if (boxId==undefined) {return;}
的情况下)。但是在不传入参数的情况下,从理论上来讲并不影响我们的运行。于是,是吧。
对小儿子的处理,有了对爹和大儿子的研究,处理起小儿子还不容易
function DragEventN(boxId){
DragEvent.call(this,boxId);
}
DragEventN.prototype=new DragEvent();
DragEventN.prototype.move=function(x,y){
if(x>=0&&x<=window.innerWidth-100){
this.ele.style.left = x + "px";
}else if(x<0){
this.ele.style.left =0+"px";
}else if(x>window.innerWidth-100){
this.ele.style.left=(window.innerWidth-100+"px");
}
if(y>=0&&y<=window.innerHeight-100){
this.ele.style.top = y + "px";
}else if(y<0){
this.ele.style.top =0+"px";
}else if(y>window.innerHeight-100){
this.ele.style.top =window.innerHeight-100+"px";
}
}
这里需要注意的是window.innerWidth
和window.innerHeight
是系统函数,目的是获取我们页面的大小。而由于系统计算元素的left
和top
值时是以左上角的那个像素点作为依据,因此我们需要减去它的left
和top
。
最后,对代码进行整理,顺便把创建的三个对象放到最后(防止出现一些奇怪的bug)。
最后,我还想顺便问一句,既然都return
了,为啥代码还会执行?