云顶娱乐手机官网-云顶娱乐网址

热门关键词: 云顶娱乐手机官网,云顶娱乐网址

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

2019-12-04 作者:前端开发   |   浏览(155)

前端底工进级(10):面向对象实战之封装拖拽对象

2017/04/02 · JavaScript · 面向对象

原作出处: 波同学   

图片 1

终于

前边几篇作品,笔者跟大家三进三出了JavaScript的部分根底知识,那篇小说,将会进来第多少个实战环节:利用前边几章的所涉及到的学识,封装三个拖拽对象。为了能够扶植大家掌握越多的办法与实行相比,笔者会使用二种分裂的点子来落到实处拖拽。

  • 不封装对象直接促成;
  • 接受原生JavaScript封装拖拽对象;
  • 透过扩充jQuery来贯彻拖拽对象。

本文的事例会停放于codepen.io中,供我们在读书时间接查看。倘使对于codepen不打听的校友,能够花点时间有个别掌握一下。

拖拽的落到实处进程会提到到非常多的实用小知识,由此为了巩固本人本人的学问积存,也为了大家能够学到越多的学识,笔者会尽量详细的将一些细节分享出去,相信大家认真阅读之后,一定能学到一些东西。

复制代码 代码如下://获取成分的样式值。 function getStyle{ if{ return elem.style[name]; }else if{ return elem.currentStyle[name]; }else if(document.defaultView&&document.defaultView.getComputedStyle卡塔尔{ name=name.replace; name=name.toLowerCase(卡塔尔国; var s=document.defaultView.getComputedStyle; return s&&s.getPropertyValue; }else{ return null } } //获取成分相对于这么些页面包车型大巴x和y坐标。 function pageX{ return elem.offsetParent?(elem.offsetLeft+pageX:elem.offsetLeft; } function pageY{ return elem.offsetParent?(elem.offsetTop+pageY:elem.offsetTop; } //获取成分相对于父成分的x和y坐标。 function parentX{ return elem.parentNode==elem.offsetParent?elem.offsetLeft:pageX-pageX; } function parentY{ return elem.parentNode==elem.offsetParent?elem.offsetTop:pageY-pageY; } //获取使用css定位的因素的x和y坐标。 function posX{ return parseInt卡塔尔国; } function posY{ return parseInt; } //设置成分地点。 function setX{ elem.style.left=pos+”px”; } function setY{ elem.style.top=pos+”px”; } //增先令素X和y坐标。 function addX{ set卡塔尔(قطر‎; } function addY{ set卡塔尔(قطر‎; } //获取成分使用css调控大小的惊人和宽窄 function getHeight{ return parseInt(getStyle; } function getWidth{ return parseInt(getStyle; } //获取成分也许,完整的万丈和增长幅度 function getFullHeight{ if(getStyle!=”none”){ return getHeight||elem.offsetHeight; }else{ var old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”}); var h=elem.clientHeight||getHeight; restoreCss; return h; } } function getFullWidth{ if(getStyle!=”none”卡塔尔{ return getWidth||elem.offsetWidth; }else{ var old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”}卡塔尔国; var w=elem.clientWidth||getWidth; restoreCss; return w; } } //设置css,并保留旧的css function resetCss{ var old={}; for{ old[i]=elem.style[i]; elem.style[i]=prop[i]; } return old; } function restoreCss{ for{ elem.style[i]=prop[i]; } } //突显和隐蔽function show{ elem.style.display=elem.$oldDisplay||” “; } function hide{ var curDisplay=getStyle; if{ elem.$oldDisplay=curDisplay; elem.style.display=”none”; } } //设置折射率 function setOpacity{ if{ elem.style.filter=”阿尔法”; }else{ elem.style.opacity=num/100; } } //滑动 function slideDown{ var h=getFullHeight; elem.style.height=”0px”; show; for{ new function(卡塔尔{ var pos=i; setTimeout{elem.style.height=+”px”;},; } } } //渐变 function fadeIn; setOpacity; for{ new function(卡塔尔(英语:State of Qatar){ var pos=i; setTimeout{setOpacity*10卡塔尔(英语:State of Qatar); } } } //获取鼠标光标相对于任何页面包车型客车职位。 function getX{ e=e||window.event; return e.pageX||e.clientX+document.body.scrollLeft; } function getY{ e=e||window.event; return e.pageY||e.clientY+document.body.scrollTop; } //获取鼠标光标相对于这几天因素的岗位。 function getElementX{ return ||window.event.offsetX; } function getElementY{ return ||window.event.offsetY; } //获取页面包车型大巴冲天和宽度 function getPageHeight(卡塔尔国{ var de=document.documentElement; return document.body.scrollHeight||; } function getPageWidth(卡塔尔(قطر‎{ var de=document.documentElement; return document.body.scrollWidth||; } //获取滚动条的岗位。 function scrollX(卡塔尔(قطر‎{ var de=document.documentElement; return self.pageXOffset||||document.body.scrollLeft; } function scrollY(卡塔尔国{ var de=document.documentElement; return self.pageYOffset||||document.body.scrollTop; } //获取视口的惊人和宽窄。 function windowHeight(卡塔尔国 { var de = document.documentElement; return self.innerHeight||(de && de.offsetHeight卡塔尔||document.body.offsetHeight; } function windowWidth(卡塔尔 { var de = document.documentElement; return self.innerWidth||( de && de.offsetWidth 卡塔尔国||document.body.offsetWidth; }

1、如何让三个DOM元素动起来

大家常常会通过改产生分的top,left,translate来其的职位发生改过。在底下的例子中,每点击一回按键,对应的成分就能移动5px。大家可点击查看。

点击查阅三个让成分动起来的小例子

鉴于更改三个因素top/left值会挑起页面重绘,而translate不会,因此从品质优化上来剖断,我们会预先使用translate属性。

2、怎么着赢妥当前浏览器扶助的transform包容写法

transform是css3的习性,当我们应用它时就不能不直面宽容性的难题。差别版本浏览器的相配写法差不离犹如下两种:

['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform']

故而我们须求看清当前浏览器情形扶助的transform属性是哪生龙活虎种,方法如下:

JavaScript

// 获取当前浏览器协理的transform包容写法 function getTransform(卡塔尔国 { var transform = '', divStyle = document.createElement('div'卡塔尔.style, // 恐怕涉及到的两种包容性写法,通过轮回搜索浏览器度和胆识其他那多少个 transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i++) { if(transformArr[i] in divStyle卡塔尔(قطر‎ { // 找到之后马上赶回,截至函数 return transform = transformArr[i]; } } // 如果未有找到,就直接回到空字符串 return transform; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 获取当前浏览器支持的transform兼容写法
function getTransform() {
    var transform = '',
        divStyle = document.createElement('div').style,
        // 可能涉及到的几种兼容性写法,通过循环找出浏览器识别的那一个
        transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],
 
        i = 0,
        len = transformArr.length;
 
    for(; i < len; i++)  {
        if(transformArr[i] in divStyle) {
            // 找到之后立即返回,结束函数
            return transform = transformArr[i];
        }
    }
 
    // 如果没有找到,就直接返回空字符串
    return transform;
}

该情势用于获取浏览器扶助的transform属性。假设回去的为空字符串,则意味近些日子浏览器并不扶植transform,当时我们就供给选择left,top值来改造成分的任务。假如支持,就改造transform的值。

3、 如何获得成分的启幕地点

笔者们第后生可畏须求拿到到指标成分的在此之前地点,因而这里大家须要贰个极其用来博取成分样式的效果函数。

但是获取成分样式在IE浏览器与别的浏览器有风华正茂部分不如,由此大家供给叁个宽容性的写法。

JavaScript

function getStyle(elem, property卡塔尔(英语:State of Qatar) { // ie通过currentStyle来得到成分的体制,别的浏览器通过getComputedStyle来赢得 return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false卡塔尔(英语:State of Qatar)[property] : elem.currentStyle[property]; }

1
2
3
4
function getStyle(elem, property) {
    // ie通过currentStyle来获取元素的样式,其他浏览器通过getComputedStyle来获取
    return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property];
}

有了那几个方法之后,就足以开端动手写获取指标成分开端地方的办法了。

JavaScript

function getTargetPos(elem) { var pos = {x: 0, y: 0}; var transform = getTransform(); if(transform) { var transformValue = getStyle(elem, transform); if(transformValue == 'none') { elem.style[transform] = 'translate(0, 0)'; return pos; } else { var temp = transformValue.match(/-?d+/g); return pos = { x: parseInt(temp[4].trim()), y: parseInt(temp[5].trim()) } } } else { if(getStyle(elem, 'position') == 'static') { elem.style.position = 'relative'; return pos; } else { var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0); var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0); return pos = { x: x, y: y } } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function getTargetPos(elem) {
    var pos = {x: 0, y: 0};
    var transform = getTransform();
    if(transform) {
        var transformValue = getStyle(elem, transform);
        if(transformValue == 'none') {
            elem.style[transform] = 'translate(0, 0)';
            return pos;
        } else {
            var temp = transformValue.match(/-?d+/g);
            return pos = {
                x: parseInt(temp[4].trim()),
                y: parseInt(temp[5].trim())
            }
        }
    } else {
        if(getStyle(elem, 'position') == 'static') {
            elem.style.position = 'relative';
            return pos;
        } else {
            var x = parseInt(getStyle(elem, 'left') ? getStyle(elem, 'left') : 0);
            var y = parseInt(getStyle(elem, 'top') ? getStyle(elem, 'top') : 0);
            return pos = {
                x: x,
                y: y
            }
        }
    }
}

在拖拽进程中,大家须要不停的装置指标成分的新义务,这样它才会活动起来,由此大家需求二个安装目的成分地方的不二等秘书技。

JavaScript

// pos = { x: 200, y: 100 } function setTargetPos(elem, pos) { var transform = getTransform(); if(transform) { elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px)'; } else { elem.style.left = pos.x + 'px'; elem.style.top = pos.y + 'px'; } return elem; }

1
2
3
4
5
6
7
8
9
10
11
// pos = { x: 200, y: 100 }
function setTargetPos(elem, pos) {
    var transform = getTransform();
    if(transform) {
        elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px)';
    } else {
        elem.style.left = pos.x + 'px';
        elem.style.top = pos.y + 'px';
    }
    return elem;
}
5、大家供给用到怎么事件?

在pc上的浏览器中,结合mousedown、mousemove、mouseup这八个事件能够扶助我们贯彻拖拽。

  • mousedown 鼠标按下时接触
  • mousemove 鼠标按下后拖动时接触
  • mouseup 鼠标放手时触发

而在移动端,分别与之对应的则是touchstart、touchmove、touchend

当大家将成分绑定这个事件时,有三个平地风波指标将会作为参数字传送递给回调函数,通过事件目的,我们得以获得到近来鼠标的纯正地点,鼠标地点消息是落到实处拖拽的第大器晚成。

事件指标非常至关心器重要,在那之中满含了不少的可行的音讯,这里自个儿就不扩大了,我们能够在函数司令员事件目的打印出来查看里面包车型地铁现实性性质,这些主意对于记不清事件目的首要性质的童鞋非常实用。

6、拖拽的原理

当事件触发时,大家能够透过事件目标获得到鼠标的精切地方。那是贯彻拖拽的重大。当鼠标按下(mousedown触发卡塔尔(قطر‎时,大家必要记住鼠标的早先位置与指标成分的早先位置,我们的靶子正是达成当鼠标移动时,目的成分也跟着移动,根据原理大家能够得出如下事关:

活动后的鼠标地方 - 鼠标初始地点 = 移动后的对象成分地点 - 指标成分的起来地点

1
移动后的鼠标位置 - 鼠标初始位置 = 移动后的目标元素位置 - 目标元素的初始位置

倘诺鼠标地点的差值大家用dis来代表,那么指标成分的岗位就约等于:

一抬手一动脚后目的成分的地点 = dis + 目的成分的伊始地点

1
移动后目标元素的位置 = dis + 目标元素的初始位置

经过事件指标,大家能够确切的明白鼠标的脚失业位,因而当鼠标拖动(mousemove卡塔尔国时,大家得以不停的计量出鼠标移动的差值,以此来求出指标成分的眼失去工作位。那么些进度,就兑现了拖拽。

而在鼠标松开(mouseup卡塔尔(قطر‎甘休拖拽时,大家须要处理部分得了专业。实际情况见代码。

7、 小编又来推荐思维导图扶植写代码了

常有新妇朋友跑来问作者,假诺逻辑思维工夫不强,能或不能够写代码做前端。作者的答案是:能。因为依据思维导图,能够很自在的弥补逻辑的短板。并且比在本身头脑中脑补逻辑更是清晰明了,不易出错。

上边第六点小编介绍了规律,因而如何做就展现不是那么难了,而实际的手续,则在底下的思维导图中显明给出,我们只需求根据这么些手续来写代码就可以,试试看,一定非常轻巧。

图片 2

应用思维导图清晰的抒发出全数拖拽进度大家须要干的业务

8、代码完毕

part1、准备干活

JavaScript

// 获取目的成分对象 var oElem = document.getElementById('target'卡塔尔(قطر‎; // 评释2个变量用来保存鼠标开首地方的x,y坐标 var startX = 0; var startY = 0; // 表明2个变量用来保存目的成分开头地点的x,y坐标 var sourceX = 0; var sourceY = 0;

1
2
3
4
5
6
7
8
9
10
// 获取目标元素对象
var oElem = document.getElementById('target');
 
// 声明2个变量用来保存鼠标初始位置的x,y坐标
var startX = 0;
var startY = 0;
 
// 声明2个变量用来保存目标元素初始位置的x,y坐标
var sourceX = 0;
var sourceY = 0;

part2、功效函数

因为前边曾经贴过代码,就不再重复

JavaScript

// 获取当前浏览器扶助的transform宽容写法 function getTransform(卡塔尔国 {} // 获取成分属性 function getStyle(elem, property卡塔尔国 {} // 获取成分的启幕位置function getTargetPos(elem卡塔尔(قطر‎ {} // 设置成分的牵头地方 function setTargetPos(elem, potions卡塔尔(英语:State of Qatar) {}

1
2
3
4
5
6
7
8
9
10
11
// 获取当前浏览器支持的transform兼容写法
function getTransform() {}
 
// 获取元素属性
function getStyle(elem, property) {}
 
// 获取元素的初始位置
function getTargetPos(elem) {}
 
// 设置元素的初始位置
function setTargetPos(elem, potions) {}

part3、申明多个事件的回调函数

那多个法子正是达成拖拽的主干所在,作者将从严依照地点思维导图中的步骤来完结我们的代码。

JavaScript

// 绑定在mousedown上的回调,event为流传的事件目的 function start(event卡塔尔{ // 获取鼠标开首地点 startX = event.pageX; startY = event.pageY; // 获取成分初叶地点 var pos = getTargetPos(oElem卡塔尔(قطر‎; sourceX = pos.x; sourceY = pos.y; // 绑定 document.addEventListener('mousemove', move, false卡塔尔(قطر‎; document.add伊夫ntListener('mouseup', end, false卡塔尔国; } function move(event卡塔尔(英语:State of Qatar){ // 获取鼠标当前职分 var currentX = event.pageX; var currentY = event.pageY; // 总括差值 var distanceX = currentX - startX; var distanceY = currentY - startY; // 总结并安装元素当前岗位 setTargetPos(oElem, { x: (sourceX + distanceX卡塔尔(英语:State of Qatar).toFixed(卡塔尔, y: (sourceY + distanceY卡塔尔国.toFixed(卡塔尔国 }卡塔尔国 } function end(event卡塔尔(英语:State of Qatar) { document.removeEventListener('mousemove', move卡塔尔国; document.remove伊芙ntListener('mouseup', end卡塔尔(英语:State of Qatar); // do other things }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 绑定在mousedown上的回调,event为传入的事件对象
function start(event) {
    // 获取鼠标初始位置
    startX = event.pageX;
    startY = event.pageY;
 
    // 获取元素初始位置
    var pos = getTargetPos(oElem);
 
    sourceX = pos.x;
    sourceY = pos.y;
 
    // 绑定
    document.addEventListener('mousemove', move, false);
    document.addEventListener('mouseup', end, false);
}
 
function move(event) {
    // 获取鼠标当前位置
    var currentX = event.pageX;
    var currentY = event.pageY;
 
    // 计算差值
    var distanceX = currentX - startX;
    var distanceY = currentY - startY;
 
    // 计算并设置元素当前位置
    setTargetPos(oElem, {
        x: (sourceX + distanceX).toFixed(),
        y: (sourceY + distanceY).toFixed()
    })
}
 
function end(event) {
    document.removeEventListener('mousemove', move);
    document.removeEventListener('mouseup', end);
    // do other things
}

OK,一个简短的拖拽,就这么中意的落实了。点击上边包车型地铁链接,能够在线查看该例子的demo。

利用原生js实现拖拽

9、封装拖拽对象

在前头豆蔻年华章小编给大家扬汤止沸了面向对象如何促成,基于那么些功底知识,大家来将下面完结的拖拽封装为一个拖拽对象。我们的靶子是,只要我们声圣元个拖拽实例,那么传入的目的成分将机关具有能够被拖拽的功用。

在实际开辟中,一个对象大家平常会独自放在一个js文件中,这一个js文件将独自作为一个模块,利用各样模块的方法组织起来使用。当然这里未有复杂的模块交互作用,因为那几个事例,我们只须求三个模块就可以。

为了避免变量污染,大家需求将模块放置于一个函数自实行措施模拟的块级功用域中。

JavaScript

; (function() { ... })();

1
2
3
4
;
(function() {
    ...
})();

在普通的模块协会中,大家只是单纯的将广大js文件收缩成为多个js文件,因而这里的第三个子集团则是为了堤防上一个模块的末尾不用分号导致报错。不可贫乏。当然在经过require可能ES6模块等方法就不会现出那样的情景。

咱俩清楚,在包装二个对象的时候,大家得以将品质与艺术放置于构造函数或然原型中,而在大增了自实行函数之后,大家又可以将品质和措施幸免与模块的当中功用域。那是闭包的学问。

那么我们直面的挑衅就在于,怎么着客观的拍卖属性与措施的岗位。

自然,每二个对象的景况都不平等,一定要分畛域,大家须求显然的精晓那三种职位的性格技术做出最相符的操纵。

  • 结构函数中: 属性与艺术为日前实例单独具有,只可以被眼下实例访问,何况每声美素佳儿(Friso卡塔尔国个实例,个中的秘技都会被再度成立壹回。
  • 原型中: 属性与方法为富有实例协同全数,可以被抱有实例访谈,新申明实例不会再一次创立方法。
  • 模块功效域中:属性和艺术无法被此外实例访谈,可是能被内部方法采访,新注脚的实例,不会再次创制雷同的艺术。

对于措施的剖断比较轻易。

因为在布局函数中的方法总会在宣称八个新的实例时被再度创造,因而大家注解的秘技都尽量制止出现在布局函数中。

而意气风发旦您的不二等秘书技中须求用到布局函数中的变量,恐怕想要公开,那就须求放在原型中。

假若措施供给个人不被外边访问,那么就放置在模块效率域中。

对于属性放置于怎样地方有个别时候很难做出准确的论断,因而笔者很难交付叁个纯正的概念告诉您怎么样性质必须求放在什么地方,那亟需在事实上付出中不停的下结论经历。不过不问可以预知,仍旧要组成那多个任务的风味来做出最合适的剖断。

万豆蔻年华属性值只好被实例单独具有,举个例子person对象的name,只好归属某二个person实例,又举个例子此处拖拽对象中,某八个因素的初始地方,也仅仅只是这些因素的脚下任务,那些特性,则适合放在布局函数中。

而要是一个属性仅仅供内部方法访谈,那些性子就切合放在模块作用域中。

有关面向对象,下边的几点思虑本人认为是那篇文章最值得认真动脑筋的精粹。假诺在封装时没有思忖清楚,很恐怕会遇上不少您不意的bug,所以提议大家结合本人的开垦经历,多多思索,计算出团结的见识。

传闻那么些思忖,我们能够和谐尝试封装一下。然后与小编的做一些相对来讲,看看大家的主见有啥样分歧,在底下例子的笺注中,笔者将团结的主张表明出来。

点击查看已经封装好的demo

js 源码

JavaScript

; (function(卡塔尔(英语:State of Qatar) { // 那是四个个体属性,没有供给被实例访问 var transform = getTransform(卡塔尔(英语:State of Qatar); function Drag(selector卡塔尔(قطر‎ { // 放在布局函数中的属性,都是归属每二个实例单独具备 this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector卡塔尔国; this.startX = 0; this.startY = 0; this.sourceX = 0; this.sourceY = 0; this.init(卡塔尔(قطر‎; } // 原型 Drag.prototype = { constructor: Drag, init: function(卡塔尔国 { // 最初时索要做些什么事情 this.setDrag(卡塔尔(英语:State of Qatar); }, // 稍作退换,仅用于获取当前元素的性质,相近于getName getStyle: function(property卡塔尔(英语:State of Qatar) { return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(this.elem, false卡塔尔[property] : this.elem.currentStyle[property]; }, // 用来收获当前因素的职位新闻,注意与从前的区别之处 getPosition: function(){ var pos = {x: 0, y: 0}; if(transform卡塔尔(英语:State of Qatar) { var transformValue = this.getStyle(transform卡塔尔(英语:State of Qatar); if(transformValue == 'none'卡塔尔(قطر‎ { this.elem.style[transform] = 'translate(0, 0)'; } else { var temp = transformValue.match(/-?d+/g); pos = { x: parseInt(temp[4].trim()), y: parseInt(temp[5].trim(卡塔尔(قطر‎卡塔尔(英语:State of Qatar) } } } else { if(this.getStyle('position'卡塔尔国== 'static'卡塔尔(قطر‎ { this.elem.style.position = 'relative'; } else { pos = { x: parseInt(this.getStyle('left'卡塔尔(قطر‎ ? this.getStyle('left'卡塔尔(قطر‎ : 0卡塔尔国, y: parseInt(this.getStyle('top'卡塔尔 ? this.getStyle('top'卡塔尔国 : 0卡塔尔 } } } return pos; }, // 用来安装当前因素的职位 setPostion: function(pos卡塔尔 { if(transform卡塔尔 { this.elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px卡塔尔(英语:State of Qatar)'; } else { this.elem.style.left = pos.x + 'px'; this.elem.style.top = pos.y + 'px'; } }, // 该办法用来绑定事件 setDrag: function(卡塔尔(英语:State of Qatar) { var self = this; this.elem.addEventListener('mousedown', start, false卡塔尔(英语:State of Qatar); function start(event卡塔尔(قطر‎ { self.startX = event.pageX; self.startY = event.pageY; var pos = self.getPosition(卡塔尔(قطر‎; self.sourceX = pos.x; self.sourceY = pos.y; document.add伊夫ntListener('mousemove', move, false卡塔尔(英语:State of Qatar); document.add伊芙ntListener('mouseup', end, false卡塔尔(英语:State of Qatar); } function move(event卡塔尔(قطر‎ { var currentX = event.pageX; var currentY = event.pageY; var distanceX = currentX - self.startX; var distanceY = currentY - self.startY; self.setPostion({ x: (self.sourceX + distanceX卡塔尔国.toFixed(卡塔尔(英语:State of Qatar), y: (self.sourceY + distanceY卡塔尔(英语:State of Qatar).toFixed(卡塔尔 }卡塔尔国 } function end(event卡塔尔 { document.removeEventListener('mousemove', move卡塔尔(英语:State of Qatar); document.removeEventListener('mouseup', end卡塔尔; // do other things } } } // 私有方法,仅仅用来赢得transform的相配写法 function getTransform(卡塔尔(قطر‎ { var transform = '', divStyle = document.createElement('div'卡塔尔.style, transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], i = 0, len = transformArr.length; for(; i < len; i++) { if(transformArr[i] in divStyle) { return transform = transformArr[i]; } } return transform; } // 黄金年代种对外拆穿的艺术 window.Drag = Drag; }卡塔尔(قطر‎(卡塔尔; // 使用:证明2个拖拽实例 new Drag('target'卡塔尔(英语:State of Qatar); new Drag('target2'卡塔尔(قطر‎;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;
(function() {
    // 这是一个私有属性,不需要被实例访问
    var transform = getTransform();
 
    function Drag(selector) {
        // 放在构造函数中的属性,都是属于每一个实例单独拥有
        this.elem = typeof selector == 'Object' ? selector : document.getElementById(selector);
        this.startX = 0;
        this.startY = 0;
        this.sourceX = 0;
        this.sourceY = 0;
 
        this.init();
    }
 
 
    // 原型
    Drag.prototype = {
        constructor: Drag,
 
        init: function() {
            // 初始时需要做些什么事情
            this.setDrag();
        },
 
        // 稍作改造,仅用于获取当前元素的属性,类似于getName
        getStyle: function(property) {
            return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(this.elem, false)[property] : this.elem.currentStyle[property];
        },
 
        // 用来获取当前元素的位置信息,注意与之前的不同之处
        getPosition: function() {
            var pos = {x: 0, y: 0};
            if(transform) {
                var transformValue = this.getStyle(transform);
                if(transformValue == 'none') {
                    this.elem.style[transform] = 'translate(0, 0)';
                } else {
                    var temp = transformValue.match(/-?d+/g);
                    pos = {
                        x: parseInt(temp[4].trim()),
                        y: parseInt(temp[5].trim())
                    }
                }
            } else {
                if(this.getStyle('position') == 'static') {
                    this.elem.style.position = 'relative';
                } else {
                    pos = {
                        x: parseInt(this.getStyle('left') ? this.getStyle('left') : 0),
                        y: parseInt(this.getStyle('top') ? this.getStyle('top') : 0)
                    }
                }
            }
 
            return pos;
        },
 
        // 用来设置当前元素的位置
        setPostion: function(pos) {
            if(transform) {
                this.elem.style[transform] = 'translate('+ pos.x +'px, '+ pos.y +'px)';
            } else {
                this.elem.style.left = pos.x + 'px';
                this.elem.style.top = pos.y + 'px';
            }
        },
 
        // 该方法用来绑定事件
        setDrag: function() {
            var self = this;
            this.elem.addEventListener('mousedown', start, false);
            function start(event) {
                self.startX = event.pageX;
                self.startY = event.pageY;
 
                var pos = self.getPosition();
 
                self.sourceX = pos.x;
                self.sourceY = pos.y;
 
                document.addEventListener('mousemove', move, false);
                document.addEventListener('mouseup', end, false);
            }
 
            function move(event) {
                var currentX = event.pageX;
                var currentY = event.pageY;
 
                var distanceX = currentX - self.startX;
                var distanceY = currentY - self.startY;
 
                self.setPostion({
                    x: (self.sourceX + distanceX).toFixed(),
                    y: (self.sourceY + distanceY).toFixed()
                })
            }
 
            function end(event) {
                document.removeEventListener('mousemove', move);
                document.removeEventListener('mouseup', end);
                // do other things
            }
        }
    }
 
    // 私有方法,仅仅用来获取transform的兼容写法
    function getTransform() {
        var transform = '',
            divStyle = document.createElement('div').style,
            transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],
 
            i = 0,
            len = transformArr.length;
 
        for(; i < len; i++)  {
            if(transformArr[i] in divStyle) {
                return transform = transformArr[i];
            }
        }
 
        return transform;
    }
 
    // 一种对外暴露的方式
    window.Drag = Drag;
})();
 
// 使用:声明2个拖拽实例
new Drag('target');
new Drag('target2');

这般五个拖拽对象就封装达成了。

建议大家依据自己提供的思考方法,多多尝试封装一些零器件。举个例子封装四个弹窗,封装一个循环轮播等。练得多了,面向对象就不再是难题了。这种观念方法,在现在别的时候都是力所能致选用的。

下后生可畏章深入分析jQuery对象的落实,与哪些将大家这里封装的拖拽对象扩展为jQuery插件。

2 赞 1 收藏 评论

图片 3

本文由云顶娱乐手机官网发布于前端开发,转载请注明出处:前端基础进阶(10):面向对象实战之封装拖拽对

关键词:

  • 上一篇:没有了
  • 下一篇:没有了