常用函数,面向对象实战之封装拖拽对象

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

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

原稿出处: 波同学   

美高梅开户网址 1

终于

前边几篇小说,我跟我们大快朵颐了JavaScript的一部分基础知识,这篇作品,将会进去第二个实战环节:利用前面几章的所涉及到的知识,封装一个拖拽对象。为了可以协助我们通晓越多的方法与展开相比较,我会使用二种分化的法子来促成拖拽。

  • 不封装对象直接促成;
  • 使用原生JavaScript封装拖拽对象;
  • 透过增加jQuery来兑现拖拽对象。

本文的例子会停放于codepen.io中,供大家在读书时一贯查看。如若对于codepen不打听的校友,可以花点时间稍微明白一下。

拖拽的兑现进程会涉嫌到越发多的实用小知识,由此为了加固自身自己的知识积累,也为了我们可以学到越来越多的学问,我会尽量详细的将一部分细节分享出来,相信大家认真读书之后,一定能学到一些事物。

复制代码 代码如下:

function stopBubble(e) {
if (e && e.stopPropagation) {//如若传入了风云目的,那么就是非IE浏览器
e.stopPropagation();
} else {
window.event.cancelBubble = true;//使用IE的法子来废除事件冒泡
}
}
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault();//幸免默许浏览器行为(W3C)
} else {
window.event.returnValue = false;
}
return false;
}

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();
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来其的职位暴发变更。在底下的例证中,每点击五次按钮,对应的因素就会活动5px。大家可点击查阅。

点击查阅一个让元素动起来的小例子

鉴于修改一个因素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;
}

function addEvent(element, type, handler) {
if (!handler.$$guid) {//为每一个事件处理函数赋予一个单独的ID
handler.$$guid = addEvent.guid++;
}
if (!element.events) {//为元素建立一个轩然大波类型的散列表
element.events = {};
}
var handlers = element.events[type];
if (!handler) {
handlers = element.events[type] = {};
if (element[“on” + type])
{//存储已有些事件处理函数(若是已经存在一个)
handlers[0] = element[“on” + type];
}
}
handlers[handler.$$guid] = handler;//在散列表中留存该事件处理函数
element[“on” + type] = handleEvent;
}
add伊芙nt.guid = 1;//创制独立ID的计数器
function remove伊芙nt(element, type, handler)
{//从散列表中删去事件处理函数
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
}
function handleEvent(event) {
var returnValue = true;
event = event ||
fix伊芙nt(window.event);//得到事件目标(IE使用全局的风云目的)
var handlers =
this.events[event.type];//得到事件处理函数散列表的引用
for (var i in handlers) {//依次执行种种事件处理函数
this.$$handlerEvent = handlers[i];
if (this.$$handlerEvent(event) === false) {
returnValue = false;
}
}
return returnValue;
}
function fixEvent(event) {//扩展一些IE事件目的的短缺的措施
event.preventDefault = fix伊夫nt.preventDefault;//伸张W3C标准事件措施
event.stopPropagation = fixEvent.stopPropagation;
return event;
}
fixEvent.preventDefault = function () {
this.returnValue = false;
}
fixEvent.stopPropagation = function () {
this.cancelBubble = true;
}
//获取指定元素elem的样式属性
function getStyle(elem, name) {
if (elem.style[name])
{//若是属性存在于style[]中,那么它已被装置了(并且是眼前的)
return elem.style[name];
} else {
if (elem.currentStyle) {//尝试使用IE的措施
return elem.currentStyle[name];
} else if (document.defaultView &&
document.defaultView.getComputedStyle) {//或者W3C的不二法门,若是存在的话
//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(水平、左端)地点
function pageX(elem) {
return elem.offsetParent ?//查看大家是不是位于根元素
elem.offsetLeft + pageX(elem.offsetParent)
://假如大家能继续取得上一个因素,增添当前的偏移量并一连升高递归
elem.offsetLeft;//否则得到当前的偏移量
}
//获得元素Y(垂直、顶端)地点
function pageY(elem) {
return elem.offsetParent ?//查看大家是或不是位于根元素
elem.offsetTop + pageY(elem.offsetParent)
://若是能延续得到上一个元素,增添当前的偏移量并继续进步递归
elem.offsetTop;//否则获取当前的偏移量
}
//获取元素相对于五伯的程度地方
function parentX(elem) {
return elem.parentNode == elem.offsetParent
?//若是offsetParent是因素的大爷,那么提前退出
elem.offsetLeft :
pageX(elem) –
pageX(elem.parentNode);//否则,大家必要找到元素和因素的三伯相对于漫天页面地点,并盘算他们前边的差
}
//获取元素相对于伯伯的垂直地点
function parentY(elem) {
return elem.parentNode == elem.offsetParent
?//倘诺offsetParent是因素的伯伯,那么提前退出
elem.offsetTop :
pageX(elem) –
pageY(elem.parentNode);//否则,大家必要找到元素和要素的生父相对于一体页面地方,并计算他们事先的差
}
//復苏css原的品质值 幸免reset css函数副成效的函数
function restoreCSS(elem, prop) {
for (var i in prop) {//重置所有属性,恢复生机它们的原有值
elem.style[i] = prop[i];
}
}
//设置CSS一组属性的函数,它可以过来到原来设置
function resetCSS(elem, prop) {
var old = [];
for (var i in prop) {
old[i] = elem.style[i];//记录旧的属性值
elem.style[i] = prop[i];//并设置新的值
}
return old;//重临已经转移的值集合,预留给restoreCSS函数使用
}
function getHeight(elem) {//得到元素的真正中度
return parseInt(getStyle(elem,
‘height’));//得到CSS的末梢值并分析出可用的数值
}
function getWidth(elem) {//获得元素的忠实宽度
return parseInt(getStyle(elem,
‘width’));//得到CSS的末段值并分析出可用的数值
}
//查找元素完整的,可能的惊人
function fullHeight(elem) {
//即使元素是浮现的,那么使用offsetHeight就能获取中度,如若没有offsetHeight,则动用getHeight()
if (getStyle(elem, ‘display’) != ‘none’) {
return elem.offsetHeight || getHeight(elem);
}
//处理display为none的因素,所以重置它的css属性以得到更确切的读数
var old = resetCSS(elem, {
display: ”,
visibility: ‘hidden’,
position: ‘absolute’
});
var h = elem.clientHeight ||
getHeight(elem);//使用clientHeihgt找到元素的一体化中度,借使还不见效,则使用getHeight函数
restoreCSS(elem, old);//恢复生机css原的质量
return h;//重临元素的全部中度
}
//查找元素完整的,可能的增幅
function fullWidth(elem) {
//假诺元素是显示的,那么使用offsetWidth就能赢得中度,假如没有offsetHeight,则采纳getHeight()
if (getStyle(elem, ‘display’) != ‘none’) {
return elem.offsetWidth || getWidth(elem);
}
//处理display为none的元素,所以重置它的css属性以取得更准确的读数
var old = resetCSS(elem, {
display: ”,
visibility: ‘hidden’,
position: ‘absolute’
});
var h = elem.clientWidth ||
getWidth(elem);//使用clientWidth找到元素的共同体中度,即使还不见效,则选拔getWidth函数
restoreCSS(elem, old);//復苏css原的属性
return h;//重临元素的一体化中度
}

连锁作品

有关搜索:

明天看甚

摸索技术库

回去首页

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

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

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

您可能感兴趣的小说:

  • jQuery常用知识点总括以及日常包裹常用函数
  • 据悉jquery封装的一个js分页
  • jquery数组封装使用办法分享(jquery数组遍历)
  • Jquery封装tab自动切换效果的现实落实
  • jquery自动将form表单封装成json的具体贯彻
  • jquery
    datatable后台封装数据示例代码
  • jQuery宗旨图切换特效插件封装实例
  • 基于jquery的用dl模拟完毕可自定义样式的SELECT下拉列表(已打包)
  • jQueryUI的Dialog的简要包装
  • 【经典源码收藏】基于jQuery的档次常见函数封装集合

function hide(elem) {//隐藏元素
var curDisplay = getStyle(elem, ‘display’);//找到元素display的当下境况
if (curDisplay != ‘none’) {//记录它的display状态
elem.$oldDisplay = curDisplay;
}
elem.style.display = ‘none’;//设置display为none 隐藏元素
}
function show(elem) {//呈现元素
elem.style.display = elem.$oldDisplay ||
”;//设置display属性为它的原始值,如没有记录原始值 则应用block
}

帮客评论

3、 怎样取得元素的起来地方

咱俩先是须要取得到对象元素的开端地方,由此那里大家要求一个专门用来获取元素样式的作用函数。

不过获取元素样式在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
            }
        }
    }
}

在拖拽进度中,我们必要不停的设置目的元素的新岗位,那样它才会移动起来,由此大家须求一个装置目标元素地点的情势。

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;
}

function setOpacity(elem, level) {//设置元素透明度 级别从0-100
if (elem.filters) {//假设存在filters那几个属性 则它是IE
所以设置元素的Alpha滤镜
elem.style.filters = “alpha(opacity=” + level + “)”;
} else {
elem.style.opacity = level / 100;//使用W3C的opacity属性
}
}
function slideDown(elem) {
elem.style.height = ‘0px’;//从0高度开首滑动
show(elem);//先显示元素(可是看不到它,因为它的莫大是0)
var h = fullHeight(elem);//找到元素的全部的隐秘中度
for (var i = 0; i <= 100; i += 5) {//在一分钟内推行一个20帧的动画
//保障可以保持正确的i的闭包函数
(function () {
var pos = i;
setTimeout(function () {
elem.style.height = ((pos / 100) * h) + ‘px’;
}, (pos + 1) * 10);
})();
}
}
function fadeIn(elem) {
setOpacity(elem, 0);//从0透明度起头
show(elem);//先突显元素(不过看不到它,因为它的透明度是0)
for (var i = 0; i <= 100; i += 5) {//在一分钟内推行一个20帧的动画
//有限帮忙可以维持正确的i的闭包函数
(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;//先检查非IE浏览器的职位,再自我批评IE的位置
}
function getY(e) {//获取光标的垂直地点
e = e || window.event;//标准化事件目的
return e.pageY || e.clientY +
document.body.scrollTop;//先反省非IE浏览器的地方,再检查IE的岗位
}
function getElementX(e)
{//得到鼠标相对于当下元素(事件对象e的性质target)的X地方
return (e && e.layerX) || window.event.offsetX;//得到正确的偏移量
}
function getElementY(e)
{//得到鼠标相对于当下元素(事件对象e的特性target)的Y地点
return (e && e.layerY) || window.event.offsetY;//获得不错的偏移量
}
function pageHeight() {//重回页面的冲天(扩充内容的时候可能会变动)
return document.body.scrollHeight;
}
function pageWidth() {//重临页面的宽窄(扩展内容的时候恐怕会转移)
return document.body.scrollWidth;
}
function scrollX() {//确定浏览器水平滚动地点的函数
var de = document.documentElement;
return self.pageXOffset ||//若是浏览器存在pageXOffset属性 则应用它
(de || de.scrollLeft) ||//尝试获取根节点的左端滚动的偏移量
document.body.scrollLeft;//尝试获取body元素的左端滚动的偏移量
}
function scrollY() {//确定浏览器垂直滚动地方的函数
var de = document.documentElement;
return self.pageYOffset ||//若是浏览器存在pageYOffset属性 则运用它
(de || de.scrollTop) ||//尝试获取根节点的上方滚动的偏移量
document.body.scrollTop;//尝试获得body元素的上方滚动的偏移量
}
function windowHeight() {//获取视口的惊人
var de = document.documentElement;
return self.innerHeight ||////借使浏览器存在innerHeight属性 则使用它
(de && de.clientHeight) ||//尝试获取根节点的莫大偏移量
document.body.clientHeight;//尝试获取body元素的可观偏移量
}
function windowWidth() {//获取视口的增幅
var de = document.documentElement;
return self.innerWidth ||////如果浏览器存在innerWidth属性 则使用它
(de && de.clientWidth) ||//尝试获取根节点的可观偏移量
document.body.clientWidth;//尝试获取body元素的万丈偏移量
}

5、我们要求用到怎么着事件?

在pc上的浏览器中,结合mousedown、mousemove、mouseup那多少个事件可以襄助大家完结拖拽。

  • mousedown 鼠标按下时接触
  • mousemove 鼠标按下后拖动时接触
  • mouseup 鼠标松开时触发

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

当大家将元素绑定那么些事件时,有一个事件目标将会作为参数传递给回调函数,通过事件目的,大家能够获得到当下鼠标的纯粹地点,鼠标地方音信是促成拖拽的首要。

事件目的格外重视,其中含有了丰硕多的管用的音信,这里我就不扩充了,大家可以在函数少将事件目的打印出来查看里面的现实性质,那一个方法对于记不清事件目标首要性质的童鞋至极实惠。

 随机数公式:

6、拖拽的规律

当事件触发时,大家得以由此事件目的获得到鼠标的精切地点。那是落到实处拖拽的主要。当鼠标按下(mousedown触发)时,大家要求记住鼠标的启幕地方与对象元素的初叶地点,大家的对象就是落成当鼠标移动时,目的元素也随后移动,依据原理大家得以汲取如下事关:

运动后的鼠标地方 – 鼠标伊始地方 = 移动后的目的元素地方 –
目的元素的发轫地点

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

假定鼠标地方的差值大家用dis来代表,那么目标元素的职位就等于:

移步后目的元素的岗位 = dis + 目标元素的启幕地方

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

通过事件目的,大家得以确切的理解鼠标的当前任务,由此当鼠标拖动(mousemove)时,大家得以不停的乘除出鼠标移动的差值,以此来求出目的元素的此时此刻职责。这一个进程,就贯彻了拖拽。

而在鼠标松开(mouseup)截至拖拽时,我们须要处理局地了结工作。详情见代码。

美高梅开户网址 2

7、 我又来推举思维导图帮助写代码了

经常有新人朋友跑来问我,借使逻辑思维能力不强,能无法写代码做前端。我的答案是:能。因为依靠思维导图,能够很轻松的弥补逻辑的短板。而且比在大团结头脑中脑补逻辑更是清晰明了,不易出错。

地点第六点我介绍了规律,因而怎么样做就显示不是那么难了,而实际的步调,则在上面的想想导图中鲜明给出,我们只需求遵从这一个手续来写代码即可,试试看,一定很轻松。

美高梅开户网址 3

采用思维导图清晰的发布出全体拖拽进度我们须要干的政工

 

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) {}

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,一个简便的拖拽,就那样欢悦的落实了。点击上边的链接,可以在线查看该例子的demo。

利用原生js达成拖拽

9、封装拖拽对象

在面前一章我给大家分享了面向对象如何促成,基于那多少个基础知识,大家来将地点完毕的拖拽封装为一个拖拽对象。大家的对象是,只要大家声可瑞康(Nutrilon)个拖拽实例,那么传入的靶子元素将活动具备可以被拖拽的意义。

在实际开发中,一个对象大家平常会独自放在一个js文件中,这一个js文件将独自作为一个模块,利用各样模块的艺术社团起来使用。当然那里没有复杂的模块交互,因为这一个例子,我们只要求一个模块即可。

为了防止变量污染,大家需求将模块放置于一个函数自推行措施模拟的块级成效域中。

JavaScript

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

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

在普通的模块社团中,大家只是独自的将广大js文件减弱成为一个js文件,因而那里的第三个分公司则是为了预防上一个模块的最终不用分号导致报错。必不可少。当然在通过require或者ES6模块等方法就不会并发如此的事态。

大家知晓,在卷入一个目的的时候,大家能够将质量与措施放置于构造函数或者原型中,而在追加了自实施函数之后,我们又有啥不可将品质和措施幸免与模块的中间功用域。那是闭包的学识。

那就是说大家面临的挑战就在于,如何合理的拍卖属性与办法的义务。

本来,每一个对象的情景都不相同,不可以一碗水端平,大家须求明显的接头那两种职位的特色才能做出最符合的主宰。

  • 构造函数中:
    属性与办法为眼前实例单独拥有,只好被眼前实例访问,并且每声贝拉米个实例,其中的方法都会被另行创立一次。
  • 原型中:
    属性与艺术为保有实例共同所有,可以被有着实例访问,新表明实例不会再也创设方法。
  • 模块功用域中:属性和章程不可能被此外实例访问,不过能被中间方法访问,新讲明的实例,不会另行成立相同的不二法门。

对此艺术的判断相比较简单。

因为在构造函数中的方法总会在声美素佳儿个新的实例时被重复创设,因而大家申明的不二法门都尽量防止出现在构造函数中。

而一旦您的主意中需求用到构造函数中的变量,或者想要公开,那就要求放在原型中。

一经措施必要个人不被外边访问,那么就停放在模块作用域中。

对此属性放置于怎样地方有些时候很难做出正确的论断,由此我很难交付一个准确的定义告诉你怎样性质一定要放在怎么着职位,那须求在其实付出中持续的下结论经验。可是总的来说,仍旧要组成那七个岗位的特点来做出最合适的判断。

若是属性值只能被实例单独拥有,比如person对象的name,只好属于某一个person实例,又比如说此处拖拽对象中,某一个因素的起来地点,也仅仅只是这么些因素的眼前岗位,这一个特性,则吻合放在构造函数中。

而只要一个属性仅仅供内部方法访问,那一个特性就适合放在模块作用域中。

至于面向对象,下面的几点考虑自己以为是那篇小说最值得认真考虑的精彩。即使在封装时没有考虑清楚,很可能会赶上不少您不意的bug,所以指出大家结合自己的开支经历,多多考虑,计算出团结的意见。

据悉那几个考虑,大家可以协调尝试封装一下。然后与自家的做一些对照,看看大家的想法有如何两样,在底下例子的注释中,我将团结的想法表明出来。

点击查看已经封装好的demo

js 源码

JavaScript

; (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.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; })(); // 使用:申明2个拖拽实例 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 收藏
评论

美高梅开户网址 4

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图