拖拽原生js

拖拽代码:

"use strict";
;(() => {
  const isFunction = (fn) => {
    return typeof fn === 'function';
  }
  const isObject = (o) => {
    return typeof o === 'object';
  }
  const isString = (str) => {
    return typeof str === 'string';
  }
  const isArray = (arr) => {
    return Object.prototype.toString.call(arr) === '[object Array]';
  }
  const isPC = () => {
    return !navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
  } 
  const getEl = (el) => {
    return !el ? null : ( isString(el) ? document.querySelector(el) : el);
  }
  const getStyle = (ele) => {
    var style = null;
    if(window.getComputedStyle) {
        style = window.getComputedStyle(ele, null);
    }else{
        style = ele.currentStyle;
    }
    
    return style;
}
  const addEvent = (el, type, cb, capture = false ) => {
    if( isString(type) ) {
      el.addEventListener(type || 'click', cb, capture);
    } else if (isArray(type)) {
      type.map(event => addEvent(el, event, cb, capture));
    } 
  }
  const removeEvent = (el, type, cb, capture = false) => {
    if( isString(type) ) {
      el.removeEventListener(type || 'click', cb, capture);
    } else if (isArray(type)) {
      type.map(event => removeEvent(el, event, cb, capture));
    } 
  }
  const initEvent = ['touchstart', 'mousedown', 'touchend', 'mouseup'];
  const moveEvent = ['touchmove', 'mousemove', 'mouseup'];
  class DragEvent {
    constructor(el, event) {
      if( !el ) return;
      const {top, left, width, height} = el.getBoundingClientRect();
      this.t = top;
      this.l = left;
      this.w = width;
      this.h = height;
      this.el = el;
      if( event ) {
        this.time = new Date().getTime();
        this.event = event;
        this.setPoint(event);
      }
    }
    get Page() {
      const event = this.event;
      const { pageX, pageY } = isPC() ? event : event.touches[0];
      return {pageX, pageY};
    }
    setPoint() {
      this.pointX = this.Page.pageX;
      this.pointY = this.Page.pageY;
    }
  }
  class _Drag {
    static zIndex = 1;
    constructor(options, cb) {
      let el = null, wrap = document.body;
      if( !options ) return false;
      if ( isObject(options) ) {
        if (options.nodeType === 1) {
          el = options;
        } else {
          const {el: oel, wrap: oWrap} = options;
          el = oel || null;
          wrap = oWrap || wrap;
        }
      }
      this.el = getEl(el);
      const zIndex = Number(getStyle(this.el).zIndex);
      _Drag.zIndex = (zIndex && zIndex > _Drag.zIndex) ? zIndex : _Drag.zIndex;
      this.wrapNode = getEl(wrap);
      this.cb = cb;
      this.startDrag = null;
      this.endDrag = null;
      this.moveDrag = null;
      this.wrap = new DragEvent(this.wrapNode);
      this.init();
    }
    get moveTarget() {
      return document;
    }
    handleEvent(e) {
      const isPc = isPC();
      const Build = isPc ? {
          mousedown: this.start,
          mousemove: this.move,
          mouseup: this.end,
          mouseout: this.end
        } : {
          touchstart: this.start, 
          touchmove: this.move,
          touchend: this.end,
        }
      if( e.type && Build[e.type]) Build[e.type].call(this, e);
    }
    render(dragEvent) {
      const { l, t } = dragEvent;
      this.el.style.top = t + 'px';
      this.el.style.left = l + 'px';
    }
    start(e) {
      const { el, cb : { startCb } } = this;
      const Event = new DragEvent(el, e);
      _Drag.zIndex += 1;
      el.style.zIndex = _Drag.zIndex;
      el.style.position = 'fixed';
      addEvent( this.moveTarget, moveEvent, this);
      this.startDrag = Event;
      this.moveDrag = Event;
      this.render(Event);
      startCb(Event);
    }
    move(event) {
      const {cb : { moveCb }, startDrag: start, wrap } = this;
      const { pageX, pageY } = isPC() ? event : event.touches[0];
      let l = pageX - (start.pointX - start.l),
          t = pageY - (start.pointY - start.t);
      if ( l <= wrap.l ) l = wrap.l;
      if ( l >= (wrap.l + wrap.w - start.w)) l = wrap.l + wrap.w - start.w;
      if ( t <= wrap.t ) t = wrap.t; 
      if ( t >= (wrap.t + wrap.h - start.h) ) t = wrap.t + wrap.h - start.h; 
      let ld = (l - this.moveDrag.l),
          td = (t - this.moveDrag.t);
      ld = ld > 0 ? 1 : (ld < 0 ? -1 : ld);    
      td = td > 0 ? 1 : (td < 0 ? -1 : td);
      Object.assign(this.moveDrag, { l, t, ld, td, pointX : pageX, pointY : pageY }); 
      this.render(this.moveDrag);
      event.preventDefault();
      moveCb(this.moveDrag);
    }
    end(e) {
      const { el, cb: { endCb } } = this;
      removeEvent(this.moveTarget, moveEvent, this);
      this.endDrag = new DragEvent(el, e);
      endCb(this.endDrag);
    }
    init() {
      const { el } = this;
      addEvent(el, initEvent, this);
    }
    destory() {
      removeEvent(el, initEvent, this);
    }
  }
  class Drag {
    constructor(...options) {
      this.startList = [];
      this.moveList = [];
      this.endList = [];  
      this.drag = new _Drag(...options, {
         startCb: o => this.fnCb('startList', o), 
         moveCb: o => this.fnCb('moveList', o), 
         endCb: o => this.fnCb('endList', o),
        });
    }
    fnCb(type, o) {
      this[type].map(item => item(o));
    }
    start(cb) {
      if( isFunction(cb) ) this.startList.push(cb); 
    }
    move(cb) {
      if( isFunction(cb) ) this.moveList.push(cb);
    }
    end(cb) {
      if( isFunction(cb) ) this.endList.push(cb);
    }
  }
  window.Drag = Drag;
  if(typeof module === 'object' && module.export) module.export = Drag; 
})(window);

如何调用:

<html>
  <style>
    body {
      border: 1px solid grey;
      margin: 40px;
      padding: 20px;
    }
    div:nth-of-type(odd){
      border: 1px solid green;
    }
    div:nth-of-type(even) {
      border: 1px solid yellow;
    }
    .item {
      width: 100px;
      height: 100px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: red;
    }
  </style>
  <body>
    <div id="item" class="item" >
      哈哈
    </div>
    <div id="xixi" class="item">嘻嘻嘻</div>
  </body>
  <script src="./drag.js"></script>
  <script type="text/javascript">
    const el = document.querySelector('#item');
    const xixi = document.querySelector('#xixi');
    new Drag(xixi);
    const drag = new Drag(el);
    //支持绑定多个事件
    drag.start((e) => {
      // console.log('out-start:', e);
    });
    drag.start((e) => {
      // console.log('out-start:', e);
    });
  
    drag.move((e) => {
      // console.log('out-move: ', e.ld);
    });
    drag.end(() => {
      // console.log('out-end');
    });
  </script>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值