本篇的存在,是一个美丽误会。。。
一、面向过程 图片拖拽
思路: 给物体添加 onmousedown (鼠标按下事件)、在事件处理函数中,让物体跟随鼠标移动、鼠标抬起时,停止鼠标跟随
1. 给body里添加一个拖拽图片
< img src="img/timg.jpg" id="bird" style="width: 100px;position: absolute;" >
2. 获取元素到 Javascript 中
var oImg = document.getElementById("bird");
3. 给物体添加 onmousedown (鼠标按下事件)、onmousemove(鼠标移动事件)、onmouseup(鼠标抬起事件)
// 鼠标点击的时候,图片开始移动
oImg.onmousedown = function(e1){
// 阻止浏览器默认行为
e1.preventDefault();
// 计算点击位置 到 图片边缘距离
var detaX = e1.clientX - oImg.offsetLeft;
var detaY = e1.clientY - oImg.offsetTop;
// 让物体跟随鼠标移动
window.onmousemove = function(e2){
// 计算图片停止的位置
var x = e2.clientX - detaX;
var y = e2.clientY - detaY;
// 判断 x,y 值是否小于0,如果小于0,让 x,y 等于0,图片就不会拖出边界
var x = (x < 0) ? 0 : x;
var y = (y < 0) ? 0 : y;
oImg.style.left = x + "px";
oImg.style.top = y + "px";
}
// 鼠标抬起的时候,图片停止移动
window.onmouseup = function(){
// 清空onmousemove 相当于 鼠标移动事件处理函数为空,图片停止
window.onmousemove = null;
}
}
二、面向对象 图片拖拽
面向对象的特点:
1. 封装:把相关的信息(无论数据或方法)存储在对象中的能力;
2.继承:从父类继承到的属性和方法的能力;
3.多态:能以多种方法运行的函数或方法;
思路:找对象(对象:拖拽物体;属性:元素;方法:开始拖拽、移动、停止)、实现对象
// 构造函数
function Img(imgId){
// 属性
this.ele = document.getElementById(imgId);
// 存储 this 对象
var self = this;
// 元素按下的时候
this.ele.onmousedown = function(e){
// 清除浏览器默认行为
e.preventDefault();
// 计算点击位置到图片边缘距离 保存到拖拽物体中
self.detaX = e.clientX - self.ele.offsetLeft;
self.detaY = e.clientY - self.ele.offsetTop;
self.start();
document.onmouseup = function(){
self.stop();
}
}
// 行为1:开始
this.start = function(e){
var x = e.clientX - self.detaX;
var y = e.clientY - self.detaY;
// 将 x,y传递到move函数中
self.move(x,y);
}
// 行为2:移动
this.move = function(x,y){
self.ele.style.left = x + "px";
self.ele.style.top = y + "px";
}
// 行为2:停止
this.stop = function(){
document.onmouseover = null;
}
}
new Img("bird");
三、面向对象继承 图片拖拽
思路:继承属性、继承方法、修改move 方法
原型对象:每一个构造函数中都存在一个隐藏的对象 原型对象(prototype)
找原型对象有两种方法:
1.构造函数名. prototype
2. 对象名. __proto__
// 构造函数
function DragBox(imgId){
// 当imgId 没有传递时,直接退出函数
if(imgId == undefined){
return ;
}
this.ele = document.getElementById(imgId);
var self = this;
// 因为物体一开始创建就具有拖拽能力,所以在一开始就进行按下的设置
this.ele.onmousedown = function(e){
e.preventDefault(); // 阻止浏览器默认行为
self.detaX = e.clientX - self.ele.offsetLeft;
self.detaY = e.clientY - self.ele.offsetTop;
// 开始
self.start();
// 停止
document.onmouseup = function(){
self.stop();
}
}
}
// 在 DragBox 的原型对象中添加一个 start(开始)行为
DragBox.prototype.start = function(){
var self = this;
document.onousemove = function(e){
var x = e.clientX - self.detaX;
var y = e.clientY - self.detaY;
self.move(x,y);
}
}
// 在 DragBox 的原型对象中添加一个 move(移动)行为
DragBox.prototype.move(){
this.ele.style.left = x + "px";
this.ele.style.top = y + "px";
}
// 在 DragBox 的原型对象中添加一个 stop(停止)行为
DragBox.prototype.stop = function(){
document.onmousemove = null;
}
// 第一个子对象继承父对象的属性
function DragBoxText(imgId){
DragBox.call(this,imgId);
}
// 第一个子对象继承父对象的行为
DragBoxText.prototype = new DragBox();
// 修改 move 行为
DragBoxText.prototype.move = function(x,y){
// this.ele.style.left = x + "px";
// this.ele.style.top = y + "px";
// 上面的方式和下面这一行代码效果相同
DragBox.prototype.move.call(this,x,y);
// 子对象继承父对象 行为时,添加了物体移动时,同时里面显示物体坐标的效果
this.ele.innerHTML = "left: " + x + "px ; top: " + y + "px";
}
// 第二个子对象继承对象的属性
function DragBoxNext(imgId){
DragBox.call(this,imgId);
}
// 第二个子对象继承父对象的行为
DragBoxNext.prototype = new DragBox();
// 添加 行为
DragBoxNext.prototype.move = function(x,y){
// 添加 行为 使元素不能退出浏览器界面
/*if( x < 0){
x = 0;
}
if( y < 0){
y = 0;
}*/
// 三目运算书写方式
x = ( x < 0 ) ? 0 : x ;
y = ( y < 0 ) ? 0 : y ;
// 得到原有的行为
DragBox.prototype.move.call(this,x,y);
}
new DragBox("bird")
new DragBoxText("bird1");
new DragBoxNext("bird2");
【注】1. DragBox.call(this,x,y);相当于调用了DragBox 函数,并且里面的第一个参数 等于 DragBox 函数的this值;第二个参数,其实就是函数的第二个形参 . . .
- DragBox.apply(this,[x,y]);apply 的 第一个参数,其实就是函数内部的this;第二个参数,必须是数组:数组的第一个元素,其实就是函数的第一个形参;数组的第二个元素,其实就是函数的第二个形参 . . .
总结: 对于这一块听可以听懂,就是不会用!!!文字性的总结不知道怎么写了,就先写这么多吧!多总结、多看、多敲代码!!!
网友评论