UNPKG

vue-stick

Version:

基于 vue 的瀑布流组件

3 lines (2 loc) 4.33 kB
!function(t){if(t&&"undefined"!=typeof window){var i=document.createElement("style");i.setAttribute("media","screen"),i.innerHTML=t,document.head.appendChild(i)}}("@keyframes stickFadeIn {\n 0% {\n opacity: 0;\n transform: translateX(-20px);\n }\n 100% {\n opacity: 1;\n transform: translateX(0);\n }\n}\n.vue-stick-outer {\n position: relative;\n}\n.vue-stick-outer .stick-fade-in {\n transition: 0s;\n animation: stickFadeIn 0.5s ease both;\n}\n");var t={props:{list:{type:Array,default:[]},columnWidth:{type:Number,default:280},animationClass:{type:String,default:"stick-fade-in"},loadTriggerDistance:{type:Number,default:1e3},columnSpacing:{type:Number,default:10}},data:function(){return{count:0,outerWidth:-1,outerHeight:200,columnWidthInUse:0,columnCount:0,localList:[],lastRowBottomPosition:[],lastTriggerScrollTime:0,widgetIDMax:0,resizeTimer:null}},render:function(t){var i=this;return t("div",{class:["vue-stick-outer"],ref:"stickOuter",style:{height:this.outerHeight+"px"}},this.localList.map(function(e){return t("div",{class:["vue-stick-item"],ref:"widget-"+e.id,key:e.id,style:{position:e.style.position,visibility:e.style.visibility,width:Math.round(i.columnWidthInUse)+"px",top:Math.round(e.style.top)+"px",left:Math.round(e.style.left)+"px"}},[i.$scopedSlots.default({data:e.data})])}))},mounted:function(){this.lastRowBottomPosition=[],document.addEventListener("scroll",this.scrollListener),window.addEventListener("resize",this.resizeListener),this.buildLayout(),this.syncList()},methods:{buildLayout:function(){var t=this.$refs.stickOuter.clientWidth;return t!==this.outerWidth&&(this.outerWidth=t,this.lastRowBottomPosition=[],this.columnCount=Math.max(Math.floor((t+this.columnSpacing)/(this.columnWidth+this.columnSpacing)),1),1===this.columnCount?this.columnWidthInUse=t:this.columnWidthInUse=(t+this.columnSpacing)/this.columnCount-this.columnSpacing,!0)},refresh:function(t){var i=this;(this.buildLayout()||t)&&(this.localList.forEach(function(t){t.style.visibility="hidden"}),this.$nextTick(function(){i.lastRowBottomPosition=[],i.localList.forEach(function(t){var e=i.$refs["widget-"+t.id];t.prepared&&i.fixItemPosition(e,t)})}))},scrollListener:function(){var t=(new Date).getTime();t-this.lastTriggerScrollTime>500&&Math.max(document.documentElement.scrollTop,document.body.scrollTop)+window.innerHeight+this.loadTriggerDistance>=document.body.scrollHeight&&(this.$emit("onScrollEnd"),this.lastTriggerScrollTime=t)},resizeListener:function(){var t=this;clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(function(){t.refresh()},500)},syncList:function(){var t=this,i=this.list,e=this.localList.map(function(t){return t.data});i.forEach(function(i){-1===e.indexOf(i)&&t.addItem(i)});for(var n=!1,o=e.length-1;o>=0;o--)-1===i.indexOf(e[o])&&(n=!0,this.localList.splice(o,1));n&&t.refresh(!0)},addItem:function(t){var i=this,e={id:this.widgetIDMax++,style:{position:"relative",top:0,left:0,width:this.columnWidthInUse,visibility:"hidden"},prepared:!1,data:t};this.localList.push(e),this.$nextTick(function(){var t=i.$refs["widget-"+e.id],n=t.querySelector("img");!function(t,i){if(t){var e=new Image;e.onerror=e.onload=o;var n=setInterval(function(){e.width>1&&o()},2);e.src=t}else setTimeout(i,0);function o(){clearInterval(n),i&&i(),i=null}}(n?n.getAttribute("src"):"",function(){e.prepared=!0,t.classList.add(i.animationClass),setTimeout(function(){t.classList.remove(i.animationClass)},1e3),i.fixItemPosition(t,e)})})},fixItemPosition:function(t,i){var e,n=0;if(t&&i){var o=t.clientHeight;this.lastRowBottomPosition.length<this.columnCount?(e=this.lastRowBottomPosition.length,this.lastRowBottomPosition.push(o)):(n=Math.min.apply(null,this.lastRowBottomPosition),e=this.lastRowBottomPosition.indexOf(n),n+=this.columnSpacing),i.style.position="absolute",i.style.visibility="visible",i.style.top=n,i.style.left=e*(this.columnWidthInUse+this.columnSpacing),this.lastRowBottomPosition[e]=n+o,this.outerHeight=Math.max.apply(null,this.lastRowBottomPosition)+this.columnSpacing}}},watch:{list:function(){this.syncList()}},beforeDestroy:function(){document.removeEventListener("scroll",this.scrollListener),window.removeEventListener("resize",this.resizeListener)}};export default{component:t,install:function(i){i.component("Stick",t)}}; //# sourceMappingURL=vue-stick.es.js.map