欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

拖拽原生js

程序员文章站 2022-07-14 16:45:52
...

拖拽代码:

"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>