UNPKG

@xiaohaih/drag

Version:

拖拽插件, 可通过指令或函数调用来拖拽元素移动

2 lines (1 loc) 16.5 kB
(function(a,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(a=typeof globalThis<"u"?globalThis:a||self,g(a.HDraggable={}))})(this,function(a){"use strict";var gt=Object.defineProperty;var dt=(a,g,x)=>g in a?gt(a,g,{enumerable:!0,configurable:!0,writable:!0,value:x}):a[g]=x;var d=(a,g,x)=>dt(a,typeof g!="symbol"?g+"":g,x);var g=(i=>(i[i.ground=1e3]="ground",i[i.sky=2e3]="sky",i[i.troposphere=3e3]="troposphere",i[i.stratosphere=4e3]="stratosphere",i[i.mesosphere=5e3]="mesosphere",i[i.thermosphere=6e3]="thermosphere",i[i.outerspace=7e3]="outerspace",i))(g||{});function x(i){return typeof i=="function"}function it(i){return typeof i=="string"}function U(i){return Object.prototype.toString.call(i).slice(8,-1)}function nt(i){return U(i)==="Object"}function y(i){return!!i&&i.enable!==!1}function V(){return/AppleWebKit.*Mobile.*/.test(navigator.userAgent)}function E(i,t,e){return i==null?e:typeof i=="string"?E(t.querySelectorAll(i),t):i instanceof Node?[i]:typeof i=="function"?E(i(t),t):Array.isArray(i)?i.reduce((s,n)=>{const r=E(n,t);return r&&(Array.isArray(r)?s.push(...r):s.push(r)),s},[]):i instanceof NodeList||i instanceof HTMLCollection?[...i]:e}function Y(i){return i.touches?i.touches[0]||i.changedTouches[0]:i}function w(i){return i.offsetParent||document.body||document.documentElement}function q(i,t,e){let s=i;for(;s;){if(s===t)return s;if(s===e)return null;s=s.parentElement}return null}function k(i){return{width:i.offsetWidth,height:i.offsetHeight}}function A(i,t){return window.getComputedStyle(i,t)}function L(i,t){t&&(i.classList?i.classList.add(...t.split(" ").filter(Boolean)):i.className+=t)}function H(i,t){if(!t)return;const e=t.split(" ").filter(Boolean);if(i.classList)i.classList.remove(...e);else{const s=i.className.split(" ");e.forEach(n=>{const r=s.indexOf(n);r!==-1&&s.splice(r,1)}),i.className=s.join(" ")}}function I(i,t){const e={left:0,right:0,top:0,bottom:0,x:0,y:0,width:i[`${t}Width`],height:i[`${t}Height`]};let s=i;for(;s;)e.left+=s.offsetLeft,e.top+=s.offsetTop,s=s.offsetParent;return e.x=e.left,e.y=e.top,e.bottom=e.top+e.height,e.right=e.left+e.width,e}const S=V(),T=S?"touchstart":"mousedown",P=S?"touchmove":"mousemove",z=S?"touchend":"mouseup";function K(){return{name:"BoundaryLimit",sort:g.sky+30,install(i){let t=[];i.on("start",e=>{let s=t.find(r=>r[0]===e.target);s||t.push(s=[e.target,{scrollWidth:0,scrollHeight:0}]);const n=w(e.target);s[1].scrollWidth=n.scrollWidth,s[1].scrollHeight=n.scrollHeight}),i.on("axisBeforeUpdate",(e,s)=>{if(!(s.status&&y(s.option.boundaryLimitOptions))||s.option.boundaryLimitOptions.boundaryLimit===!1)return;const r=t.find(l=>l[0]===e.target);if(!r)return;const{scrollWidth:o,scrollHeight:c}=r[1],{width:h,height:u}=k(e.target);e.x+h>o?e.x=o-h:e.x<0&&(e.x=0),e.y+u>c?e.y=c-u:e.y<0&&(e.y=0)})}}}class B{constructor(t){d(this,"option",{setCursor:G,getCursor:D,cursorOver:"move",cursorMoving:"move"});d(this,"plugins",[]);d(this,"operationDom",[]);d(this,"status",!0);d(this,"ratio",[1,1]);d(this,"brokerDoms",[]);d(this,"_cursorTouch","");d(this,"isTouching",!1);d(this,"_cursor","");d(this,"isEntering",!1);d(this,"events",{});d(this,"eventsScope",[]);this.addEventListenerForBrokerDom=this.addEventListenerForBrokerDom.bind(this),this.touchstart=this.touchstart.bind(this),this.down=this.down.bind(this),this.move=this.move.bind(this),this.up=this.up.bind(this),this.mouseenter=this.mouseenter.bind(this),this.mouseleave=this.mouseleave.bind(this),this.setPosition=this.setPosition.bind(this),this.on=this.on.bind(this),this.once=this.once.bind(this),this.off=this.off.bind(this),this.emit=this.emit.bind(this),this.option.disabled&&(this.status=!1),t&&this.updateOption(t)}updateOption(t){return Object.assign(this.option,t),t.eventProxy&&this.formatBrokerDom(),(t.target||this.option.target&&t.handle)&&this.formatDom(),this}enabled(){return this.status=!0,this.addEventsListener(),this}disabled(){return this.status=!1,G(this._cursor),this._cursor="",this.isTouching=this.isEntering=!1,this.removeEventsListener(),this}formatBrokerDom(){this.removeEventListenerForBrokerDoms();const{eventProxy:t}=this.option;this.brokerDoms=E(t,document)||[],this.addEventListenerForBrokerDoms()}addEventListenerForBrokerDoms(){this.brokerDoms.forEach(t=>{t.addEventListener(T,this.addEventListenerForBrokerDom)})}removeEventListenerForBrokerDoms(){this.brokerDoms.forEach(t=>{t.removeEventListener(T,this.addEventListenerForBrokerDom)})}formatDom(){const{target:t,handle:e}=this.option;return this.removeEventsListener(),this.operationDom=[],(this.brokerDoms.length?this.brokerDoms.reduce((n,r)=>(n.push(...E(t,r,[])),n),[]):E(t,document,[])).forEach(n=>{(E(e,n)||[n]).forEach(o=>this.operationDom.push({target:n,handle:o,x:0,y:0,dragging:!1,setPosition:this.setPosition}))}),this.status&&this.addEventsListener(),this}addEventsListener(){this.operationDom.forEach(({handle:t})=>{t.addEventListener(T,this.touchstart),S||(t.addEventListener("mouseenter",this.mouseenter),t.addEventListener("mouseleave",this.mouseleave))})}removeEventsListener(){this.operationDom.forEach(t=>{t.dragging&&this.up(t,{}),t.handle.removeEventListener(T,this.touchstart),t.handle.removeEventListener("mouseenter",this.mouseenter),t.handle.removeEventListener("mouseleave",this.mouseleave)})}addEventListenerForBrokerDom(t){const{target:e}=this.option,{operationDom:s}=this;if(!e||E(e,t.currentTarget,[]).every((l,f)=>{var m;return l===((m=s[f])==null?void 0:m.target)}))return;this.formatDom();const r=this.operationDom.find(l=>q(t.target,l.target,t.currentTarget));if(!r)return;const{clientX:o,clientY:c,pageX:h,pageY:u}=Y(t);this.down(r,{x:o,y:c,pageX:h,pageY:u},t)}touchstart(t){const e=this.operationDom.find(c=>c.handle===t.currentTarget);if(!e)return;const{clientX:s,clientY:n,pageX:r,pageY:o}=Y(t);this.down(e,{x:s,y:n,pageX:r,pageY:o},t)}down(t,e,s){s==null||s.preventDefault(),this.isTouching=!0,this.emit("beforeStart",this.getCustomEvent(t,s),this),this._cursorTouch=this.isEntering?this._cursor:document.body.style.cursor,this.option.setCursor(this.option.getCursor("down",t,this,D));const{position:n,marginLeft:r,marginTop:o}=A(t.target),c=n==="absolute"||n==="fixed",h=c?t.target.offsetLeft:0,u=c?t.target.offsetTop:0,{x:l,y:f}=t.target.getBoundingClientRect();this.ratio=B.getRatioByElement(t.target);const[m,O]=this.ratio;t.dragging=!0,t.clientX=e.x,t.clientY=e.y,t.pageX=e.pageX,t.pageY=e.pageY,t.offsetX=e.pageX-h/m,t.offsetY=e.pageY-u/O,t.offsetInsetX=Math.abs(e.x-l),t.offsetInsetY=Math.abs(e.y-f),t.initialX=h,t.initialY=u,t.ml=r&&Number.parseFloat(r)||0,t.mt=o&&Number.parseFloat(o)||0,t.x=h,t.y=u,L(t.target,this.option.classActive),this.option.classActivated&&this.operationDom.forEach(p=>{p.target===t.target?L(p.target,this.option.classActivated):H(p.target,this.option.classActivated)}),this.emit("start",this.getCustomEvent(t,s),this);const R=p=>{const{clientX:C,clientY:M,pageX:F,pageY:X}=Y(p);this.move(t,{x:C,y:M,pageX:F,pageY:X},p)},b=p=>{const{clientX:C,clientY:M,pageX:F,pageY:X}=Y(p);this.up(t,{x:C,y:M,pageX:F,pageY:X},p),window.removeEventListener(P,R),window.removeEventListener(z,b)};window.addEventListener(P,R,{passive:!1}),window.addEventListener(z,b,{passive:!1})}move(t,e,s){if(!this.status)return;s==null||s.preventDefault(),s==null||s.stopImmediatePropagation(),this.emit("beforeMove",this.getCustomEvent(t,s),this),L(t.target,this.option.classMoving),this.option.setCursor(this.option.getCursor("moving",t,this,D));const[n,r]=this.ratio;t.clientX=e.x,t.clientY=e.y,t.pageX=e.pageX,t.pageY=e.pageY,t.x=(e.pageX-t.offsetX)*n,t.y=(e.pageY-t.offsetY)*r,this.setPosition(t,t.target),this.emit("move",this.getCustomEvent(t,s),this)}up(t,e,s){if(!this.status)return;this.emit("beforeEnd",this.getCustomEvent(t,s),this),H(t.target,this.option.classActive),H(t.target,this.option.classMoving),this.isTouching=!1;const n=this.isEntering?"over":"up";this.option.setCursor(this.option.getCursor(n,t,this,D)||this._cursorTouch),t.dragging=!1,this.emit("end",this.getCustomEvent(t,s),this)}setPosition(t,e){let s=!1;function n(c,h){(c.x!==r.x||c.y!==r.y)&&(s=!0,r.setPosition(c,h))}const r={...t,setPosition:n};if(this.emit("axisBeforeUpdate",r,this),s)return;this.option.virtualAxis||(e.style.left=`${r.x-r.ml}px`,e.style.top=`${r.y-r.mt}px`),t.x=r.x,t.y=r.y;const o=this.operationDom.find(c=>c.target===e);o&&Object.assign(o,t),this.emit("axisUpdated",t,this)}getCustomEvent(t,e){return{...t,native:e}}mouseenter(t){const e=this.operationDom.find(s=>s.handle===t.currentTarget);e&&(this.isEntering=!0,this._cursor=this.isTouching?this._cursorTouch:document.body.style.cursor,!this.isTouching&&this.option.setCursor(this.option.getCursor("over",e,this,D)))}mouseleave(t){const e=this.operationDom.find(s=>s.handle===t.currentTarget);e&&(this.isEntering=!1,!this.isTouching&&this.option.setCursor(this.option.getCursor("out",e,this,D)||this._cursor))}on(t,e,s){return this.events[t]||(this.events[t]=[]),this.events[t].push([e,s]),this.eventsScope.forEach(n=>{n[t]||(n[t]=[]),n[t].push([e,s])}),this}once(t,e){return this.on(t,e,!0)}rebindEvents(t){t&&Object.entries(t).forEach(([e,s])=>{s.forEach(([n,r])=>{this.off(e,n),this.on(e,n,r)})})}off(t,e){return this.eventsScope.forEach(s=>s[t]&&(e?s[t]=s[t].filter(n=>n[0]!==e):delete s[t])),this.events[t]?e?(this.events[t]=this.events[t].filter(s=>s[0]!==e),this.events[t].length||delete this.events[t],this):(delete this.events[t],this):this}emit(t,...e){if(!this.events[t])return this;let s=0;return this.events[t].slice().forEach((n,r)=>{n[0].apply(null,e),n[1]&&(this.events[t].splice(r-s,1),++s)}),this}getFragmentEvents(){const t={};return{get:()=>t,run:()=>{this.eventsScope.push(t)},stop:()=>{const e=this.eventsScope.indexOf(t);e!==-1&&this.eventsScope.splice(e,1)}}}disposeEvents(t){t&&Object.entries(t).forEach(([e,s])=>s.forEach(n=>this.off(e,n[0])))}use(t){const e=t();if(!this.plugins.find(s=>s.name===e.name)){const{run:s,get:n,stop:r}=this.getFragmentEvents();if(this.plugins.push(e),s(),e.install(this),r(),e.events=n(),this.plugins.length<2)return this;this.plugins.sort((o,c)=>(o.sort||0)-(c.sort||0)),this.plugins.forEach(o=>this.rebindEvents(o.events))}return this}unuse(t){var s;const e=typeof t=="string"?this.plugins.findIndex(n=>n.name===t):t;if(e!==-1){const[n]=this.plugins.splice(e,1);n&&((s=n.uninstall)==null||s.call(n,this),this.disposeEvents(n.events))}return this}destroyed(){this.disabled(),this.plugins.forEach(t=>{var e;(e=t.uninstall)==null||e.call(t,this),this.disposeEvents(t.events),delete t.events}),this.eventsScope=[]}static getRatioByElement(t){const{width:e,height:s}=t.getBoundingClientRect(),{offsetWidth:n,offsetHeight:r}=t;return[n/e,r/s]}}function rt(i){return new B(i)}const ot={over:"cursorOver",out:"cursorOut",moving:"cursorMoving",down:"cursorDown",up:"cursorUp"};function D(i,t,e){if(e.status)return e.option[ot[i]]}function G(i){typeof i=="string"&&(document.body.style.cursor=i)}function J(){return{name:"Direction",sort:g.sky+10,install(i){i.on("axisBeforeUpdate",(t,e)=>{if(!(e.status&&y(e.option.directionOptions)))return;e.option.directionOptions.orient==="y"?t.x=t.initialX:t.y=t.initialY})}}}function Q(){let i=[];return{name:"Scrolling",sort:g.sky,install(t){let e=0;function s(o,c){if(!(c.status&&y(c.option.scrollingOptions)))return;const h=c.option.scrollingOptions,u=i.find(v=>v[0]===o.target);if(!u)return;const[l,f]=c.ratio,{threshold:m=40,speed:O=10,scrollOption:R}=h,b={...R},{scrollWidth:p,scrollHeight:C,offsetWidth:M,offsetHeight:F,scrollTop:X,scrollLeft:tt,clientWidth:et,clientHeight:st}=u[1].scrollContainer;if(p<=M&&C<=F)return;const{x:W,y:j}=u[1].scrollContainerRect;o.x=(o.clientX-W-o.offsetInsetX)*l+u[1].x,o.y=(o.clientY-j-o.offsetInsetY)*f+u[1].y;const _=o.clientX-W<m?O*-1:W+et/l-o.clientX<m?O:0,$=o.clientY-j<m?O*-1:j+st/f-o.clientY<m?O:0;if(_){const v=_>0?Math.min(tt+_,p-et):Math.max(0,tt+_);b.left=u[1].x=v,o.x=(o.clientX-W-o.offsetInsetX)*l+v}if($){const v=$>0?Math.min(X+$,C-st):Math.max(0,X+$);b.top=u[1].y=v,o.y=(o.clientY-j-o.offsetInsetY)*f+v}(b.left!==void 0||b.top!==void 0)&&u[1].scrollContainer.scrollTo(b),o.setPosition(o,o.target),u[1].clientX=o.clientX,u[1].clientY=o.clientY}function n(o,c){if(!(c.status&&y(c.option.scrollingOptions)))return;const{scrollMs:h=100}=c.option.scrollingOptions;r(),s(o,c),e=setInterval(s,h,o,c)}function r(){clearInterval(e)}t.on("start",(o,c)=>{if(!(c.status&&y(c.option.scrollingOptions)))return;const{container:h}=c.option.scrollingOptions,u=typeof h=="function"?h(o):h||w(o.target);let l=i.find(f=>f[0]===o.target);l||i.push(l=[o.target,{clientX:0,clientY:0,x:0,y:0,scrollContainerRect:{},scrollContainer:null}]),Object.assign(l[1],{clientX:o.clientX,clientY:o.clientY,x:u.scrollLeft,y:u.scrollTop,scrollContainerRect:u.getBoundingClientRect(),scrollContainer:u}),n(o,c)}).on("move",n).on("end",o=>{r();const c=i.find(h=>h[0]===o.target);c&&Object.assign(c[1],{clientX:0,clientY:0,x:0,y:0})})}}}function Z(){let i=[];return{name:"ShadowFollow",sort:g.thermosphere,install(t){t.on("start",(e,s)=>{if(!(s.status&&y(s.option.shadowFollowOptions)))return;const n=s.option.shadowFollowOptions;if(i.find(l=>l[0]===e.target))return;const o={createDom:u,append:ct,setDomAttrs:ht,...n},c=o.createDom(o,e),h={x:0,y:0};if(n.fixed){const l=e.target.getBoundingClientRect();h.x=l.x,h.y=l.y,Object.assign(c.style,{left:`${l.x-e.ml}px`,top:`${l.y-e.mt}px`})}else{const{position:l}=A(e.target);Object.assign(c.style,{left:`${e.target.offsetLeft-e.ml}px`,top:`${e.target.offsetTop-e.mt}px`}),l!=="absolute"&&Object.assign(h,{x:e.target.offsetLeft,y:e.target.offsetTop})}if(o.append(c,e),!n.fixed&&c.parentElement!==e.target.parentElement){const l=I(e.target,"offset"),f=I(c,"offset");f.x!==l.x&&(h.x=h.x+(l.x-f.x),c.style.left=`${h.x-e.ml}px`),f.y!==l.y&&(h.y=h.y+(l.y-f.y),c.style.top=`${h.y-e.mt}px`)}i.push([e.target,{dom:c,x:h.x,y:h.y}]);function u(l){const f=e.target.cloneNode(!0);return l.setDomAttrs(f,l,e),f}}).on("axisBeforeUpdate",(e,s)=>{if(!(s.status&&y(s.option.shadowFollowOptions)))return;const n=i.find(r=>r[0]===e.target);n&&(n[1].dom.style.left=`${e.x+n[1].x-e.ml}px`,n[1].dom.style.top=`${e.y+n[1].y-e.mt}px`)}).on("end",(e,s)=>{var o;const n=i.findIndex(c=>c[0]===e.target);if(n===-1)return;const[r]=i.splice(n,1);(o=r[1].dom.parentElement)==null||o.removeChild(r[1].dom)})}}}function ct(i,t){var e;(e=t.target.parentElement)==null||e.appendChild(i)}function ht(i,t,e){const s=A(e.target).boxSizing==="border-box",n=s?e.target.offsetWidth:e.target.clientWidth,r=s?e.target.offsetHeight:e.target.clientHeight;Object.assign(i.style,{opacity:"0.5",pointerEvents:"none",position:t.fixed?"fixed":"absolute",width:`${n}px`,height:`${r}px`}),L(i,t.class),t.style&&Object.assign(i.style,t.style)}const at=["left","right","x"],lt={x:["left","right"],y:["top","bottom"]},ut={x:"width",y:"height"};function N(){return{name:"Snap",sort:g.sky+20,install(i){let t=[];i.on("start",e=>{let s=t.find(r=>r[0]===e.target);s||t.push(s=[e.target,{scrollWidth:0,scrollHeight:0}]);const n=w(e.target);s[1].scrollWidth=n.scrollWidth,s[1].scrollHeight=n.scrollHeight}).on("axisBeforeUpdate",(e,s)=>{if(!(s.status&&y(s.option.snapOptions)))return;const n=s.option.snapOptions;if(!n.enable||n.forceSnap)return;const r=t.find(m=>m[0]===e.target);if(!r)return;const{orient:o,threshold:c=10}=n,h={width:r[1].scrollWidth,height:r[1].scrollHeight},u=k(e.target),l=o!=="y",f=o!=="x";l&&(e.x<c?e.x=0:h.width-e.x-u.width<c&&(e.x=h.width-u.width)),f&&(e.y<c?e.y=0:h.height-e.y-u.height<c&&(e.y=h.height-u.height))}).on("end",(e,s)=>{if(!(s.status&&y(s.option.snapOptions)))return;const n=s.option.snapOptions;if(!n.forceSnap)return;let r=n.forceSnapOrient||"x";const o=at.includes(r)?"x":"y",c=ut[o],h=w(e.target).getBoundingClientRect(),u=w(e.target)[o==="x"?"scrollWidth":"scrollHeight"],l=k(e.target)[c];if(r==="x"||r==="y"){const f=lt[r];r=e[`client${r.toUpperCase()}`]-h[r]>h[c]/2?f[1]:f[0]}e[o]=r==="left"||r==="top"?0:u-l,e.setPosition(e,e.target)})}}}function ft(i){return new B(i).use(J).use(K).use(N).use(Q).use(Z)}a.BoundaryLimit=K,a.Direction=J,a.DragCore=B,a.Scrolling=Q,a.ShadowFollow=Z,a.Snap=N,a.addElementClass=L,a.downEventName=T,a.drag=ft,a.dragCore=rt,a.getBoundingClientRect=I,a.getElementStyle=A,a.getEnableStatus=y,a.getEvent=Y,a.getMobilePlatStatus=V,a.getParent=w,a.getSize=k,a.getType=U,a.isFunction=x,a.isMobile=S,a.isObject=nt,a.isString=it,a.matchForDomTree=q,a.moveEventName=P,a.parseDOM=E,a.removeElementClass=H,a.upEventName=z,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})});