suspend-vue
Version:
一个悬浮窗组件,支持组件形式 / 自定义指令
8 lines (7 loc) • 6.96 kB
JavaScript
(function(p,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],s):(p=typeof globalThis<"u"?globalThis:p||self,s(p.SuspendVue={},p.Vue))})(this,function(p,s){"use strict";const x=(r,i)=>{const o=getComputedStyle(r)[i],f=typeof o=="string"?o.match(/^(\d+\.?\d*)(px)?$/i):[];return f&&f[1]?+f[1]:o};function O(r){let i;if(typeof r=="number"||V(r))return+r;const o=r.match(/^(\-?[0-9]+)(.+)/);if(!o)return 0;const[f,a,h]=o;switch(h){case"px":i=+a;break;case"rem":{const c=x(document.querySelector("html"),"fontSize");i=+a*c}break;case"vw":{const c=x(document.querySelector("html"),"width");i=+a*.01*c}break;case"vh":{const c=x(document.querySelector("html"),"height");i=+a*.01*c}break;default:i=+a;break}return i}function V(r){return/^\-?[0-9]*$/.test(r)}function X(r){return 1/+r>0}const U=(()=>/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))();function W(r,i){const o=Object.assign({},i,r);for(const f in o)f in i&&typeof o[f]>"u"&&(o[f]=i[f]);return o}const E="suspend-box",Y={stopDrag:"suspend-stop-drag-wrapper"};function C(r,i,o){const a=s.isRef(r)?r:s.ref(r);let h;i=W(i,{model:"default",delay:300,contentMove:!0,zIndex:999});const c=s.ref(!1),_=s.computed(()=>i.delay+"ms"),y=s.ref(),S=1,v=s.ref(!0),$=s.computed(()=>Object.assign({x:!0,y:!0},i.move)),b=s.computed(()=>Object.assign({x:!1,y:!1},i.adsorption)),n=s.reactive({left:0,top:0,flagX:0,flagY:0,width:0,height:0,mLeft:0,mTop:0}),l=s.reactive({left:0,top:0,width:0,height:0}),w=s.computed(()=>({MinLeft:-n.mLeft,MaxLeft:l.width-n.width-n.mLeft,MinTop:-n.mTop,MaxTop:l.height-n.height-n.mTop})),L=s.ref(!1);function B(e=a.value){if(i.model==="window"&&e){if(e.nodeName==="HTML")return;{const t=e.parentNode;return x(t,"position")!="static"?t:B(t)}}}function R(e,t){const u={left:0,top:0},{MaxLeft:d,MaxTop:m,MinLeft:H,MinTop:j}=w.value;return u.left=e<H?H:e>d?d:e,u.top=t<j?j:t>m?m:t,n.left=$.value.x?u.left:n.left,n.top=$.value.y?u.top:n.top,u}function K(){const{defaultSite:e}=i,t={x:(e==null?void 0:e.left)??(e==null?void 0:e.x)??-0,y:(e==null?void 0:e.top)??(e==null?void 0:e.y)??"-2vh"};t.x=O(t.x),t.y=O(t.y);const{MaxLeft:u,MaxTop:d}=w.value;n.left=Math.abs(t.x)>u?u:X(t.x)?t.x:u+t.x,n.top=Math.abs(t.y)>d?d:X(t.y)?t.y:d+t.y}function z(e,t){c.value=!1,L.value=!0,n.flagX=e.offsetX,n.flagY=e.offsetY,y.value={x:n.left,y:n.top},v.value=!0,h=setTimeout(()=>{var u;(u=o==null?void 0:o.moveStart)==null||u.call(o)},200)}const I=s.withModifiers(e=>{const t={offsetX:0,offsetY:0},u=s.computed(()=>{var d,m;return{left:((d=a.value)==null?void 0:d.getBoundingClientRect().left)||0,top:((m=a.value)==null?void 0:m.getBoundingClientRect().top)||0}});if("changedTouches"in e&&a.value&&e.changedTouches)t.offsetX=e.changedTouches[0].clientX-u.value.left,t.offsetY=e.changedTouches[0].clientY-u.value.top,z(t);else{const d=e;t.offsetX=d.clientX-u.value.left,t.offsetY=d.clientY-u.value.top,z(t)}},[i.contentMove?"":"self"]);function Q(e){if(e.changedTouches)return N(e.changedTouches[0])}function N(e){if(!L.value)return;const{clientX:t,clientY:u}=e,d=t-n.flagX-l.left-n.mLeft,m=u-n.flagY-l.top-n.mTop;R(d,m),y.value&&(Math.abs(n.left-y.value.x)>S||Math.abs(n.top-y.value.y)>S)&&(v.value=!1)}async function D(e){var t,u;if(L.value){if(L.value=!1,i.delay&&(c.value=!0),v.value?(clearTimeout(h),(t=o==null?void 0:o.click)==null||t.call(o,e)):((u=o==null?void 0:o.moveEnd)==null||u.call(o),y.value=void 0),b.value.x){const d=n.left+n.width/2>l.width/2-n.mLeft?w.value.MaxLeft:w.value.MinLeft;n.left=d}if(b.value.y){const d=n.top+n.height/2>l.height/2-n.mTop?w.value.MaxTop:w.value.MinTop;n.top=d}}}function T(){const e=B();e?(l.left=e.getBoundingClientRect().left,l.top=e.getBoundingClientRect().top,l.width=e.getBoundingClientRect().width,l.height=e.getBoundingClientRect().height):(l.width=document.documentElement.clientWidth||window.innerWidth,l.height=document.documentElement.clientHeight||window.innerHeight)}function P(){a.value&&(n.width=a.value.clientWidth,n.height=a.value.clientHeight,n.mLeft=x(a.value,"marginLeft"),n.mTop=x(a.value,"marginTop"))}async function A(){await s.nextTick();const e=B();e&&(new MutationObserver(T).observe(e,{attributeFilter:["style"]}),e.addEventListener("transitionend",T,!1)),T(),P(),K()}const Z=()=>{const e=`${E}-style`,t=`
.${Y.stopDrag} * {
user-select: none;
-webkit-user-drag: none;
}
`;document.querySelector(`style[data-${e}=${e}]`)||s.nextTick(()=>{var m;const d=document.createElement("style");d.setAttribute(`data-${e}`,e),d.innerHTML=t,(m=document.querySelector("head"))==null||m.appendChild(d)})};function ee(e){const t={left:"0",top:"0",userSelect:"none",touchAction:"none",zIndex:i.zIndex+"",position:i.model==="default"?"fixed":"absolute",boxSizing:"border-box"};i.contentMove&&e.classList.add(Y.stopDrag);for(const u in t)e.style[u]=t[u]||"";e.setAttribute(`data-${E}`,E),e.onmousedown=I,e.ontouchstart=I,e.addEventListener("click",u=>!v.value&&u.stopPropagation(),!0),Z()}const q=s.effectScope();q.run(()=>{s.watchEffect(()=>a.value&&(ee(a.value),A())),s.watchEffect(()=>{a.value&&(c.value?a.value.style.transition=`transform ${_.value} ease-out`:a.value.style.transition="none")}),s.watchEffect(()=>a.value&&(a.value.style.transform=`translate3d(${n.left}px, ${n.top}px, 0)`))});function F(e="add"){e==="add"?g.forEach(t=>window.addEventListener(t.type,t.value,!0)):g.forEach(t=>window.removeEventListener(t.type,t.value))}const g=new Set([{type:"resize",value:A}]);return U?(g.add({type:"touchmove",value:Q}),g.add({type:"touchend",value:D})):(g.add({type:"mousemove",value:N}),g.add({type:"mouseup",value:D}),g.add({type:"contextmenu",value:D})),i.model==="window"&&g.add({type:"scroll",value:T}),F("add"),{unmount:()=>{const e=B();e&&e.removeEventListener("transitionend",T),q.stop(),F("remove")},reset:()=>{P(),R(n.left,n.top)}}}const k=s.createElementVNode("div",null,"test",-1),M=s.defineComponent({name:"Suspend",__name:"Suspend",props:{model:{},move:{},adsorption:{},defaultSite:{},delay:{},contentMove:{type:Boolean,default:!0},zIndex:{}},emits:["click","moveStart","moveEnd"],setup(r,{expose:i,emit:o}){const f=r,a=s.ref();function h(v){o("click",v)}function c(){o("moveStart")}function _(){o("moveEnd")}const{unmount:y,reset:S}=C(a,f,{click:h,moveStart:c,moveEnd:_});return s.onBeforeUnmount(y),i({reset:S}),(v,$)=>(s.openBlock(),s.createElementBlock("div",{id:"suspend-box",class:"suspend-box",ref_key:"suspendBox",ref:a},[s.renderSlot(v.$slots,"default",{},()=>[k])],512))}});function G(r){r.directive("suspend",{mounted(i,o,f){var c;const a=o.value,{unmount:h}=C(i,a,{click:(c=o.value)==null?void 0:c.click});i.unmount=h},beforeUnmount(i,o){i.unmount()}})}M.install=r=>{r.component(M.name,M),G(r)};const J=M;p.Suspend=M,p.default=J,p.useSuspend=C,Object.defineProperties(p,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
//# sourceMappingURL=suspend-vue.umd.js.map