您的位置:新葡亰496net > 新葡亰官网 > 新葡亰496net:心碎的JavaScript公用方法,Resig本人

新葡亰496net:心碎的JavaScript公用方法,Resig本人

发布时间:2019-07-07 13:34编辑:新葡亰官网浏览(102)

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

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

    原文出处: 波同学   

    新葡亰496net 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();
    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的方法
    新葡亰496net:心碎的JavaScript公用方法,Resig本人包裹的javascript。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常用脚本了,希望大家能够喜欢。

    本文给大家分享的常用脚本有通过数组,拓展字符串拼接容易导致性能的问题、页面 视口 滚动条的位置的辅助...

    JavaScript常用脚本汇总(三),javascript脚本汇总

    通过数组,拓展字符串拼接容易导致性能的问题

    复制代码 代码如下:
    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属性来切换元素可见性的一组函数

    复制代码 代码如下:
    新葡亰496net:心碎的JavaScript公用方法,Resig本人包裹的javascript。/**
     * 使用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常用脚本了,希望大家能够喜欢。

    通过数组,拓展字符串拼接容易导致性能的问题 复制代码 代码如下: function StringBuffer() {...

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

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

    相关文章

    相关搜索:

    今天看啥

    搜索技术库

    返回首页

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

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

    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;
    }
    addEvent.guid = 1;//创建独立ID的计数器
    function removeEvent(element, type, handler) {//从散列表中删除事件处理函数
    if (element.events && element.events[type]) {
    delete element.events[type][handler.$$guid];
    }
    }
    function handleEvent(event) {
    var returnValue = true;
    event = event || fixEvent(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 = fixEvent.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;//返回元素的完整高度
    }

    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)结束拖拽时,我们需要处理一些收尾工作。详情见代码。

    新葡亰496net 2

    7、 我又来推荐思维导图辅助写代码了

    常常有新人朋友跑来问我,如果逻辑思维能力不强,能不能写代码做前端。我的答案是:能。因为借助思维导图,可以很轻松的弥补逻辑的短板。而且比在自己头脑中脑补逻辑更加清晰明了,不易出错。

    上面第六点我介绍了原理,因此如何做就显得不是那么难了,而具体的步骤,则在下面的思维导图中明确给出,我们只需要按照这个步骤来写代码即可,试试看,一定很轻松。

    新葡亰496net 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.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 }

    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模块等方式就不会出现这样的情况。

    我们知道,在封装一个对象的时候,我们可以将属性与方法放置于构造函数或者原型中,而在增加了自执行函数之后,我们又可以将属性和方法防止与模块的内部作用域。这是闭包的知识。

    那么我们面临的挑战就在于,如何合理的处理属性与方法的位置。

    当然,每一个对象的情况都不一样,不能一概而论,我们需要清晰的知道这三种位置的特性才能做出最适合的决定。

    • 构造函数中: 属性与方法为当前实例单独拥有,只能被当前实例访问,并且每声明一个实例,其中的方法都会被重新创建一次。
    • 原型中: 属性与方法为所有实例共同拥有,可以被所有实例访问,新声明实例不会重复创建方法。
    • 模块作用域中:属性和方法不能被任何实例访问,但是能被内部方法访问,新声明的实例,不会重复创建相同的方法。

    对于方法的判断比较简单。

    因为在构造函数中的方法总会在声明一个新的实例时被重复创建,因此我们声明的方法都尽量避免出现在构造函数中。

    而如果你的方法中需要用到构造函数中的变量,或者想要公开,那就需要放在原型中。

    如果方法需要私有不被外界访问,那么就放置在模块作用域中。

    对于属性放置于什么位置有的时候很难做出正确的判断,因此我很难给出一个准确的定义告诉你什么属性一定要放在什么位置,这需要在实际开发中不断的总结经验。但是总的来说,仍然要结合这三个位置的特性来做出最合适的判断。

    如果属性值只能被实例单独拥有,比如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.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');

    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 收藏 评论

    新葡亰496net 4

    本文由新葡亰496net发布于新葡亰官网,转载请注明出处:新葡亰496net:心碎的JavaScript公用方法,Resig本人

    关键词: