vue-virtual-scroller
Version:
Smooth scrolling for any amount of data
2 lines (1 loc) • 8.48 kB
JavaScript
var VueVirtualScroller=function(e){"use strict";function t(){var e=window.navigator.userAgent,t=e.indexOf("MSIE ");if(t>0)return parseInt(e.substring(t+5,e.indexOf(".",t)),10);if(e.indexOf("Trident/")>0){var i=e.indexOf("rv:");return parseInt(e.substring(i+3,e.indexOf(".",i)),10)}var n=e.indexOf("Edge/");return n>0?parseInt(e.substring(n+5,e.indexOf(".",n)),10):-1}function i(){i.init||(i.init=!0,l=-1!==t())}function n(e){if(null!==e&&"function"!=typeof e)throw new Error("observe-visibility directive expects a function as the value")}function s(e,t){e.component(t+"virtual-scroller",u)}var l=void 0,o={render:function(){var e=this,t=e.$createElement;return(e._self._c||t)("div",{staticClass:"resize-observer",attrs:{tabindex:"-1"}})},staticRenderFns:[],_scopeId:"data-v-b329ee4c",name:"resize-observer",methods:{notify:function(){this.$emit("notify")},addResizeHandlers:function(){this._resizeObject.contentDocument.defaultView.addEventListener("resize",this.notify),this._w===this.$el.offsetWidth&&this._h===this.$el.offsetHeight||this.notify()},removeResizeHandlers:function(){this._resizeObject&&this._resizeObject.onload&&(!l&&this._resizeObject.contentDocument&&this._resizeObject.contentDocument.defaultView.removeEventListener("resize",this.notify),delete this._resizeObject.onload)}},mounted:function(){var e=this;i(),this.$nextTick(function(){e._w=e.$el.offsetWidth,e._h=e.$el.offsetHeight});var t=document.createElement("object");this._resizeObject=t,t.setAttribute("style","display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;"),t.onload=this.addResizeHandlers,t.type="text/html",l&&this.$el.appendChild(t),t.data="about:blank",l||this.$el.appendChild(t)},beforeDestroy:function(){this.removeResizeHandlers()}},r={version:"0.4.2",install:function(e){e.component("resize-observer",o)}},a=null;"undefined"!=typeof window?a=window.Vue:"undefined"!=typeof global&&(a=global.Vue),a&&a.use(r);var d={bind:function(e,t,i){var s=t.value;if("undefined"==typeof IntersectionObserver)console.warn("[vue-observe-visibility] IntersectionObserver API is not available in your browser. Please install this polyfill: https://github.com/WICG/IntersectionObserver/tree/gh-pages/polyfill");else{n(s),e._vue_visibilityCallback=s;var l=e._vue_intersectionObserver=new IntersectionObserver(function(t){var i=t[0];e._vue_visibilityCallback&&e._vue_visibilityCallback.call(null,i.intersectionRatio>0,i)});i.context.$nextTick(function(){l.observe(e)})}},update:function(e,t){var i=t.value;n(i),e._vue_visibilityCallback=i},unbind:function(e){e._vue_intersectionObserver&&(e._vue_intersectionObserver.disconnect(),delete e._vue_intersectionObserver,delete e._vue_visibilityCallback)}},h={version:"0.3.1",install:function(e){e.directive("observe-visibility",d)}},c=null;"undefined"!=typeof window?c=window.Vue:"undefined"!=typeof global&&(c=global.Vue),c&&c.use(h);var u={render:function(){var e=this,t=e.$createElement,i=e._self._c||t;return i(e.mainTag,{directives:[{name:"observe-visibility",rawName:"v-observe-visibility",value:e.handleVisibilityChange,expression:"handleVisibilityChange"}],tag:"component",staticClass:"virtual-scroller",class:e.cssClass,on:{scroll:e.handleScroll}},[e._t("before-container",[i(e.containerTag,{ref:"itemContainer",tag:"component",staticClass:"item-container",class:e.containerClass,style:e.itemContainerStyle},[e._t("before-content",[i(e.contentTag,{ref:"items",tag:"component",staticClass:"items",class:e.contentClass,style:e.itemsStyle},[e.renderers?e._l(e.visibleItems,function(t,n){return i(e.renderers[t[e.typeField]],{key:e.keysEnabled&&t[e.keyField]||"",tag:"component",staticClass:"item",attrs:{item:t,"item-index":e._startIndex+n}})}):[e._l(e.visibleItems,function(t,i){return e._t("default",null,{item:t,itemIndex:e._startIndex+i,itemKey:e.keysEnabled&&t[e.keyField]||""})})]],2),e._v(" "),e._t("after-content")])],2),e._v(" "),e._t("after-container",[i("resize-observer",{on:{notify:e.handleResize}})])])],2)},staticRenderFns:[],_scopeId:"data-v-727d6836",name:"virtual-scroller",components:{ResizeObserver:o},directives:{ObserveVisibility:d},props:{items:{type:Array,required:!0},renderers:{default:null},itemHeight:{type:[Number,String],default:null},typeField:{type:String,default:"type"},keyField:{type:String,default:"id"},heightField:{type:String,default:"height"},mainTag:{type:String,default:"div"},containerTag:{type:String,default:"div"},containerClass:{default:null},contentTag:{type:String,default:"div"},contentClass:{default:null},pageMode:{type:Boolean,default:!1},buffer:{type:[Number,String],default:200},poolSize:{type:[Number,String],default:2e3},prerender:{type:[Number,String],default:0},emitUpdate:{type:Boolean,default:!1}},data:function(){return{visibleItems:[],itemContainerStyle:null,itemsStyle:null,keysEnabled:!0}},computed:{cssClass:function(){return{"page-mode":this.pageMode}},heights:function(){if(null===this.itemHeight){for(var e={},t=this.items,i=this.heightField,n=0,s=0;s<t.length;s++)n+=t[s][i],e[s]=n;return e}}},watch:{items:{handler:function(){this.updateVisibleItems(!0)},deep:!0},pageMode:function(){this.applyPageMode(),this.updateVisibleItems(!0)},itemHeight:"setDirty"},methods:{getScroll:function(){var e=this.$el,t=void 0;if(this.pageMode){var i=e.getBoundingClientRect(),n=-i.top,s=window.innerHeight;n<0&&(s+=n,n=0),n+s>i.height&&(s=i.height-n),t={top:n,bottom:n+s}}else t={top:e.scrollTop,bottom:e.scrollTop+e.clientHeight};return t.bottom>=0&&t.top<=t.bottom?t:null},updateVisibleItems:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.items.length,n=this.getScroll(),s=this.items,l=this.itemHeight,o=void 0,r=void 0;if(n){var a=-1,d=-1,h=parseInt(this.buffer),c=parseInt(this.poolSize),u=~~(n.top/c)*c-h,f=Math.ceil(n.bottom/c)*c+h;if(!t&&(u===this._oldScrollTop&&f===this._oldScrollBottom||this._skip))return void(this._skip=!1);if(this._oldScrollTop=u,this._oldScrollBottom=f,null===l){var v=this.heights,p=0,b=i-1,m=~~(i/2),g=void 0;do{g=m,v[m]<u?p=m:m<i&&v[m+1]>u&&(b=m),m=~~((p+b)/2)}while(m!==g);for(m<0&&(m=0),a=m,r=m>0?v[m-1]:0,o=v[i-1],d=m;d<i&&v[d]<f;d++);-1===d?d=s.length-1:++d>i&&(d=i)}else a=~~(u/l),d=Math.ceil(f/l),a<0&&(a=0),d>i&&(d=i),r=a*l,o=i*l;this._startIndex===a&&this._endIndex===d&&this._offsetTop===r&&this._height===o&&this._length===i||(this.keysEnabled=!(a>this._endIndex||d<this._startIndex),this.visibleItems=s.slice(this._startIndex,d),this.itemContainerStyle={height:o+"px"},this.itemsStyle={marginTop:r+"px"},this.$nextTick(function(){e.visibleItems=s.slice(a,d)}),this.emitUpdate&&this.$emit("update",a,d),this._startIndex=a,this._endIndex=d,this._length=i,this._offsetTop=r,this._height=o)}},scrollToItem:function(e){var t=void 0;t=null===this.itemHeight?e>0?this.heights[e-1]:0:e*this.itemHeight,this.$el.scrollTop=t},setDirty:function(){this._oldScrollTop=null,this._oldScrollBottom=null},applyPageMode:function(){this.pageMode?this.addWindowScroll():this.removeWindowScroll()},addWindowScroll:function(){window.addEventListener("scroll",this.handleScroll,!0),window.addEventListener("resize",this.handleResize)},removeWindowScroll:function(){window.removeEventListener("scroll",this.handleScroll,!0),window.removeEventListener("resize",this.handleResize)},handleScroll:function(){this.updateVisibleItems()},handleResize:function(){this.$emit("resize"),this._ready&&this.updateVisibleItems()},handleVisibilityChange:function(e,t){var i=this;this._ready&&(e||0!==t.boundingClientRect.width||0!==t.boundingClientRect.height)&&this.$nextTick(function(){i.updateVisibleItems()})}},created:function(){this._ready=!1,this._startIndex=0,this._oldScrollTop=null,this._oldScrollBottom=null,this._offsetTop=0,this._height=0;var e=parseInt(this.prerender);e>0?(this.visibleItems=this.items.slice(0,e),this._length=this.visibleItems.length,this._endIndex=this._length-1,this._skip=!0):(this._endIndex=0,this._length=0,this._skip=!1)},mounted:function(){var e=this;this.applyPageMode(),this.$nextTick(function(){e.updateVisibleItems(!0),e._ready=!0,e.$nextTick(e.updateVisibleItems)})},beforeDestroy:function(){this.removeWindowScroll()}},f={version:"0.10.2",install:function(e,t){var i=Object.assign({},{installComponents:!0,componentsPrefix:""},t);i.installComponents&&s(e,i.componentsPrefix)}},v=null;return"undefined"!=typeof window?v=window.Vue:"undefined"!=typeof global&&(v=global.Vue),v&&v.use(f),e.VirtualScroller=u,e.default=f,e}({});