1function initNewsFeedInstance(feed, scrollContainer) { 2 3 if (!feed) return 4 5 const list = feed.querySelector('.news-feed__list') 6 if (!list) return 7 8 const app = { 9 init() { 10 11 this.page = 1 12 this.feed = feed 13 this.list = list 14 15 this.scrollContainer = scrollContainer || window 16 17 this.isLoading = false 18 this.hasMore = true 19 this.page = 1 20 this.maxPages = 5 21 this.ajaxUrl = '/ajax/news-feed-more.html' 22 this.createSentinel() 23 this.initObserver() 24 }, 25 26 createSentinel() { 27 const existing = this.list.querySelector('.news-feed__sentinel') 28 if (existing) { 29 this.sentinel = existing 30 return 31 } 32 33 const sentinel = document.createElement('div') 34 sentinel.className = 'news-feed__sentinel' 35 this.list.appendChild(sentinel) 36 this.sentinel = sentinel 37 }, 38 39 initObserver() { 40 41 const root = 42 this.scrollContainer && this.scrollContainer !== window 43 ? this.scrollContainer 44 : null 45 46 console.log('root',root) 47 48 this.observer = new IntersectionObserver( 49 (entries) => { 50 entries.forEach((entry) => { 51 if (entry.isIntersecting) { 52 this.loadMore() 53 } 54 }) 55 }, 56 { 57 root, 58 rootMargin: '200px', 59 threshold: 0, 60 } 61 ) 62 63 this.observer.observe(this.sentinel) 64 }, 65 66 67 async loadMore() { 68 if (this.isLoading || !this.hasMore) { 69 return 70 } 71 72 if (this.page > this.maxPages) { 73 this.hasMore = false 74 this.destroy() 75 return 76 } 77 78 this.isLoading = true 79 this.feed.classList.add('news-feed--loading') 80 81 try { 82 const url = `${this.ajaxUrl}?PAGEN=${this.page}` 83 84 const response = await fetch(url, { 85 headers: { 86 'X-Requested-With': 'XMLHttpRequest', 87 }, 88 cache: 'no-cache', 89 }) 90 91 if (!response.ok) { 92 throw new Error('Failed to load news feed') 93 } 94 95 const html = await response.text() 96 97 const wrapper = document.createElement('div') 98 wrapper.innerHTML = html 99 100 const ajaxList = wrapper.querySelector('.news-feed__list') 101 const source = 102 ajaxList && ajaxList.children.length 103 ? ajaxList 104 : wrapper 105 106 const items = Array.from( 107 source.querySelectorAll('.feed-card') 108 ) 109 110 items.forEach((item) => { 111 this.list.insertBefore(item, this.sentinel) 112 }) 113 114 this.page += 1 115 } catch (e) { 116 console.error(e) 117 this.hasMore = false 118 this.destroy() 119 } finally { 120 this.isLoading = false 121 this.feed.classList.remove('news-feed--loading') 122 } 123 }, 124 125 destroy() { 126 if (this.observer && this.sentinel) { 127 this.observer.unobserve(this.sentinel) 128 this.observer.disconnect() 129 } 130 131 if (this.scrollHandler && this.scrollTarget) { 132 this.scrollTarget.removeEventListener('scroll', this.scrollHandler) 133 } 134 135 if (this.sentinel && this.sentinel.parentNode) { 136 this.sentinel.parentNode.removeChild(this.sentinel) 137 } 138 }, 139 } 140 141 app.init() 142} 143 144function NewsFeedScript() { 145 const feeds = document.querySelectorAll('.js-news-feed') 146 if (!feeds.length) return 147 148 feeds.forEach((feed) => 149 initNewsFeedInstance(feed) 150 ) 151} 152 153if (typeof window !== 'undefined') { 154 if (!window.slam) { 155 window.slam = {} 156 } 157 158 window.slam.NewsFeedScriptInit = function (feed) { 159 const container = document.querySelector( 160 '.js-news-feed-target .news-feed__list' 161 ) 162 163 initNewsFeedInstance(feed, container) 164 } 165 window.addEventListener('ReactContentLoaded', NewsFeedScript) 166 document.addEventListener('DOMContentLoaded', NewsFeedScript) 167} 168
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.