www.bifa88.com 3

前端基础进阶,常用函数

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

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

原稿出处: 波同学   

www.bifa88.com 1

终于

前边几篇小说,笔者跟我们大饱眼福了JavaScript的一部分基础知识,那篇小说,将会进去第二个实战环节:利用前面几章的所提到到的文化,封装三个拖拽对象。为了能够支持我们探听更加多的格局与开始展览对照,小编会使用三种不一致的方法来贯彻拖拽。

  • 不封装对象间接完成;
  • 使用原生JavaScript封装拖拽对象;
  • 透过扩张jQuery来完成拖拽对象。

本文的例子会停放于codepen.io中,供大家在读书时直接查看。如若对于codepen不打听的同班,能够花点时间有个别精通一下。

拖拽的贯彻进程会提到到卓殊多的实用小知识,由此为了巩固自身要好的知识储存,也为了大家能够学到愈来愈多的学识,作者会尽量详细的将一部分细节分享出去,相信我们认真读书之后,一定能学到一些事物。

复制代码 代码如下:

JavaScript常用脚本集中(三)

 本文给大家大快朵颐的常用脚本有经过数组,拓展字符串拼接轻易导致质量的题目、页面
视口
滚动条的地点的救助函数、调整因素反射率的函数、获取鼠标地方的多少个通用的函数、使用cssdisplay属性来切换来分可知性的一组函数、样式相关的通用函数、获取成分当前的可观和宽窄。

 

 

经过数组,拓展字符串拼接轻易造成品质的难点

 

代码如下:

function StringBuffer() {
this.__strings__ = new Array();
}
StringBuffer.prototype.append = function (str) {
this.__strings__.push(str);
return this;
}
StringBuffer.prototype.toString = function () {
return this.__strings__.join(“”);
}
var buffer = new StringBuffer();
www.bifa88.com,buffer.append(“Hello “).append(“javascript”);
var result = buffer.toString();
alert(result); //Hello javascript

页面 视口 滚动条的岗位的鼎力相助函数

 

代码如下:

/*规定当前页面高度和幅度的三个函数*/
function pageHeight() {
return document.body.scrollHeight;
}
function pageWidth() {
return document.body.scrollWidth;
}
/*规定滚动条水平和垂直的地点*/
function scrollX() {
var de = document.documentElement;
return self.pageXOffset || (de && de.scrollLeft) ||
document.body.scrollLeft;
}
function scrollY() {
var de = document.documentElement;
return self.pageYOffset || (de && de.scrollTop) ||
document.body.scrollTop;
}
/*分明浏览器视口的可观和增长幅度的多少个函数*/
function windowHeight() {
var de = document.documentElement;
return self.innerHeight || (de && de.clientHeight) ||
document.body.clientHeight;
}
function windowWidth() {
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) ||
document.body.clientWidth;
}

调度因素折射率的函数

 

代码如下:

/*调解因素光滑度的函数*/
function setOpacity(elem, level) {
//IE管理光滑度
if (elem.filters) {
elem.style.filters = ‘alpha(opacity=’ + level + ‘)’;
} else {
elem.style.opacity = level / 100;
}
}

获得鼠标地方的多少个通用的函数

 

代码如下:

/*多少个通用函数,用于获取鼠标相对于全部页面包车型地铁近日地方*/
function getX(e) {
e = e || window.event;
return e.pageX || e.clientX + document.body.scrollLeft;
}
function getY(e) {
e = e || window.event;
return e.pageY || e.clientY + document.body.scrollTop;
}
/*七个得到鼠标相对于当下成分地点的函数*/
function getElementX(e) {
return (e && e.layerX) || window.event.offsetX;
}
function getElementY(e) {
return (e && e.layerY) || window.event.offsetY;
}

选择cssdisplay属性来切换到分可知性的一组函数

 

代码如下:

/**
* 使用display来隐藏成分的函数
* */
function hide(elem) {
var curDisplay = getStyle(elem, ‘display’);

 

if (curDisplay != ‘none’) {
elem.$oldDisplay = curDisplay;
}
elem.style.display = ‘none’;
}
/**
* 使用display来显示存分的函数
* */
function show(elem) {
elem.style.display = elem.$oldDisplay || ”;
}

体制相关的通用函数

 

代码如下:

/**
* 获取钦点元素(elem)的体制属性(name)
* */
function getStyle(elem, name) {
//假若存在于style[]中,那么它已棉被服装置了(并且是当前的)
if (elem.style[name]) {
return elem.style[name];
}
//否则,测试IE的方法
else if (elem.currentStyle) {
return elem.currentStyle[name];
}
//或者W3C的方法
else if(document.defaultView &&
document.defaultView.getComputedStyle){
name = name.replace(/(A-Z)/g, “-$1”);
name = name.toLowerCase();
var s = document.defaultView.getComputedStyle(elem, “”);
return s && s.getPropertyValue(name);
}
//不然,用户采纳的是其它浏览器
else {
return null;
}
}

赢得成分当前的可观和幅度

 

代码如下:

/**
* 获取成分的实在中度
* 依赖的getStyle见上面的函数。
* */
function getHeight(elem) {
return parseInt(getStyle(elem, ‘height’));
}
/**
* 获取成分的真实性宽度
* 正视的getStyle见上面的函数
* */
function getWidth(elem) {
return parseInt(getStyle(elem, ‘width’));
}

如上正是本文分享的javascript常用脚本了,希望大家能够欣赏。

本文给大家大饱眼福的常用脚本有经过数组,拓展字符串拼接轻易导致质量的标题、页面
视口 滚动条的职位的扶助…

1、怎么样让二个DOM成分动起来

我们常常会透过修改元素的top,left,translate来其的地点产生改换。在底下的例证中,每点击2回按键,对应的因素就能够活动5px。大家可点击查看。

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

鉴于修改3个因素top/left值会挑起页面重绘,而translate不会,因而从性质优化上来决断,大家会优先选择translate属性。

//获取成分的样式值。
function getStyle(elem,name){
if(elem.style[name]){
return elem.style[name];
}else if(elem.currentStyle){
return elem.currentStyle[name];
}else if(document.defaultView&&document.defaultView.getComputedStyle){
name=name.replace(/([A-Z])/g,”-$1″);
name=name.toLowerCase();
var s=document.defaultView.getComputedStyle(elem,””);
return s&&s.getPropertyValue(name);
}else{
return null
}
}
//获取元素相对于这几个页面包车型大巴x和y坐标。
function pageX(elem){
return
elem.offsetParent?(elem.offsetLeft+pageX(elem.offsetParent)):elem.offsetLeft;
}
function pageY(elem){
return
elem.offsetParent?(elem.offsetTop+pageY(elem.offsetParent)):elem.offsetTop;
}
//获取成分相对于父成分的x和y坐标。
function parentX(elem){
return
elem.parentNode==elem.offsetParent?elem.offsetLeft:pageX(elem)-pageX(elem.parentNode);
}
function parentY(elem){
return
elem.parentNode==elem.offsetParent?elem.offsetTop:pageY(elem)-pageY(elem.parentNode);
}
//获取使用css定位的要素的x和y坐标。
function posX(elem){
return parseInt(getStyle(elem,”left”));
}
function posY(elem){
return parseInt(getStyle(elem,”top”));
}
//设置成分地点。
function setX(elem,pos){
elem.style.left=pos+”px”;
}
function setY(elem,pos){
elem.style.top=pos+”px”;
}
//增比索素X和y坐标。
function addX(elem,pos){
set(elem,(posX(elem)+pos));
}
function addY(elem,pos){
set(elem,(posY(elem)+pos));
}
//获取成分选择css调整大小的万丈和宽窄
function getHeight(elem){
return parseInt(getStyle(elem,”height”));
}
function getWidth(elem){
return parseInt(getStyle(elem,”width”));
}
//获取成分也许,完整的惊人和宽度
function getFullHeight(elem){
if(getStyle(elem,”display”)!=”none”){
return getHeight(elem)||elem.offsetHeight;
}else{
var
old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”});
var h=elem.clientHeight||getHeight(elem);
restoreCss(elem,old);
return h;
}
}
function getFullWidth(elem){
if(getStyle(elem,”display”)!=”none”){
return getWidth(elem)||elem.offsetWidth;
}else{
var
old=resetCss(elem,{display:”block”,visibility:”hidden”,position:”absolute”});
var w=elem.clientWidth||getWidth(elem);
restoreCss(elem,old);
return w;
}
}
//设置css,并保存旧的css
function resetCss(elem,prop){
var old={};
for(var i in prop){
old[i]=elem.style[i];
elem.style[i]=prop[i];
}
return old;
}
function restoreCss(elem,prop){
for(var i in prop){
elem.style[i]=prop[i];
}
}
//显示和隐身
function show(elem){
elem.style.display=elem.$oldDisplay||” “;
}
function hide(elem){
var curDisplay=getStyle(elem,”display”);
if(curDisplay!=”none”){
elem.$oldDisplay=curDisplay;
elem.style.display=”none”;
}
}
//设置折射率
function setOpacity(elem,num){
if(elem.filters){
elem.style.filter=”alpha(opacity=”+num+”)”;
}else{
elem.style.opacity=num/100;
}
}
//滑动
function slideDown(elem){
var h=getFullHeight(elem);
elem.style.height=”0px”;
show(elem);
for(var i=0;i<=100;i+=5){
new function(){
var pos=i;
setTimeout(function(){elem.style.height=(pos/100*h)+”px”;},(pos*10));
}
}
}
//渐变
function fadeIn(elem){
show(elem);
setOpacity(elem,0);
for(var i=0;i<=100;i+=5){
new function(){
var pos=i;
setTimeout(function(){setOpacity(elem,pos);},(pos+1)*10);
}
}
}
//获取鼠标光标相对于整个页面包车型地铁职位。
function getX(e){
e=e||window.event;
return e.pageX||e.clientX+document.body.scrollLeft;
}
function getY(e){
e=e||window.event;
return e.pageY||e.clientY+document.body.scrollTop;
}
//获取鼠标光标相对于当下元素的任务。
function getElementX(e){
return (e&&e.layerX)||window.event.offsetX;
}
function getElementY(e){
return (e&&e.layerY)||window.event.offsetY;
}
//获取页面包车型大巴冲天和幅度
function getPageHeight(){
var de=document.documentElement;
return document.body.scrollHeight||(de&&de.scrollHeight);
}
function getPageWidth(){
var de=document.documentElement;
return document.body.scrollWidth||(de&&de.scrollWidth);
}
//获取滚动条的职位。
function scrollX(){
var de=document.documentElement;
return
self.pageXOffset||(de&&de.scrollLeft)||document.body.scrollLeft;
}
function scrollY(){
var de=document.documentElement;
return self.pageYOffset||(de&&de.scrollTop)||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;
}

相关小说

有关找寻:

明天看甚

索求本领库

重临首页

  • 隐性调用php程序的点子
  • 浅谈JavaScript中的Math.atan()方法的利用
  • JavaScript中反正弦函数Math.asin()的施用简要介绍
  • JavaScript中的acos()方法运用详解
  • 介绍JavaScript中Math.abs()方法的应用
  • JavaScript中Math.SQRT2属性的选拔详解

有关频道:
HTML/CSS  HTML5  Javascript  jQuery  AJax教程  前者代码  正则表明式  Flex教程  WEB前端教程  

二、怎么样得到当前浏览器扶助的transform包容写法

transform是css三的习性,当大家应用它时就只好面对兼容性的难点。分歧版本浏览器的十分写法大约有如下两种:

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

所以大家须要推断当前浏览器情形扶助的transform属性是哪1种,方法如下:

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的值。

您大概感兴趣的篇章:

  • jQuery常用知识点计算以及平常包裹常用函数
  • 基于jquery封装的四个js分页
  • jquery数组封装使用方式分享(jquery数组遍历)
  • Jquery封装tab自动切换效果的现实贯彻
  • jquery自动将form表单封装成json的求实贯彻
  • jquery
    datatable后台封装数据示例代码
  • jQuery核心图切换特效插件封装实例
  • 依照jquery的用dl模拟完成可自定义样式的SELECT下拉列表(已打包)
  • jQueryUI的Dialog的简约包装
  • 【卓越源码收藏】基于jQuery的花色常见函数封装会集

帮客批评

三、 怎么样得到成分的起先地点

大家率先须求得到到目的成分的发端地方,由此这里大家供给一个专门用来得到成分样式的效应函数。

唯独获取成分样式在IE浏览器与其他浏览器有一部分例外,由此大家须要贰个包容性的写法。

JavaScript

function getStyle(elem, property) { //
ie通过currentStyle来获取成分的样式,其余浏览器通过getComputedStyle来博取
return document.defaultView.getComputedStyle ?
document.defaultView.getComputedStyle(elem, false)[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
            }
        }
    }
}

在拖拽过程中,大家须要不停的安装目的成分的新任务,那样它才会移动起来,由此大家须求3个设置目的成分地点的章程。

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

当我们将元素绑定那几个事件时,有四个风云目的将会作为参数字传送递给回调函数,通过事件目的,我们得以拿走到近期鼠标的可信赖地点,鼠标地方新闻是促成拖拽的根本。

事件目的13分要害,在那之中积存了这几个多的卓有作用的音信,这里小编就不扩展了,大家可以在函数元帅事件目标打字与印刷出来查看里面包车型大巴切切实实性质,那么些法子对于记不清事件目的首要性质的童鞋格外有效。

六、拖拽的规律

当事件触发时,大家得以因此事件目的获得到鼠标的精切地点。那是得以达成拖拽的主要性。当鼠标按下(mousedown触发)时,大家必要牢记鼠标的初始地方与对象成分的初叶地点,大家的对象正是贯彻当鼠标移动时,目的成分也跟着移动,遵照原理大家能够汲取如下事关:

活动后的鼠标地点 – 鼠标伊始地点 = 移动后的对象成分地方 –
目的成分的早先地点

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

假定鼠标地点的差值我们用dis来代表,那么目的成分的岗位就也就是:

一抬手一动脚后目的成分的地方 = dis + 目的成分的早先地方

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

经过事件目的,大家能够确切的驾驭鼠标的脚下职分,由此当鼠标拖动(mousemove)时,大家得以不停的总结出鼠标移动的差值,以此来求出目的元素的目前岗位。这几个进程,就贯彻了拖拽。

而在鼠标放开(mouseup)停止拖拽时,大家需求管理部分收尾职业。实际情况见代码。

7、 笔者又来推荐思维导图协理写代码了

平日有新人朋友跑来问小编,纵然逻辑思维工夫不强,能还是不能够写代码做前端。作者的答案是:能。因为依据思维导图,能够很自在的弥补逻辑的短板。而且比在和煦头脑中脑补逻辑更是清晰明了,不易出错。

上边第伍点自身介绍了规律,因而如何做就显得不是那么难了,而具体的步子,则在底下的思维导图中一览了然给出,大家只须要依照那几个手续来写代码就能够,试试看,一定很自在。

www.bifa88.com 2

运用思维导图清晰的表述出总体拖拽进程大家须要干的事体

八、代码完结

part一、希图干活

JavaScript

// 获取目的成分对象 var oElem = document.getElementById(‘target’); //
证明2个变量用来保存鼠标开始地方的x,y坐标 var startX = 0; var startY =
0; // 注脚二个变量用来保存目的成分开始地方的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;

part二、作用函数

因为在此以前曾经贴过代码,就不再重复

JavaScript

// 获取当前浏览器援救的transform兼容写法 function getTransform() {} //
获取成分属性 function getStyle(elem, property) {} // 获取成分的开始地点function getTargetPos(elem) {} // 设置成分的始发地方 function
setTargetPos(elem, potions) {}

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.add伊夫ntListener(‘mousemove’, move, false);
document.add伊芙ntListener(‘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.remove伊夫ntListener(‘mousemove’, move);
document.remove伊芙ntListener(‘mouseup’, end); // 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,2个简短的拖拽,就这么欢欣的得以完毕了。点击下边的链接,能够在线查看该例子的demo。

利用原生js完毕拖拽

九、封装拖拽对象

在前头一章作者给咱们大饱眼福了面向对象怎么样得以实现,基于那些基础知识,我们来将方面完结的拖拽封装为一个拖拽对象。大家的目的是,只要大家声可瑞康(Karicare)个拖拽实例,那么传入的靶子成分将电动具备能够被拖拽的意义。

在实际上付出中,二个对象大家平时会单独放在1个js文件中,这么些js文件将独立作为七个模块,利用各个模块的情势组织起来使用。当然这里未有复杂的模块交互,因为那几个例子,大家只供给2个模块就能够。

为了制止变量污染,大家必要将模块放置于2个函数自实行措施模拟的块级作用域中。

JavaScript

; (function() { … })();

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

在平凡的模块组织中,我们只是独自的将洋洋js文件减弱成为三个js文件,由此这里的第二个分店则是为着防止上一个模块的最后不用分号导致报错。不可或缺。当然在通过require可能ES6模块等措施就不会见世如此的境况。

我们通晓,在包装2个对象的时候,大家得以将性能与格局放置于构造函数恐怕原型中,而在增添了自进行函数之后,大家又足以将品质和办法幸免与模块的个中功能域。那是闭包的知识。

那正是说我们面临的挑衅就在于,怎么着客观的管理属性与措施的地方。

自然,每二个目的的场合都不雷同,不能够玉石俱焚,大家须求分明的明亮那三种职位的风味才具做出最适合的垄断(monopoly)。

  • 构造函数中:
    属性与艺术为近来实例单独具备,只好被日前实例访问,并且每声美素佳儿(Friso)个实例,当中的方法都会被再一次创造2回。
  • 原型中:
    属性与方式为持有实例共同享有,能够被有着实例访问,新评释实例不会重新制造方法。
  • 模块功能域中:属性和方法不可能被别的实例访问,但是能被里面方法访问,新表明的实例,不会重新创造一样的法子。

对此艺术的论断相比较轻易。

因为在构造函数中的方法总会在宣称二个新的实例时被另行创立,由此大家评释的不二等秘书籍都尽量制止出未来构造函数中。

而只要您的点子中供给用到构造函数中的变量,大概想要公开,那就须求放在原型中。

若是艺术须求个人不被外界访问,那么就停放在模块成效域中。

对此属性放置于怎么样岗位有些时候很难做出科学的决断,因而小编很难交付一个纯正的概念告诉您怎么样性质一定要放在怎样地点,那亟需在实际上开荒中穿梭的下结论经验。但是总的来讲,依然要结合那多少个职位的性状来做出最合适的论断。

若果属性值只可以被实例单独具备,举个例子person对象的name,只可以属于某三个person实例,又比方这里拖拽对象中,某四个成分的起首地方,也仅仅只是那么些因素的方今地点,这么些本性,则吻合放在构造函数中。

而一旦1特质量仅仅供内部方法访问,那几个性格就符合放在模块功用域中。

关于面向对象,上边的几点思考自身认为是那篇文章最值得认真思虑的精髓。如果在封装时未有怀恋清楚,很只怕会高出海重机厂重您意外的bug,所以建议大家结合本身的费用经历,多多思量,总计出本身的见地。

依照那一个观念,我们能够友善尝尝封装一下。然后与本人的做一些比较,看看大家的主见有何样两样,在下边例子的注释中,笔者将和煦的主张表明出来。

点击查阅已经封装好的demo

js 源码

JavaScript

; (function() { // 那是一个个体属性,没有供给被实例访问 var transform =
getTransform(); function Drag(selector) { //
放在构造函数中的属性,都是属于每3个实例单独具有 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.add伊夫ntListener(‘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.add伊芙ntListener(‘mousemove’,
move, false); document.add伊夫ntListener(‘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.remove伊夫ntListener(‘mousemove’, move);
document.remove伊夫ntListener(‘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; })(); // 使用:证明一个拖拽实例 new Drag(‘target’);
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 收藏
评论

www.bifa88.com 3