| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  | <div class="virtual-list-item {{shown ? 'shown' : ''}}" | 
					
						
							|  |  |  |      virtual-list-key="{{key}}" | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |      ref:node | 
					
						
							| 
									
										
										
										
											2018-01-15 16:12:07 -08:00
										 |  |  |      style="transform: translate3d(0, {{offset}}px, 0);" | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  | > | 
					
						
							|  |  |  |   <:Component {component} virtualProps="{{props}}" /> | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  | </div> | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  |   .virtual-list-item { | 
					
						
							|  |  |  |     position: absolute; | 
					
						
							|  |  |  |     top: 0; | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |     opacity: 0; | 
					
						
							|  |  |  |     pointer-events: none; | 
					
						
							| 
									
										
										
										
											2018-01-17 00:06:24 -08:00
										 |  |  |     /* will-change: transform; */ /* causes jank in mobile Firefox */ | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |   } | 
					
						
							|  |  |  |   .shown { | 
					
						
							|  |  |  |     opacity: 1; | 
					
						
							|  |  |  |     pointer-events: auto; | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </style> | 
					
						
							|  |  |  | <script> | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  |   import { virtualListStore } from '../_utils/virtualListStore' | 
					
						
							| 
									
										
										
										
											2018-01-17 00:59:15 -08:00
										 |  |  |   import { mark, stop } from '../_utils/marks' | 
					
						
							| 
									
										
										
										
											2018-01-15 12:23:28 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 18:08:37 -08:00
										 |  |  |   let updateItemHeights = {} | 
					
						
							|  |  |  |   let promise = Promise.resolve() | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |   let onIntersectionCallbacks = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let intersectionObserver = new IntersectionObserver(entries => { | 
					
						
							|  |  |  |     entries.forEach(entry => { | 
					
						
							|  |  |  |       let key = entry.target.getAttribute('virtual-list-key') | 
					
						
							|  |  |  |       onIntersectionCallbacks[key](entry) | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2018-01-16 18:08:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |   export default { | 
					
						
							|  |  |  |     oncreate() { | 
					
						
							| 
									
										
										
										
											2018-01-15 16:35:08 -08:00
										 |  |  |       let key = this.get('key') | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |       onIntersectionCallbacks[key] = entry => { | 
					
						
							| 
									
										
										
										
											2018-01-16 23:16:15 -08:00
										 |  |  |         let rect = entry.boundingClientRect | 
					
						
							|  |  |  |         updateItemHeights[key] = rect.height | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |         promise.then(() => { | 
					
						
							|  |  |  |           // update all item heights in one microtask batch for better perf | 
					
						
							|  |  |  |           let updatedKeys = Object.keys(updateItemHeights) | 
					
						
							|  |  |  |           if (!updatedKeys.length) { | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2018-01-17 00:59:15 -08:00
										 |  |  |           mark('batch update VirtualListItem') | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |           // batch all updates to itemHeights for better perf | 
					
						
							|  |  |  |           let itemHeights = this.store.get('itemHeights') | 
					
						
							|  |  |  |           for (key of updatedKeys) { | 
					
						
							|  |  |  |             itemHeights[key] = updateItemHeights[key] | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           this.store.set({ | 
					
						
							|  |  |  |             itemHeights: itemHeights | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |           updateItemHeights = {} | 
					
						
							| 
									
										
										
										
											2018-01-17 00:59:15 -08:00
										 |  |  |           stop('batch update VirtualListItem') | 
					
						
							| 
									
										
										
										
											2018-01-16 18:08:37 -08:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |       intersectionObserver.observe(this.refs.node) | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     ondestroy() { | 
					
						
							|  |  |  |       intersectionObserver.unobserve(this.refs.node) | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2018-01-16 20:34:09 -08:00
										 |  |  |     store: () => virtualListStore, | 
					
						
							|  |  |  |     computed: { | 
					
						
							|  |  |  |       'shown': ($itemHeights, key) => $itemHeights[key] > 0 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-15 10:54:02 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | </script> |