1class ScriptContentList extends Script { 2 constructor(params) { 3 super(params) 4 // 产åå表ç»ä»¶dom 5 this.$unit = document.getElementById(`${this.attrId}`) 6 if (!this.$unit) return 7 this.$unitList = this.$unit.querySelector('.unit-content-list') 8 // tabé项å¡dom 9 this.$tabList = this.$unit.querySelectorAll('.nav-item') 10 this.$tabTypeItem = this.$unit.querySelectorAll('[tab-type]') 11 // æ æ°æ®æ¶æ¾ç¤ºNodata 12 this.$noData = this.$unit.querySelector(".page_no_data") 13 // 产åé项å¡å 容dom 14 this.pageInfo = JSON.parse(this.utilts.htmlDecode(params.pageInfo)) 15 this.colInfo = JSON.parse(this.utilts.htmlDecode(params.colInfo)) 16 this.config = JSON.parse(this.utilts.htmlDecode(params.config)) 17 this.relate_list = JSON.parse(this.utilts.htmlDecode(params.relate_list)) 18 this.config.hover_img = (params.hoverImg === 'true') 19 this.content_type = params.content_type 20 this.content_type_list = params.content_type.split(',') 21 this.modal = null 22 this.info = window.app.info 23 this.open_hover = params.open_hover // hoverå¨ç» fadeInUp,fadeOutUp, 24 this.$carouselEl = this.$unitList 25 // console.log('this.config', this.config); 26 // è§é¢ææ¾æ¹å¼ 27 if (this.config.video) { 28 let methodMap = { 29 default: this.config.video.method, 30 md: this.config.video.method_md, 31 xl: this.config.video.method_xl 32 } 33 this.method = methodMap[this.utilts.getScreen()] 34 } 35 36 if (this.config.swiper.is_swiper) { 37 this.initSwiperEvents() 38 } 39 this.sizeMap = { 40 default: this.config.page_size_default, 41 md: this.config.page_size_md, 42 xl: this.config.page_size_xl 43 } 44 this.bg_hover_linear = params.bg_hover_linear 45 this.page_size = Number(this.sizeMap[this.utilts.getScreen()]) || 6 46 this.all_total = JSON.parse(this.utilts.htmlDecode(params.all_total)) 47 this.all_page_category_id = JSON.parse(this.utilts.htmlDecode(params.all_page_category_id)) 48 this.tab_list = JSON.parse(this.utilts.htmlDecode(params.tab_list)) 49 this.allPage = {} 50 this.tab_list.forEach((val, index) => { 51 this.allPage[val] = { 52 page_number: 1, 53 page_total: 0, 54 page_count: 1, 55 page_category_id: '', 56 limit_page_number: 1 57 } 58 if (this.all_total[val]) { 59 this.allPage[val].page_total = this.all_total[val] 60 this.allPage[val].page_count = Math.ceil(this.all_total[val] / this.page_size) 61 this.allPage[val].limit_page_number = Math.ceil(100 / this.page_size) 62 } 63 if (this.all_page_category_id[index]) this.allPage[val].page_category_id = this.all_page_category_id[index] 64 }) 65 // console.log('this.allPage---', this.allPage); 66 } 67 68 render() { 69 if (this.$unit._zoom && this.$unit._zoom.render) { 70 this.$unit._zoom.render() 71 } 72 } 73 74 async init() { 75 if (!this.$unit) return 76 if (!this.viewsData) { 77 if (window.app.info.site.viewsData) { 78 this.viewsData = window.app.info.site.viewsData 79 } else { 80 try { 81 this.viewsData = window.app.info.site.viewsData = await loadJSModule('/dist/template/views-data.js') 82 } catch (error) { 83 console.error('模åå 载失败:', error); 84 } 85 } 86 } 87 if (!window.ejs) { 88 await new Load('/assets/plugins/ejs.min.js') 89 } 90 const that = this 91 this.content_type_list.forEach(item => { 92 if (item !== 'page_content') { 93 this.initLoadData(item) 94 } 95 }) 96 if (this.config.load_type === 2) { 97 // æ»å¨å è½½ 98 this.initObserver() 99 } else if (this.config.load_type === 1) { 100 // ç¹å»å è½½ 101 this.initLoadEvent() 102 } 103 if (!this.utilts.checkDesign()) this.initFilter() 104 this.initMoreData() 105 this.initHoverContent() 106 this.initInquiry() 107 // this.initVideoData() 108 this.initVideo() 109 this.initLink() 110 this.initResize() 111 this.initQuoteList() 112 const initContent = () => { 113 // çå¾ contentRender宿åè¿è¡åå§å 114 setTimeout(function () { 115 that.initHoverImg() 116 }, 300) 117 } 118 if (this.utilts.checkDesign() || (window.app && window.app.hookEvents && window.app.hookEvents['hookInitContentRender'])) { 119 initContent(); 120 // window.addEventListener('hookInitContentRender', initContent, { 121 // once: false 122 // }) 123 } else { 124 window.addEventListener('hookInitContentRender', initContent, { 125 once: true 126 }) 127 } 128 129 // åå§é项å¡åæ¢äºä»¶ 130 this.initTabEvent() 131 // æ¾å¤§å¾ç 132 if (this.config.target === 'zoom') { 133 await new Load('/assets/plugins/zoom.js') 134 this.$unit._zoom = new ZoomBuilder({ 135 attrId: this.attrId, 136 dom: this.$unit, 137 selector: '.unit-list__image[zoom-img="true"]', 138 titleSelector: ".unit-list__title", 139 boxClass: 'list-zoom-box' 140 }) 141 }
142 this.initPrevClick() 143 } 144 // æ ç¾è¯¦æ 页çéæåº 145 initFilter() { 146 const filterText = this.$unit.querySelector('.unit-content-list__filter-text') 147 if (!filterText) return 148 filterText.addEventListener('click', () => { 149 if (filterText.classList.contains('active')) { 150 filterText.classList.remove('active') 151 } else { 152 filterText.classList.add('active') 153 } 154 }) 155 document.querySelector('body').addEventListener('click', (e) => { 156 if (!e.target.classList.contains('unit-content-list__filter-text') && !e.target.parentNode?.classList.contains('unit-content-list__filter-text')){ 157 if (filterText.classList.contains('active')) filterText.classList.remove('active') 158 } 159 }) 160 window.addEventListener('scroll', () => { 161 if (filterText.classList.contains('active')) filterText.classList.remove('active') 162 }) 163 const filterListType = this.$unit.querySelectorAll('.unit-content-list__filter-type span') 164 if (filterListType && filterListType.length) { 165 filterListType.forEach((val, index) => { 166 val.addEventListener('click', async () => { 167 if (!val.classList.contains('active')) { 168 filterListType.forEach(val => val.classList.remove('active')) 169 val.classList.add('active') 170 if (index === 1) this.$unit.querySelector('.unit-list__items').classList.add('unit-list__items-single-row') 171 else this.$unit.querySelector('.unit-list__items').classList.remove('unit-list__items-single-row') 172 } 173 }) 174 }) 175 } 176 const dropdownItems = this.$unit.querySelectorAll('.unit-content-list__filter-dropdown-item') 177 const listItems = this.$unit.querySelector('.unit-list__items') 178 const currentReadMore = this.$unit.querySelector(`.unit-content-list_more .more-btn`) 179 if (dropdownItems && dropdownItems.length) { 180 dropdownItems.forEach(val => { 181 val.addEventListener('click', async () => { 182 if (!val.classList.contains('active')) { 183 dropdownItems.forEach(val => val.classList.remove('active')) 184 val.classList.add('active') 185 filterText.querySelector('.unit-content-list__filter-default').innerText = this.utilts.$t(val.innerText) 186 this.allPage[this.tab_list[0]].page_number = 1 187 const sortValue = val.getAttribute('data-value') 188 const list = await this.getVideoData(this.tab_list[0], sortValue) 189 if (currentReadMore.classList.contains('put-away')) { 190 currentReadMore.querySelector('span').innerHTML = this.utilts.$t('Load More') 191 currentReadMore.classList.remove('put-away') 192 listItems.classList.remove('hidden-load-item') 193 } 194 this.rederInnerContent(list, this.$unit, 'replace') 195 } 196 }) 197 }) 198 } 199 } 200 initLoadEvent() { 201 // å页 202 // if (this.tab_list.length > 1 && this.content_type === 'video_column') { 203 // this.tab_list.forEach(val => { 204 // this.renderPagination(val, this.$unit.querySelector(`[tab-type=${val}]`)) 205 // // this.$unit.querySelector(`[tab-type=${val}] .unit-content-list_more`) 206 // }) 207 // } else { 208 // this.renderPagination(this.tab_list[0], this.$unit) 209 // } 210 // ç¹å»å è½½æ´å¤ 211 if (this.config.load_type === 1) { 212 if (this.tab_list.length > 1) { 213 this.tab_list.forEach(val => { 214 this.changeDom(val, this.$unit.querySelector(`[tab-type=${val}]`)) 215 }) 216 } else { 217 this.changeDom(this.tab_list[0], this.$unit) 218 } 219 } 220 } 221 changeDom(val, dom) { 222 const listItems = dom.querySelector('.unit-list__items') 223 if (listItems) { 224 const maxSize = Math.max(this.sizeMap.xl, this.sizeMap.md, this.sizeMap.default) 225 const hideCount = maxSize - this.page_size 226 const childrenArray = Array.from(listItems.children) 227 if (hideCount > 0 && childrenArray.length > hideCount) { 228 listItems.classList.remove('temp-items') 229 childrenArray.slice(-hideCount).forEach(child => child.remove()); 230 } 231 } 232 const currentReadMore = dom.querySelector(`.unit-content-list_more .more-btn`) 233 const allContentList = dom.querySelector(`.unit-content-list_all`) 234 if (!currentReadMore) return 235 const currentPage = this.allPage[val] 236 // console.log('currentPage', currentPage, this.attrId) 237 if (currentPage.page_count > 1) { 238 currentReadMore.parentNode.classList.remove('d-none') 239 } 240 currentReadMore.addEventListener('click', async () => { 241 if (this.config.limit_count && currentPage.page_total > this.config.limit_count && currentPage.page_number === Math.ceil(this.config.limit_count / this.page_size)) return 242 if (currentReadMore.classList.contains('put-away')) { 243 currentReadMore.querySelector('span').innerHTML = this.utilts.$t('Load More') 244 currentReadMore.classList.remove('put-away') 245 listItems.classList.add('hidden-load-item') 246 return false 247 } 248 if (currentPage.page_number === currentPage.page_count) { 249 currentReadMore.querySelector('span').innerHTML = this.utilts.$t('Put Away') 250 currentReadMore.classList.add('put-away') 251 listItems.classList.remove('hidden-load-item') 252 return false 253 } 254 currentPage.page_number++ 255 const list = await this.getVideoData(val) 256 this.rederInnerContent(list, dom) 257 if (this.config.limit_count) { 258 const resCount = currentPage.page_total > this.config.limit_count ? this.config.limit_count : currentPage.page_total
259 const limitPage = Math.ceil(resCount / this.page_size) 260 if (currentPage.page_number === limitPage) { 261 if (currentPage.page_total > this.config.limit_count) allContentList.classList.remove('d-none') 262 currentReadMore.parentNode.classList.add('d-none') 263 } 264 } 265 if (currentPage.page_number === currentPage.page_count && !this.config.limit_count && !this.config.swiper.is_swiper) { 266 currentReadMore.querySelector('span').innerHTML = this.utilts.$t('Put Away') 267 currentReadMore.classList.add('put-away') 268 } 269 if (currentPage.page_number === currentPage.page_count && this.config.swiper.is_swiper) { 270 currentReadMore.parentNode.classList.add('d-none') 271 } 272 }) 273 } 274 rederInnerContent(data, dom, method='append') { 275 const listItems = dom.querySelector('.unit-list__items') 276 const currentLength = dom.querySelector('.unit-list__items').children.length 277 const newHtml = data.map((item, index) => { 278 if (item.video_id) { 279 item = new ContentItemVideo(item) 280 } else if (item.article_id) { 281 item = new ContentItemArticle(item) 282 } else { 283 item = new ContentItemDefault(item) 284 } 285 return ` 286 <div 287 animate 288 class="${this.bg_hover_linear} animate unit-list__item swiper-slide ${!item.img ? 'no-image' : ''} col-${this.colInfo.cols_col} col-md-${this.colInfo.cols_md} col-xl-${this.colInfo.cols_xl} ${method !== 'replace' ? 'load-item' : ''}" 289 data-media="${item.title}" 290 composing-xl="${this.config.composing_xl}" 291 ${item.title === 'Wechat' ? `data-wechatCode=${item.href}` : ''} 292 > 293 <div class="unit-list__a" 294 data-href="${this.config.target==='block'?'javascript:;':globalThis.Server.getRinseHref(item.href, window.app.info.site)}" 295 data-target="${this.config.target==='block'?'_self':this.config.target || item.target || '_self'}" 296 > 297 <div 298 class="unit-list__item-inner d-flex ${this.config.composing_xl ? '' : 'flex-column'}" 299 > 300 ${this.renderInner(item, currentLength + index)} 301 </div> 302 </div> 303 </div> 304 ` 305 }).join('') 306 // å页 307 if (method === 'replace') { 308 listItems.innerHTML = newHtml 309 } else { 310 // æ»å¨å è½½æ´å¤ 311 listItems.innerHTML += newHtml 312 } 313 // å¾çå è½½ 314 this.$unit.querySelectorAll('[lazy-src]').forEach(item => { 315 if (!item.getAttribute('src')) { 316 new LazyImg(item, { img_using_avif: window.app.siteConfig?.img_using_avif }).loadImg() 317 } 318 }) 319 if (this.content_type === 'article_list') { 320 // è§é¢åå§å 321 this.initVideo() 322 } 323 // link 324 this.initLink() 325 // è½®ææ´æ° 326 if (this.config.swiper.is_swiper) { 327 // this.$unit.querySelectorAll('.swiper-container').forEach(item => { 328 // item.swiper?.destroy() 329 // }) 330 this.$unit.querySelectorAll('[carousel]').forEach(item => this.utilts.interObserver(item, () => new Carousel(item, this.config.swiper), false)) 331 this.initSwiperEvents() 332 } 333 } 334 renderInner(item, index) {
335 let contentItem = item 336 let selfPackage = this.utilts.checkDesign() ? design.packages[this.attrId] : window.app.info.windowCtxState.packages[this.attrId] 337 if (item.cover_url && (item.content_type === 'video' || (item.content_type === 'material' && /\.mp4/i.test(item.cover_url) || item.is_embed_video))) { 338 // let contentItem = new ContentItemVideo(item) 339 return this.getEjsResult(`/package/components/unit-content-list-card__video`, { package: selfPackage, item: contentItem, from: 'content-list', subIndex: index }) 340 } else { 341 // let contentItem = new ContentItemDefault(item) 342 return this.getEjsResult(`/package/components/unit-content-list-card__image`, { package: selfPackage, item: contentItem, from: 'content-list', subIndex: index }) 343 } 344 } 345 /* 346 * è·åHTML 347 */ 348 getEjsResult(path, data) { 349 data = this.getEjsParmes(data) 350 const ejsOptions = { client: true, delimiter: '?' } 351 const viewString = this.viewsData[path] 352 const viewCompile = window.ejs.compile(viewString, ejsOptions) 353 const viewHtml = viewCompile(data, null, (sonPath, sonData) => { 354 let thisViewString = this.viewsData[sonPath] 355 356 if (thisViewString) { 357 if (thisViewString.indexOf('include(') >= 1) { 358 thisViewString = this.getEjsResult(sonPath, sonData) 359 } 360 sonData = this.getEjsParmes(sonData) 361 const template = window.ejs.render(thisViewString, sonData, ejsOptions) 362 return template 363 } else { 364 console.error(`${sonPath} æªæ¾å°å¯¹åºçhtmlã`) 365 } 366 }) 367 return viewHtml 368 } 369 /** 模å弿忰 */ 370 getEjsParmes(data) { 371 if (this.utilts.checkDesign()) { 372 return { 373 ...ctx.state, 374 ...data, 375 getViewsPath: path => path, 376 translate: text => text 377 } 378 } 379 const state = { 380 ...window.app.info.windowCtxState, 381 site: window.app.info.site, 382 page: window.app.info.page, 383 $t: window.app.utilts.$t 384 } 385 return { 386 ctx: {state}, 387 ...state, 388 ...data, 389 getViewsPath: path => path, 390 translate: text => text 391 } 392 } 393 initObserver() { 394 // if (!this.utilts.checkDesign()) { 395 // } 396 const listBox = this.$unit.querySelector('.unit-content-list') 397 function throttle(func, limit) { 398 let lastFunc; 399 let lastRan; 400 return function() { 401 const context = this; 402 const args = arguments; 403 if (!lastRan) { 404 func.apply(context, args); 405 lastRan = Date.now(); 406 } else { 407 clearTimeout(lastFunc); 408 lastFunc = setTimeout(function() { 409 if ((Date.now() - lastRan) >= limit) { 410 func.apply(context, args); 411 lastRan = Date.now(); 412 } 413 }, limit - (Date.now() - lastRan)); 414 } 415 } 416 } 417 const loadEle = this.$unit.querySelector('.loading-inner') 418 const targetElement = this.$unit 419 let isLoading = false; // å è½½ç¶æé 420 let lastScrollTop = 0 421 const checkScroll = async () => { 422 let currentScrollTop = window.pageYOffset || document.documentElement.scrollTop; 423 const elementBottom = targetElement.getBoundingClientRect().bottom; 424 // console.log('elementBottom', elementBottom, 'innerHeight', window.innerHeight) 425 const currentPageObj = this.allPage[this.tab_list[0]] 426 if (currentScrollTop > lastScrollTop && elementBottom && elementBottom <= window.innerHeight + 20 && !isLoading && currentPageObj.page_count > 1 && currentPageObj.page_number < currentPageObj.page_count) { 427 console.log('å è½½æ´å¤æ°æ®----'); 428 listBox.classList.add('scroll-list') 429 isLoading = true 430 loadEle.classList.remove('d-none') 431 currentPageObj.page_number++ 432 const sortValue = this.$unit.querySelector('.content-set .change-set span.active').getAttribute('data-value') 433 const list = await this.getVideoData(this.tab_list[0], sortValue) 434 this.rederInnerContent(list, this.$unit) 435 setTimeout(() => { 436 isLoading = false 437 loadEle.classList.add('d-none') 438 listBox.classList.remove('scroll-list') 439 }, 500) 440 } 441 lastScrollTop = currentScrollTop; // æ´æ°ä¸ä¸æ¬¡çæ»å¨ä½ç½® 442 } 443 window.addEventListener('scroll', throttle(checkScroll, 200)); 444 const setItems = this.$unit.querySelectorAll('.content-set .change-set span') 445 if (setItems && setItems.length) {
446 setItems.forEach(val => { 447 val.addEventListener('click', async () => { 448 if (!val.classList.contains('active')) { 449 setItems.forEach(val => val.classList.remove('active')) 450 val.classList.add('active') 451 this.allPage[this.tab_list[0]].page_number = 1 452 const sortValue = val.getAttribute('data-value') 453 const list = await this.getVideoData(this.tab_list[0], sortValue) 454 this.rederInnerContent(list, this.$unit, 'replace') 455 } 456 }) 457 }) 458 } 459 } 460 renderPagination(val, dom) { 461 const paginationDom = dom.querySelector(".unit-content-list_pagination") 462 if (!paginationDom) return 463 window.changePagination = (e, num) => { 464 if ((e.target.classList.contains('iconfont') && e.target.parentNode.parentNode.classList.contains('disabled')) || ((e.target.classList.contains('base-pagination__link') && e.target.parentNode.classList.contains('disabled')))) return 465 this.onPagination(num, val, paginationDom) 466 } 467 let resHtml = `` 468 if (val && this.allPage[val].page_total) { 469 resHtml = ` 470 <nav class="base-pagination"> 471 <ul class="base-pagination__items"> 472 <li class="base-pagination__item base-pagination__item--prev ${this.allPage[val].page_number === 1 ? 'disabled' : ''}"> 473 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_number - 1})"><span class="iconfont icon-action-left-lighter"></span></a> 474 </li> 475 ` 476 if (this.allPage[val].page_number > 2) { 477 resHtml += ` 478 <li class="base-pagination__item ${this.allPage[val].page_count > 3 ? 'base-pagination__item-first' : ''}"> 479 <a class="base-pagination__link" href='javascript:;' onClick="changePagination(event, 1)">1</a> 480 </li> 481 ` 482 } 483 if (this.allPage[val].page_number > 2 && this.allPage[val].page_number - 2 > 1) { 484 resHtml += ` 485 <li class="base-pagination__item base-pagination__item-more disabled"> 486 <a class="base-pagination__link base-pagination__link-more" href="javascript:;">...</a> 487 </li> 488 ` 489 } 490 if (this.allPage[val].page_number > 1) { 491 resHtml += ` 492 <li class="base-pagination__item"> 493 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_number - 1})">${this.allPage[val].page_number - 1}</a> 494 </li> 495 ` 496 } 497 resHtml += ` 498 <li class="base-pagination__item active unit-pagination-active"> 499 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_number})">${this.allPage[val].page_number}</a> 500 </li> 501 ` 502 if (this.allPage[val].page_count - this.allPage[val].page_number > 1) { 503 resHtml += ` 504 <li class="base-pagination__item"> 505 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_number + 1})">${this.allPage[val].page_number + 1}</a> 506 </li> 507 ` 508 } 509 if (this.allPage[val].page_number == 1 && this.allPage[val].page_count > 3) { 510 resHtml += ` 511 <li class="base-pagination__item base-pagination__item-third"> 512 <a class="base-pagination__link" href="javascript:;" onClick="onPagination(event, 3)">3</a> 513 </li> 514 ` 515 } 516 if (this.allPage[val].page_count - this.allPage[val].page_number > 2) { 517 resHtml += ` 518 <li class="base-pagination__item base-pagination__item-more disabled"> 519 <a class="base-pagination__link" href="javascript:;">...</a> 520 </li> 521 ` 522 } 523 if (this.allPage[val].page_count !== this.allPage[val].page_number && this.allPage[val].page_count > this.allPage[val].page_number) { 524 resHtml += ` 525 <li class="base-pagination__item ${this.allPage[val].page_count > 3 && this.allPage[val].page_count - this.allPage[val].page_number !== 1 ? 'base-pagination__item-last' : ''}"> 526 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_count})">${this.allPage[val].page_count}</a> 527 </li> 528 ` 529 } 530 resHtml += ` 531 <li class="base-pagination__item base-pagination__item--next ${this.allPage[val].page_number >= this.allPage[val].page_count ? 'disabled' : ''} page-next"> 532 <a class="base-pagination__link" href="javascript:;" onClick="changePagination(event, ${this.allPage[val].page_number + 1})"><span class="iconfont icon-action-left-lighter"></span></a> 533 </li> 534 ` 535 } 536 paginationDom.innerHTML = resHtml 537 } 538 async onPagination(num, val, dom) { 539 this.allPage[val].page_number = num 540 const list = await this.getVideoData(val) 541 this.rederInnerContent(list, dom) 542 } 543 /** è·åè§é¢æ°æ® */ 544 getVideoData(val, default_sort) { 545 return new Promise((resolve, reject) => { 546 let resSize = this.page_size 547 if (this.config.limit_count && this.allPage[val].page_total > this.config.limit_count) {
548 const limitPage = Math.ceil(this.config.limit_count / this.page_size) 549 if (limitPage === this.allPage[val].page_number) { 550 resSize = this.config.limit_count - (this.allPage[val].page_number - 1) * this.page_size 551 } 552 } 553 let params = { 554 site_id: window.app.info.site.site_id, 555 language_code: window.app.info.site.language_code, 556 page_size: resSize, 557 page_number: this.allPage[val].page_number, 558 status: 1, 559 show_status: 1, 560 sort: 'update_time desc' 561 } 562 if (this.content_type === 'short_video') { 563 params.type = 1 564 } 565 if (this.content_type === 'specify_video') { 566 params.id = this.relate_list.join(',') 567 } 568 if (this.content_type === 'video_column') { 569 if (this.tab_list.length > 1) params.page_category_id = this.allPage[val].page_category_id 570 else params.page_category_id = this.relate_list.join(',') || '' 571 } 572 if (this.content_type === 'article_list') { 573 params.content_type = 3 574 params.is_delete = 0 575 } 576 if (this.config?.allow_content_tag) { 577 params.tag_id = this.pageInfo.tag_id 578 } 579 params.sort = this.config.sort || 'update_time desc' 580 if (default_sort) params.sort = default_sort 581 const apiUrl = this.content_type === 'article_list' ? '/article/list-page-by-search' : '/video/list-page-by-search'
582 const prefix = this.content_type === 'article_list' ? 'jmc' : 'qqt' 583 this.utilts.request({ 584 url: apiUrl, 585 method: 'POST', 586 prefix, 587 params 588 }).then(res => { 589 resolve(res.data.list) 590 }) 591 .catch(error => reject(error)) 592 }) 593 } 594 /** 595 * åå§åè½®æå¾ç¸å ³äºä»¶ 596 */ 597 initSwiperEvents() { 598 const that = this; 599 /** 600 * ä¿®å¤å½åè½®æå¾å¼å¸¸å¾ç 601 * æ£æ¥å½åæ´»å¨å¹»ç¯çä¸çå¾ç,妿srcä¸ºç©ºä½ælazy-src屿§,å设置src 602 */ 603 const fixEmptySrc = () => { 604 if (this.$carouselEl.swiper) { 605 const swiper = this.$carouselEl.swiper; 606 const activeSlide = swiper.slides[swiper.activeIndex]; 607 if (activeSlide) { 608 activeSlide.querySelectorAll('img[lazy-src][src=""], img[lazy-src]:not([src])').forEach(img => { 609 const imgSrc = img.getAttribute('data-src') || img.getAttribute('lazy-src'); 610 if (imgSrc) { 611 // 设置å¼å¸¸å¾ççsrc 612 img.setAttribute('src', imgSrc); 613 } 614 }); 615 } 616 } 617 }; 618 619 /** 620 * å½åææ¾æ¨¡å¼è§é¢èªå¨ææ¾ 621 * éç½®ææè§é¢,å¹¶ææ¾å½åæ´»å¨å¹»ç¯çä¸çè§é¢ 622 */ 623 const _autoplayVideo = () => { 624 if (this.$carouselEl.swiper) { 625 const swiper = this.$carouselEl.swiper; 626 swiper.slides.forEach((slide, index) => { 627 const $baseVideo = slide.querySelector('.base-video'); 628 if ($baseVideo) { 629 $baseVideo.resetVideo && $baseVideo.resetVideo(); 630 const CURRENT_PLAY = '2'; //å½åææ¾ 631 const videoConfig = this.config.video; 632 if (videoConfig?.autoplay && Number(videoConfig.autoplay) > 0 && this.method === CURRENT_PLAY && index === swiper.activeIndex) { 633 setTimeout(() => { 634 $baseVideo.playVideo && $baseVideo.playVideo(); 635 }); 636 } 637 } 638 }); 639 } 640 } 641 // è½®æç»æéç½®è§é¢ 642 const _autoResetVideo = () => { 643 if (this.$carouselEl.swiper) { 644 const swiper = this.$carouselEl.swiper; 645 swiper.slides.forEach((slide, index) => { 646 const $baseVideo = slide.querySelector('.base-video'); 647 if ($baseVideo) { 648 if (index !== swiper.activeIndex) { 649 $baseVideo.resetVideo && $baseVideo.resetVideo(); 650 } 651 } 652 }) 653 } 654 } 655 656 if (this.config.swiper.is_swiper) { 657 /** 658 * çå¬Swiperåå§å 659 * 设置Swiperåå§ååéè¦æ§è¡çäºä»¶ 660 */ 661 const listenSwiperInit = () => { 662 // å¤çswiper init 663 const _eventsInitSwiper = []; 664 this.$carouselEl._eventsInitSwiper = _eventsInitSwiper; 665 if (this.$carouselEl.swiper) { 666 _eventsInitSwiper.forEach(func => { 667 if (func instanceof Function) { 668 func(); 669 } 670 }); 671 } 672 }; 673 674 /** 675 * çå¬Swiperå¹»ç¯ç忢 676 * 设置幻ç¯ç忢æ¶éè¦æ§è¡çäºä»¶ 677 */ 678 const listenSwiperSlide = () => { 679 /** 680 * è½®æå¾åæ¢æ¶æ§è¡äºä»¶ 681 * @type {Array} 682 * @private 683 */ 684 const _eventsOnSlide = [fixEmptySrc]; 685 const _eventsSlideEnd = [] 686 const _eventsSlideStart = [] 687 const videoConfig = this.config.video; 688 const CURRENT_PLAY = '2'; //å½åææ¾ 689 if (videoConfig && this.method === CURRENT_PLAY) { 690 const videoAutoplay = videoConfig.autoplay && parseInt(videoConfig.autoplay) > 0; 691 if (videoAutoplay) { 692 _eventsSlideStart.push(_autoplayVideo); 693 } 694 _eventsSlideEnd.push(_autoResetVideo); 695 } 696 // [carousel]å± 697 this.$carouselEl._eventsOnSlide = _eventsOnSlide; 698 this.$carouselEl._eventsSlideStart = _eventsSlideStart; 699 this.$carouselEl._eventsSlideEnd = _eventsSlideEnd; 700 }; 701 702 listenSwiperInit(); 703 listenSwiperSlide(); 704 } 705 } 706 707
708 initPrevClick() { 709 const gifHoverImages = this.$unit.querySelectorAll('.unit-list-hover__image') 710 if (gifHoverImages.length) { 711 gifHoverImages.forEach(val => { 712 val.addEventListener('click', () => { 713 if (this.method === '2') val.classList.add('d-none') 714 val.parentNode.parentNode.click() 715 }) 716 }) 717 } 718 } 719 initVideoData(currentDom) { 720 const doms = currentDom ? currentDom.querySelectorAll('.unit-list__img[video-gif]') : ( 721 this.$unitList.querySelectorAll('.unit-list__video[video-gif]') || this.$unitList.querySelectorAll('.unit-list__img[video-gif]') 722 ) 723 if (doms.length) { 724 doms.forEach(item => { 725 this.renderHoverImg(item, currentDom ? true : false) 726 const h_dom = item.querySelector('.unit-list-hover__image') 727 const originImg = item.children[0].querySelector('.base-image__item') // hoveråå¾çææ 728 const video_gif = item.getAttribute('video-gif') 729 item.parentNode.onmouseover = e => { 730 if (h_dom && h_dom.classList.contains('hover_img_before_load')) { 731 h_dom.classList.remove('hover_img_before_load') 732 } 733 originImg.classList.add('opacity0') 734 item.querySelector('.base-video__play')?.classList.add('d-none') 735 item.parentNode?.querySelector('.base-video__play').classList.add('d-none') 736 } 737 item.parentNode.onmouseout = e => { 738 originImg.classList.remove('opacity0') 739 if (h_dom) { 740 h_dom.classList.add('hover_img_before_load') 741 } 742 item.querySelector('.base-video__play')?.classList.remove('d-none') 743 item.parentNode?.querySelector('.base-video__play').classList.remove('d-none') 744 } 745 }) 746 } 747 } 748 renderHoverImg(node, flag) { 749 const video_gif = node.getAttribute('video-gif') 750 node.setAttribute('hover-img', true) 751 node.setAttribute('video-gif', video_gif) 752 let hoverImgEl = '' 753 if (node.querySelector('.unit-list-hover__image img')) { 754 hoverImgEl = node.querySelector('.unit-list-hover__image img') 755 hoverImgEl.setAttribute('lazy-src', video_gif) 756 const wrapper = flag ? node.children[0].cloneNode(true) : node.children[0].querySelector('.base-video__thumb').cloneNode(true) 757 wrapper.querySelector('.base-image__item').innerHTML = hoverImgEl.outerHTML 758 node.querySelector('.unit-list-hover__image').innerHTML = wrapper.outerHTML 759 const hoverImg = node.querySelector('.unit-list-hover__image img') 760 new LazyImg(hoverImg) 761 // node.querySelector('.unit-list-hover__image img').setAttribute('lazy-type', '') 762 } else { 763 hoverImgEl = document.createElement('div') 764 // unit-list-hover__image animate__animated hover_img_before_load 765 hoverImgEl.classList.add('unit-list-hover__image', 'hover_img_before_load') 766 const wrapper = flag ? node.children[0].cloneNode(true) : node.children[0].querySelector('.base-video__thumb').cloneNode(true) 767 wrapper.querySelector('.base-image__item').innerHTML = `<img class="base-image__img img-fluid" lazy-src="${video_gif}" alt="">` 768 hoverImgEl.innerHTML = wrapper.outerHTML 769 const hoverImg = hoverImgEl.querySelector('.unit-list-hover__image img') 770 new LazyImg(hoverImg) 771 if (flag) node.appendChild(hoverImgEl) 772 else node.querySelector('.base-video__preview').appendChild(hoverImgEl) 773 // node.querySelector('.unit-list-hover__image img').setAttribute('lazy-type', '') 774 } 775 } 776 initMoreData() { 777 const tabHeader = this.$unit.querySelector('.tab-header') 778 const contentSet = this.$unit.querySelector('.content-set') 779 if (this.utilts.getScreen() === 'default' && !this.utilts.checkDesign() && tabHeader) { 780 const parents = this.utilts.getParentsByAttr(this.$unit, 'package-group', 'cell') 781 const videoInner = parents[0].querySelector('.video-inner') 782 let bottomVal = document.querySelector('[package-type="header"]').offsetHeight 783 if (videoInner) { 784 const videoRect = videoInner.getBoundingClientRect() 785 bottomVal = videoRect.bottom 786 } 787 tabHeader.style.top = bottomVal + 'px' 788 } 789 if (this.utilts.getScreen() === 'default' && !this.utilts.checkDesign() && contentSet) { 790 const headerHeight = document.querySelector('[package-type="header"]').offsetHeight 791 contentSet.style.top = headerHeight + 'px' 792 } 793 const moreEle = this.$unitList.querySelector('.show-more-box') 794 const listEles = this.$unitList.querySelectorAll('.unit-list__item') 795 if (moreEle) { 796 moreEle.addEventListener('click', () => { 797 moreEle.classList.add('d-none')
798 listEles.forEach(val => { 799 val.classList.remove('hide-more-box') 800 }) 801 }) 802 } 803 } 804 initModal() { 805 this.modal = new Modal() 806 const $modal = this.$unit.querySelector('.inquiry-modal-inner') 807 if (!$modal) return 808 this.modal.init({ 809 body: $modal, 810 title: window.app.utilts.$t('Free Quote & Information Request'), 811 size: 'lg', 812 className: 'inquiry-modal', 813 onSubmit: () => { 814 $modal.querySelector(`.btn`).click() 815 } 816 }) 817 } 818 initInquiry() { 819 let inquiryBtn = this.$unit.querySelectorAll(".unit-list__product.no-price") 820 if (this.config.show_inquiry == 1 && inquiryBtn.length) { 821 this.initModal() 822 Array.from(inquiryBtn).forEach(_val => { 823 _val.querySelector('.unit-list__inquire').addEventListener('click', (e) => { 824 e.preventDefault() 825 e.stopPropagation() 826 this.modal.open() 827 }) 828 }) 829 } 830 } 831 initQuoteList() { 832 let quoteDiv = this.$unit.querySelectorAll(".unit-list__quote") 833 if (this.config.show_quote_list == 1 && quoteDiv.length) { 834 const productQuoteIdList = window.app.info.productQuoteIdList 835 Array.from(quoteDiv).forEach(_val => { 836 const contentId = _val.getAttribute("content-id") 837 const addBtn = _val.querySelector('.unit-list__quoteAdd') 838 const listBtn = _val.querySelector('.unit-list__quoteList') 839 if (productQuoteIdList.includes(contentId)) { 840 addBtn.style.display = 'none' 841 listBtn.style.display = 'inline-block' 842 } 843 _val.querySelector('.unit-list__quoteAdd').addEventListener('click', (e) => { 844 e.preventDefault() 845 e.stopPropagation() 846 if (this.info.productQuoteIdList.length >= 50) { 847 new Message().warn(window.app.utilts.$t('The number of added products has reached the maximum limit (50). ')) 848 return 849 } 850 addBtn.style.display = 'none' 851 listBtn.style.display = 'inline-block' 852 const contentId = _val.getAttribute("content-id") 853 this.info.addProductQuoteId(contentId) 854 }) 855 }) 856 } 857 } 858 859 /** 860 * 产å屿§æç´¢å®¢æ·æ¸²æ 861 */ 862 renderList(keyword='') { 863 this.content_type_list.forEach(item => { 864 if (item === 'page_content') { 865 this.pageInfo.page_number = window.app.info.pagination.page_number || 1 866 } 867 this.initLoadData(item,keyword) 868 }) 869 } 870 871 /** åå§åé项å¡åæ¢äºä»¶ */ 872 initTabEvent() { 873 if (this.$tabList.length === 0) return 874 this.$tabList.forEach($tab => { 875 $tab.addEventListener('click', () => { 876 // å½åé项å¡éä¸ 877 this.$tabList.forEach(p => p.classList.remove('active')) 878 $tab.classList.add('active') 879 // å½åå 容éä¸ 880 const tabtype = $tab.dataset.tabtype 881 // 产åé项å¡å 容dom 882 const $tabTypeItem = this.$unit.querySelectorAll('[tab-type]') 883 $tabTypeItem.forEach($tabContent => { 884 const selected = $tabContent.getAttribute('tab-type') === tabtype 885 if (selected) { 886 $tabContent.classList.remove('d-none') 887 } else { 888 $tabContent.classList.add('d-none') 889 } 890 }) 891 }) 892 }) 893 } 894 895 async initLoadData(type = '',keyword='') { 896 if (type === 'products-discount-now') type = 'now' 897 else if (type === 'products-discount-upcoming') type = 'upcoming' 898 899 const validType = ['now', 'upcoming', 'page_content'] 900 if (type && validType.includes(type) && (type !== 'page_content' || window.app.info.page.page_type === 'product_list')) { 901 const num = this.pageInfo.page_number 902 const size = this.pageInfo.page_size 903 const data = await window.app.getProductListPageBySearch(type, num, size,keyword) 904 let tabType = type 905 // if (tabType === 'youMightLike') tabType = 'you might like' 906 // else if (tabType === 'products-similar') tabType = 'similar' 907 const $nodeList = this.$unitList.querySelector('[tab-type="' + tabType + '"]') 908 this.getTabList($nodeList || this.$unitList, data.list) 909 // this.initVideoData($nodeList || this.$unitList) 910 } 911 } 912 getTabList($tabNode, list) { 913 const self = this 914 $tabNode.innerHTML = '' 915 if (list.length === 0 && this.$noData) { 916 this.$noData.classList.remove('d-none') 917 return 918 } 919 this.$noData.classList.add('d-none') 920 const params = { 921 open_hover: this.open_hover, 922 attrId: this.attrId, pageInfo: this.pageInfo, colInfo: this.colInfo, config: this.config 923 } 924 this.element = new ScriptContentListElement(params) 925 for (let index = 0; index < list.length; index++) { 926 const item = list[index]; 927 const $itemNode = this.element.getItem(item) 928 if (item.video_gif) { 929 $itemNode.querySelector('.unit-list__img')?.setAttribute('hover-img', true) 930 $itemNode.querySelector('.unit-list__img')?.setAttribute('video-gif', item.video_gif) 931 } 932 this.element.$items.append($itemNode) 933 } 934 $tabNode.append(this.element.$container) 935 if (this.config.swiper.is_swiper) { 936 $tabNode.setAttribute('data-carousel', 0) 937 } 938 window.addEventListener('hookInitContentRender', function () { 939 self.initHoverImg() 940 }, { 941 once: false 942 }) 943 window.app.initPlug(this.attrId, true)
944 this.initQuoteList() 945 } 946 947 initHoverContent() { 948 949 } 950 951 initHoverImg() { 952 const that = this 953 const hoverImgEffect = (this.open_hover || '').replace(/[^A-Za-z0-9,_-]/g, '').split(',') 954 const hoverImgIn = hoverImgEffect[0] || '' 955 const hoverImgOut = hoverImgEffect[1] || '' 956 const hoverImgDuration = hoverImgEffect[2] || '' 957 const doms = this.$unit.querySelectorAll('.unit-list__image[hover-img="true"]') 958 if (doms.length) { 959 doms.forEach((item, index) => { 960 let h_dom = item.querySelector('.unit-list-hover__image') 961 const video_gif = item.getAttribute('video-gif') 962 // if (!h_dom) return 963 let h_img = item.querySelector('.unit-list-hover__image img') 964 const hoverNextImg = h_img && h_img.src 965 let e_in = video_gif ? '' : hoverImgIn ? `animate__${hoverImgIn}` : '' 966 let e_out = video_gif ? '' : hoverImgOut ? `animate__${hoverImgOut}` : '' 967 const style_val = window.getComputedStyle(item) 968 const pt = style_val['paddingTop'] || '0px' 969 const pb = style_val['paddingBottom'] || '0px' 970 const pl = style_val['paddingLeft'] || '0px' 971 const pr = style_val['paddingRight'] || '0px' 972 if (`${pt + pb + pl + pr}` !== '0px0px0px0px' && h_dom) { 973 h_dom.setAttribute('style', `top:${pt};left:${pl};width:calc(100% - ${pl} - ${pr});height:calc(100% - ${pt} - ${pb});`) 974 } 975 let originImg = item.children[0].querySelector('.base-image__item') || item.querySelector('.unit-list__img .base-image__item') // hoveråå¾çææ 976 if (hoverImgDuration) { 977 originImg.classList.add(hoverImgDuration) 978 } 979 h_dom && h_dom.classList.add('hover_img_before_load'); 980 item.parentNode.onmouseover = e => { 981 let h_img = item.querySelector('.unit-list-hover__image img') 982 const hoverNextImg = h_img && h_img.src 983 if (h_dom && h_dom.classList.contains('hover_img_before_load')) { 984 h_dom.classList.remove('hover_img_before_load') 985 } 986 if (hoverNextImg) { 987 if (e_in) { 988 originImg.classList.remove(e_in) 989 h_dom.classList.add(e_in, 'animate__animated') 990 } 991 if (e_out) { 992 originImg.classList.add(e_out, 'animate__animated') 993 h_dom.classList.remove(e_out) 994 } else { 995 originImg.classList.add('opacity0') 996 } 997 } else { 998 if (e_in) { 999 originImg.classList.add(e_in, 'animate__animated') 1000 } 1001 if (e_out) { 1002 originImg.classList.remove(e_out) 1003 } 1004 } 1005 if (item.getAttribute('video-gif')) { 1006 originImg.classList.add('opacity0') 1007 // h_img.setAttribute('src', video_gif) 1008 item.querySelector('.base-video__play')?.classList.add('opacity0') 1009 } 1010 } 1011 1012 1013 item.parentNode.onmouseout = e => { 1014 originImg.classList.remove('opacity0') 1015 let h_img = item.querySelector('.unit-list-hover__image img') 1016 const hoverNextImg = h_img && h_img.src 1017 if (hoverNextImg) { 1018 if (e_in) { 1019 originImg.classList.add(e_in, 'animate__animated') 1020 h_dom.classList.remove(e_in) 1021 } 1022 if (e_out) { 1023 originImg.classList.remove(e_out) 1024 h_dom.classList.add(e_out, 'animate__animated') 1025 } else { 1026 if (h_dom) { 1027 h_dom.classList.add('hover_img_before_load') 1028 } 1029 } 1030 } else { 1031 if (e_in) { 1032 originImg.classList.remove(e_in) 1033 } 1034 // if (e_out) { 1035 // originImg.classList.add(e_out, 'animate__animated') 1036 // } 1037 } 1038 if (item.getAttribute('video-gif')) { 1039 // h_img.setAttribute('src', '') 1040 item.querySelector('.base-video__play')?.classList.remove('opacity0') 1041 } 1042 } 1043 }) 1044 } 1045 } 1046 initVideo() { 1047 const doms = this.$unit.querySelectorAll('[video-src]') 1048 if (!doms.length) { 1049 return 1050 } 1051 const slideNext = () => { 1052 const swiper = this.$carouselEl.swiper 1053 if (swiper && swiper.slideNext) { 1054 swiper.slideNext() 1055 } 1056 } 1057 const config = this.config.video 1058 doms.forEach(($el, index) => { 1059 let url = $el.getAttribute('video-src') 1060 const videothumbDom = $el.querySelector('.base-video__thumb img') 1061 const videothumb = videothumbDom.getAttribute('src') || videothumbDom.getAttribute('lazy-src') 1062 const isIframe = /^\s*<iframe[^>]*>[\s\S]*?<\/iframe>\s*$/.test(url) 1063 const isMp4 = /\.(mp4|m3u8)(\?|$)/i.test(url || '') 1064 const showMask = config.show_mask * 1 1065 const opacity = showMask?`filter:brightness(${config.opacity});`:'' 1066 const showControls = config.controls && config.controls.toString() === '1' || false 1067 if (url) { 1068 // éæ 1069 const replayWrap = 1070 `<div class="base-video__wrap--replay"> 1071 <div class="replay-icon"> 1072 <svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%"> 1073 <path class="ytp-svg-fill" d="M 18,11 V 7 l -5,5 5,5 v -4 c 3.3,0 6,2.7 6,6 0,3.3 -2.7,6 -6,6 -3.3,0 -6,-2.7 -6,-6 h -2 c 0,4.4 3.6,8 8,8 4.4,0 8,-3.6 8,-8 0,-4.4 -3.6,-8 -8,-8 z" id="ytp-id-125"></path> 1074 </svg> 1075 </div> 1076 </div>` 1077 const videoList = [ 1078 `<div class="base-video__wrap"> 1079 ${showControls && this.method=== '2' ? '<div class="base-video__wrap--close">Ã</div>': ''} 1080 ${showControls && this.method=== '2' ? replayWrap : replayWrap} 1081 <video 1082 style="height:auto;display:block;margin:0 auto;max-width:100%;${opacity}" 1083 autoplay 1084 controlsList="nodownload" 1085 webkit-playsinline="true" 1086 playsinline="true" 1087 x5-video-player-type="h5-page" 1088 preload="metadata" 1089 src="${url}" 1090 ${config.loop && config.loop.toString() === '1' ? ' loop' : ''} 1091 ${config.muted && config.muted.toString() === '1' ? ' muted' : ''} 1092 ${showControls ? ' controls' : '' } 1093 poster="${videothumb}" 1094 ></video> 1095 </div>`, 1096 '<iframe '+ opacity +' width="100%" frameborder="0" allow="autoplay" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" src="' + url + '"></iframe>' 1097 ] 1098 1099 let videoHtml; 1100 let iframeUrl = [] 1101 if (isIframe) { 1102 iframeUrl = globalThis.Server.iframeAutoplay(url).split('<iframe') 1103 videoHtml = `<iframe style="filter:brightness(${showMask?config.opacity:'1'})"`+iframeUrl[1] 1104 } else if (isMp4) { 1105 // videoHtml = videoList[0] 1106 if (this.utilts.getDevice().access_device === 'PC') { // æ²¡é¼ æ ä¸éè¦ææ¾ï¼éè¿this.initLink()ç»å®äºä»¶ç´æ¥è·³è½¬è¯¦æ 页 1107 const videoPlayer = new VideoPlayer($el.querySelector('.video-container'), url, { 1108 trigger: 'hover', 1109 ...config, 1110 playerConfig: { 1111 poster: videothumb, 1112 } 1113 }) 1114 const swiperAutoplay = parseInt(this.config.swiper.autoplay || '0') 1115 if (swiperAutoplay) { 1116 videoPlayer.on('play', () => { 1117 if (this.$carouselEl.swiper) { 1118 this.$carouselEl.swiper.autoplay.stop() 1119 } 1120 }) 1121 videoPlayer.on('destroy', () => { 1122 if (this.$carouselEl.swiper) { 1123 this.$carouselEl.swiper.autoplay.start() 1124 } 1125 }) 1126 } 1127 } 1128 return 1129 } else { 1130 videoHtml = globalThis.Server.iframeAutoplay(videoList[1]) 1131 } 1132 const stopPlay = (e) => { 1133 // 夿å¨éæ©éèææ¬ä¸ä¸è½®ææ åµä¸ä¸æ¾ç¤ºææ¬ 1134 if (!swiperContainerEle.swiper && config.auto_hide == 1) { 1135 // swiperContainerEle.querySelector('.unit-list__text').style.opacity = 0 1136 $el.closest('.unit-list__item').classList.add('hide-videotext') 1137 } 1138 if (!swiperContainerEle.swiper) return 1139 if (swiperContainerEle) swiperContainerEle.swiper.autoplay.stop() 1140 // è½®ææ¨¡å¼ä¸æ¯å¦èªå¨éèææ¬ç夿,ä¸é¢æ¯éè½®ææ¨¡å¼,ä¸å²çª 1141 if (parseInt(config.auto_hide) === 1) { 1142 // swiperContainerEle.swiper.slides[swiperContainerEle.swiper.activeIndex].querySelector('.unit-list__text').style.opacity = 0 1143 $el.closest('.unit-list__item').classList.add('hide-videotext') 1144 } 1145 // è°ç¨play()æ¹æ³è¿è¡èªå¨ææ¾ 1146 // swiperContainerEle.getElementsByTagName("video")[0].play() 1147 e.target.play() 1148 } 1149 const startPlay = (e) => { 1150 if (!swiperContainerEle.swiper && config.auto_hide == 1) { 1151 // swiperContainerEle.querySelector('.unit-list__text').style.opacity = 1 1152 $el.closest('.unit-list__item').classList.remove('hide-videotext') 1153 } 1154 if (!swiperContainerEle.swiper) return 1155 // 妿é ç½®ä¸éè¦èªå¨è½®æ,åä¸åæ¢å¤èªå¨è½®æ 1156 if (swiperContainerEle && this.config.swiper.autoplay !== '0') swiperContainerEle.swiper.autoplay.start() 1157 if (parseInt(config.auto_hide) === 1) { 1158 // swiperContainerEle.swiper.slides[swiperContainerEle.swiper.activeIndex].querySelector('.unit-list__text').style.opacity = 1 1159 $el.closest('.unit-list__item').classList.remove('hide-videotext') 1160 } 1161 } 1162 const resetVideo = $el.resetVideo = () => { 1163 const $preview = $el.querySelector('.base-video__preview') 1164 const $video = $el.querySelector('.base-video__preview video') 1165 const $replayWrap = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--replay') 1166 if ($preview) { 1167 const videoWrapDom = $preview.querySelector('.base-video__wrap') 1168 // console.log('videoWrapDom', videoWrapDom) 1169 1170 const isSwiper = this.config.swiper.is_swiper 1171 // console.log('isSwiper', isSwiper) 1172 if (!this.config.swiper.is_swiper) { 1173 // console.log('䏿¯ swiper') 1174 $replayWrap.style.display = 'flex' 1175 $video.controls = false 1176 return 1177 } 1178 if (videoWrapDom) { 1179 videoWrapDom.remove() 1180 } 1181 $preview.querySelectorAll('video, iframe').forEach(video => { 1182 if (video instanceof HTMLVideoElement) { 1183 video.removeEventListener("ended", resetVideo) 1184 } 1185 video.remove() 1186 }) 1187 $preview.classList.remove('play') 1188 } 1189 } 1190 // å½åææ¾ 1191 const playVideo = $el.playVideo = () => { 1192 const videothumb = $el.querySelector('.base-video__thumb img') 1193 const videotDom = $el.querySelector('.base-video__preview video') 1194 const videoPoster = videothumb && (videothumb.currentSrc || videothumb.getAttribute('src') || videothumb.getAttribute('lazy-src')) 1195 const $preview = $el.querySelector('.base-video__preview') 1196 const $videos = $preview.querySelectorAll('video, iframe') 1197 $preview.classList.add('play') 1198 // $el.getAttribute('videoscale') && $el.classList.add('base-video--scale') 1199 $el.classList.add('play') 1200 if ($preview && !$videos.length) { 1201 const template = document.createElement('template') 1202 template.innerHTML = videoHtml 1203 const videos = Array.from(template.content.children) 1204 videos.forEach(video => { 1205 $preview.insertAdjacentElement('beforeend', video) 1206 }) 1207 } 1208 if (this.$carouselEl.swiper) { 1209 this.$carouselEl.swiper.autoplay.stop() 1210 } 1211 if (videothumb && videotDom) videotDom.poster = videothumb.getAttribute('src') || videothumb.getAttribute('lazy-src') 1212 $el.querySelector('.base-video__preview').classList.add('play') 1213 // $el.getAttribute('videoscale') && $el.classList.add('base-video--scale') 1214 $el.classList.add('play') 1215 const closeBtn = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--close') 1216 const replayBtn = $el.querySelector('.base-video__preview').querySelector('.replay-icon') 1217 if (showControls && closeBtn) { 1218 const closeVideo = (event) => { 1219 event.stopPropagation() 1220 event.preventDefault() 1221 const videoWrapDom = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap') 1222 if (videoWrapDom) { 1223 videoWrapDom?.remove() 1224 $el.querySelector('.base-video__preview')?.classList.remove('play') 1225 $el.classList.remove('play') 1226 } 1227 } 1228 closeBtn.addEventListener('click', closeVideo, { once: true }) 1229 } 1230 // console.log('auto_reset', this.config.video.auto_reset) 1231 // if (showControls && replayBtn && this.config.video.auto_reset !== '1') { 1232 if (showControls && replayBtn ) { 1233 const videoDom = $el.querySelector('.base-video__wrap video') 1234 const replayWrapDom = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--replay') 1235 // console.log('videoDom', videoDom) 1236 const showReplayBtn = (event) => { 1237 event.stopPropagation() 1238 event.preventDefault() 1239 if(replayWrapDom) { 1240 replayWrapDom.style.display = 'flex' 1241 videoDom.controls = false 1242 } 1243 } 1244 videoDom?.addEventListener('ended', showReplayBtn) 1245 const replay = (event) => { 1246 event.stopPropagation() 1247 event.preventDefault() 1248 videoDom.currentTime = 0 1249 videoDom.play() 1250 replayWrapDom.style.display = 'none' 1251 videoDom.controls = true 1252 } 1253 replayBtn?.addEventListener('click', replay) 1254 } 1255 // console.log('auto_reset', this.config.video.auto_reset) 1256 // console.log('config', this.config) 1257 let myVideo = $el.querySelectorAll('video') 1258 const swiperAutoplay = parseInt(this.config.swiper.autoplay || '0') 1259 myVideo.forEach(elVideo => { 1260 if (videoPoster) { 1261 elVideo.poster = videoPoster 1262 } 1263 elVideo.removeEventListener('play', stopPlay) 1264 elVideo.addEventListener('play', stopPlay) 1265 elVideo.removeEventListener('pause', startPlay) 1266 elVideo.addEventListener('pause', startPlay) 1267 if (this.config.video.auto_reset > 0) { 1268 elVideo.removeEventListener("ended", resetVideo); 1269 if (swiperAutoplay === 0) { 1270 // èªå¨è½®æçæ åµä¸ï¼è§é¢ææ¾ç»æä¸èªå¨éç½® 1271 elVideo.addEventListener("ended", resetVideo, {once: true}); 1272 } 1273 } 1274 if (swiperAutoplay > 0 && !elVideo._eventSlideNext) { 1275 elVideo._eventSlideNext = slideNext 1276 elVideo.addEventListener("ended", slideNext, {once: true}); 1277 } 1278 }) 1279 // if (myVideo) { 1280 // myVideo.removeEventListener('play', stopPlay) 1281 // myVideo.addEventListener('play', stopPlay) 1282 // myVideo.removeEventListener('pause', startPlay) 1283 // myVideo.addEventListener('pause', startPlay) 1284 // if (this.config.video.auto_reset > 0) { 1285 // myVideo.removeEventListener("ended", resetVideo); 1286 // myVideo.addEventListener("ended", resetVideo); 1287 // } 1288 // } 1289 } 1290 const clickPlayVideo = (e) => { 1291 e.stopPropagation() 1292 e.stopImmediatePropagation() 1293 if (!$el.querySelector('.base-video__preview').classList.contains('play')) { 1294 // æè§é¢ 1295 // e.preventDefault() 1296 playVideo() 1297 } 1298 1299 // if (/\.mp4(\?|$)/.test(url) && window.app.utilts.checkScreenMobile()) { 1300 // // ææºç«¯ 1301 // $el.querySelector('video').requestFullscreen() 1302 // } 1303 return false 1304 }
1305 if (config.autoplay.toString() === '1' && isMp4 && $el.querySelector('.base-video__preview').classList.value.indexOf('play') === -1) { 1306 // èªå¨ææ¾ 1307 playVideo() 1308 if (this.config.video.auto_reset > 0) { 1309 $el.addEventListener('click', clickPlayVideo, {useCapture: false}) 1310 } 1311 } else { 1312 // æå¨ææ¾ 1313 if (isIframe) { 1314 videoHtml = this.config.default_src ? videoHtml : globalThis.Server.iframeAutoplayClear(videoHtml, config.muted && config.muted.toString() === '1') 1315 } 1316 $el.addEventListener('click', clickPlayVideo, {useCapture: false}) 1317 } 1318 } 1319 }) 1320 } 1321 1322 initResize() { 1323 if (!this.config.resize?.is_resize) return 1324 1325 const $container = this.$unitList.querySelector('.resize-container') 1326 if (!$container) return 1327 const $wrapper = $container.querySelector('.unit-list__items') 1328 const $firstItem = $wrapper.firstElementChild 1329 const $firstItemInner = $firstItem.querySelector('.unit-list__item-inner') 1330 const $laseItem = $wrapper.lastElementChild 1331 // const $firstImg = $firstItem.querySelector('.base-image__img') 1332 // const $firstText = $firstItem.querySelector('.unit-list__text') 1333 const $splitLine = $container.querySelector('.unit-list__split-line') 1334 1335 let direction = this.config.resize?.direction || 'x'; 1336 let offsetX = 0; 1337 let offsetY = 0; 1338 1339 // $firstText.setAttribute('style', `width:${$container.offsetWidth * 0.5}px;`) 1340 if (direction === 'x') { 1341 $firstItemInner.setAttribute('style', `width:${$container.offsetWidth}px;max-width:${$container.offsetWidth}px`) 1342 // çå¬ container 尺寸åå 1343 var observer = new ResizeObserver(function (entries) { 1344 entries.forEach(function (entry) { 1345 if (entry.target === $container) { 1346 // è·å宽度 1347 const width = entry.contentRect.width; 1348 $firstItemInner.setAttribute('style', `width:${width}px;max-width:${width}px`) 1349 } 1350 }); 1351 }); 1352 // çå¬ç®æ å ç´ ç宽度åå 1353 observer.observe($container); 1354 } 1355 1356 function startDrag(event) { 1357 event.preventDefault() 1358 1359 offsetX = $container.getBoundingClientRect().left; 1360 offsetY = $container.getBoundingClientRect().top; 1361 document.addEventListener('mouseup', stopDrag) 1362 document.addEventListener('mousemove', drag) 1363 1364 document.addEventListener('touchend', stopDrag) 1365 document.addEventListener('touchmove', drag, { 1366 passive: false, // 黿¢é»è®¤æ»å¨è¡ä¸º 1367 }) 1368 } 1369 1370 function stopDrag(event) { 1371 event.preventDefault() 1372 1373 document.removeEventListener('mousemove', drag) 1374 document.removeEventListener('mouseup', stopDrag) 1375 1376 document.removeEventListener('touchmove', drag) 1377 document.removeEventListener('touchend', stopDrag) 1378 } 1379 1380 function drag(event) { 1381 event.preventDefault() 1382 requestAnimationFrame(() => { 1383 if (direction === 'x') { 1384 let containerLeft = $container.getBoundingClientRect().left; 1385 let containerWidth = $container.offsetWidth;
1386 let clientX = 'touches' in event ? event.touches[0].clientX : event.clientX 1387 let x = clientX - offsetX; 1388 // å°ææ½åºåéå¶å¨å®¹å¨å é¨ 1389 if (clientX < containerLeft) { 1390 // console.log('å·¦è¾¹è¶ åº'); 1391 x = 0; 1392 } 1393 if (clientX > containerLeft + containerWidth - $splitLine.offsetWidth) { 1394 // console.log('å³è¾¹è¶ åº'); 1395 x = containerWidth - $splitLine.offsetWidth 1396 } 1397 $splitLine.style.left = x + "px"; 1398 $firstItem.setAttribute('style', `width:${x}px`) 1399 $laseItem.setAttribute('style', `clip-path: inset(0 0 0 ${x}px)`) // fixï¼éæèæ¯ï¼å¾çéå 1400 } else { 1401 let containerTop = $container.getBoundingClientRect().top 1402 let containerHeight = $container.offsetHeight; 1403 let clientY = 'touches' in event ? event.touches[0].clientY : event.clientY 1404 let y = clientY - offsetY; 1405 // å°ææ½åºåéå¶å¨å®¹å¨å é¨ 1406 if (clientY < containerTop) { 1407 y = 0; 1408 } 1409 if (clientY > containerTop + containerHeight - $splitLine.offsetHeight) { 1410 y = containerHeight - $splitLine.offsetHeight; 1411 } 1412 $splitLine.style.top = y + "px"; 1413 $firstItem.setAttribute('style', `height:${y}px`) 1414 $laseItem.setAttribute('style', `clip-path: inset(${y}px 0 0 0)`) 1415 } 1416 }) 1417 } 1418 1419 $splitLine.onmousedown = startDrag; 1420 $splitLine.ontouchstart = startDrag; 1421 } 1422 1423 initLink() { 1424 // ç¹å»å¡ç跳转详æ 1425 const $listAList = this.$unitList.querySelectorAll('.unit-list__a[data-href]') 1426 1427 for (const item of $listAList) { 1428 const dataHref = item.getAttribute('data-href') 1429 if (!this.utilts.checkDesign()) { 1430 if (dataHref.startsWith('javascript')) continue 1431 item.style.cursor = 'pointer' 1432 item.addEventListener('click', (e) => { 1433 if (e.target.closest('.xgplayer-controls')) return 1434 1435 const link = e.target.closest('a[href]'); 1436 if (link && link.href && !link.href.startsWith('javascript')) { 1437 e.stopPropagation(); 1438 return false; 1439 } 1440 1441 let target = item.getAttribute('data-target') 1442 if (target !== 'block') { 1443 window.open(dataHref, target || '_self') 1444 } 1445 }, true) 1446 } 1447 } 1448 } 1449} 1450 1451/** 1452 * 客æ·ç«¯æ°æ®html 1453 */ 1454class ScriptContentListElement { 1455 constructor({ attrId, pageInfo, colInfo, config, open_hover }) { 1456 this.open_hover = open_hover 1457 this.attrId = attrId 1458 this.pageInfo = pageInfo 1459 this.is_swiper = config.swiper.is_swiper 1460 this.colInfo = colInfo 1461 this.config = config 1462 this.init() 1463 } 1464 1465 init() { 1466 this.getMainHtml() 1467 } 1468 1469 getMainHtml() { 1470 this.$container = document.createElement('div') 1471 this.$container.classList.add('swiper-container') 1472 this.$items = this.getItems() 1473 this.$container.append(this.$items) 1474 this._setSwiperNode() 1475 } 1476 1477 getItems() { 1478 const $items = document.createElement('div') 1479 $items.classList.add('unit-list__items', 'swiper-wrapper') 1480 if (!this.is_swiper) $items.classList.add('row') 1481 if (this.is_swiper && !this.swiper.pagination) $items.classList.add('no-swiper-pagination') 1482 return $items 1483 } 1484 1485 /** è·å产åå表项 **/ 1486 getItem(item) { 1487 const $item = document.createElement('div') 1488 $item.setAttribute('data-id', item.content_id) 1489 $item.classList.add('animate', 'unit-list__item', 'swiper-slide') 1490 if (!this.is_swiper) { 1491 $item.classList.add(`col-${this.colInfo.cols_col}`) 1492 $item.classList.add(`col-md-${this.colInfo.cols_md}`) 1493 $item.classList.add(`col-xl-${this.colInfo.cols_xl}`) 1494 } 1495 const $listA = document.createElement('div') 1496 $listA.classList.add('unit-list__a') 1497 $listA.append(this.getItemContent(item)) 1498 $item.append($listA) 1499 1500 return $item 1501 } 1502 /** è·å产åå表项å 容 **/ 1503 getItemContent(item) { 1504 const $listInner = document.createElement('div') 1505 $listInner.classList.add('unit-list__item-inner', 'd-flex', 'flex-column') 1506 $listInner.append(this.getLinkImage(item)) 1507 $listInner.append(this.getLinkText(item)) 1508 return $listInner 1509 } 1510 1511 /** 1512 * æé®èç¹ 1513 */ 1514 getLinkImage(item) { 1515 const hoverImgEffect = (this.open_hover || '').replace(/[^A-Za-z0-9,_-]/g, '').split(',') 1516 const hoverImgIn = hoverImgEffect[0] || '' 1517 const hoverImgOut = hoverImgEffect[1] || '' 1518 const hoverImgDuration = hoverImgEffect[2] || '' 1519 const self = this 1520 const subNode = { 1521 // 1522 get baseImage() { 1523 let scale = '' 1524 let effect = 0 1525 if (self.config.image) { 1526 scale = self.config.image.scale || '' 1527 if (scale) scale = Number(scale) * 100 + '%' 1528 effect = self.config.image.effect 1529 } 1530 return ` 1531 <div class="base-image ${scale ? 'base-image--scale' : ''} ${effect ? 'base-image--effect-' + effect : ''}" ${scale ? 'style="--img-pt: ' + scale + '"' : ''}> 1532 <div class="base-image__item hover_img_origin base-image__item--default"> 1533 <img class="base-image__img img-fluid ${hoverImgDuration}" effect-in="${hoverImgIn}" effect-out="${hoverImgOut}" lazy-src="${item.img}" alt="${item.alt || item.title}" lazy-type="img"> 1534 </div> 1535 </div>` 1536 }, 1537 } 1538 1539 const $imgBoxs = document.createElement('a') 1540 $imgBoxs.classList.add('unit-list__image') 1541 const href = globalThis.Server.getRinseHref(item.href || 'javascript:;', window.app.info.site) 1542 $imgBoxs.setAttribute('href', href) 1543 $imgBoxs.setAttribute('target', item.target || '_self') 1544 1545 if (item.cover_url && this.config.video.icon === '1') { 1546 const videoNode = document.createElement('div') 1547 videoNode.classList.add('base-video__play') 1548 videoNode.innerHTML = `<i class="iconfont icon-action-play"></i>` 1549 $imgBoxs.appendChild(videoNode) 1550 } 1551 1552 // 产åå¾ç 1553 const $baseImg = document.createElement('div') 1554 // console.log('item*---list', item); 1555 $baseImg.classList.add('unit-list__img') 1556 $baseImg.setAttribute('content-render', 'product_hover,video_icon') 1557 $baseImg.setAttribute('content-type', item.content_type) 1558 $baseImg.setAttribute('content-id', item.content_id); 1559 (item.hover_img || self.config.hover_img) && $baseImg.setAttribute('open-hover', this.open_hover || '') 1560 $baseImg.innerHTML = subNode.baseImage 1561 $imgBoxs.append($baseImg) 1562 return $imgBoxs 1563 } 1564
1565 /** 1566 * æ é¢æè¿°ï¼ä»·æ ¼ 1567 */ 1568 getLinkText(item) { 1569 const self = this 1570 const getShowContent = (className, item, textStyle, title) => { 1571 const $titleBox = document.createElement('div') 1572 $titleBox.classList.add(`unit-list__${className}`) 1573 $titleBox.setAttribute('text-style', textStyle || '') 1574 1575 let $textBox 1576 if (className === 'title') { 1577 $textBox = document.createElement('a') 1578 const href = globalThis.Server.getRinseHref(item.href || 'javascript:;', window.app.info.site) 1579 $textBox.setAttribute('href', href) 1580 $textBox.setAttribute('target', item.target || '_self') 1581 } else { 1582 $textBox = document.createElement('div') 1583 } 1584 $textBox.classList.add('text_ellipsis') 1585 $textBox.setAttribute('_html', item[className + '_sign'] || '') 1586 $textBox.setAttribute('toolbar', 'false') 1587 $textBox.innerHTML = item[className] 1588 $titleBox.append($textBox) 1589 1590 return $titleBox 1591 } 1592 const subNode = { 1593 get priceInfo() { 1594 const min = `<div class="unit-list__price-min"><i>$</i><span>${item.price_min}</span></div>` 1595 let max = '' 1596 if (item.price_max > 0) { 1597 max = `<div class="unit-list__price-max"><i>$</i><span>${item.price_max}</span></div>` 1598 } 1599 return `${min}${max}` 1600 }, 1601 get listExtend() { 1602 const noPrice = ` 1603 <div class="unit-list__cart text-capitalize"> 1604 <i class="iconfont icon-base-cart-lighter"></i> 1605 <a href="${globalThis.Server.getRinseHref(item.href, window.app.info.site)}" target="${item.target || '_self'}">${window.app.utilts.$t('Add to cart')}
1605 </a> 1606 </div> 1607 <div class="unit-list__inquire text-capitalize"> 1608 <a href="${item.target==='block'?'javascript:;':globalThis.Server.getRinseHref(item.href, window.app.info.site)}" target="${item.target==='block'?'_self':item.target || '_self'}">${window.app.utilts.$t('Inquiry')}</a> 1609 </div>` 1610 let like = '' 1611 if (self.config.show_like) { 1612 like = ` 1613 <div class="unit-list__like" title="${window.app.utilts.$t('Like')}" pro-id="${item.id}"> 1614 <i class="iconfont icon-base-collect"></i> 1615 </div>` 1616 } 1617 return `${noPrice}${like}` 1618 } 1619 } 1620 1621 const $textBox = document.createElement('div') 1622 $textBox.classList.add('unit-list__text') 1623 1624 const $textInner = document.createElement('div') 1625 $textInner.classList.add('unit-list__text-inner') 1626 1627 const $content = document.createElement('div') 1628 $content.classList.add('unit-list__content') 1629 1630 $textInner.append($content) 1631 $textBox.append($textInner) 1632 1633 // æ é¢ 1634 if (this.config.show_title && item.title && this.config.has_title) { 1635 const style_title = self.config.style_type_title 1636 const $title = getShowContent('title', item, style_title) 1637 $content.append($title) 1638 } 1639 // åæ é¢ 1640 if (this.config.show_subtitle && item.subtitle && this.config.has_subtitle) { 1641 const style_subtitle = self.config.style_type_subtitle 1642 const $subtitle = getShowContent('subtitle', item, style_subtitle) 1643 $content.append($subtitle) 1644 } 1645 // æè¿° 1646 if (this.config.show_description && item.description && this.config.has_description) { 1647 const style_description = self.config.style_type_description 1648 const $description = getShowContent('description', item, style_description) 1649 $content.append($description) 1650 } 1651 1652 // ä»·æ ¼ 1653 if (this.config.show_read_more) { 1654 const $pricesBox = document.createElement('div') 1655 $pricesBox.classList.add('unit-list__product') 1656 if (Number(item.price_min) <= 0) $pricesBox.classList.add('no-price') 1657 1658 const $listPrice = document.createElement('div') 1659 $listPrice.classList.add('unit-list__price') 1660 $listPrice.innerHTML = subNode.priceInfo 1661 $pricesBox.append($listPrice) 1662 1663 const $extend = document.createElement('div') 1664 $extend.classList.add('unit-list__extend') 1665 $extend.innerHTML = subNode.listExtend 1666 $pricesBox.append($extend) 1667 1668 $textInner.append($pricesBox) 1669 } 1670 if (this.config.show_quote_list == '1') { 1671 $textBox.append(this.getQuoteBtn(item)) 1672 } 1673 return $textBox 1674 } 1675 1676 getQuoteBtn(item) { 1677 const self = this 1678 const $content = document.createElement('div') 1679 $content.classList.add('unit-list__quote') 1680 $content.setAttribute("content-id", item.content_id) 1681 const $addBtn = document.createElement('div') 1682 $addBtn.classList.add('unit-list__quoteAdd') 1683 $addBtn.innerHTML = `<i class="iconfont icon-action-add"></i> 1684 <span>${window.app.utilts.$t('Add to Quote List')}</span>` 1685 const $listBtn = document.createElement('a') 1686 $listBtn.classList.add('unit-list__quoteList') 1687 $listBtn.innerHTML = ` <div> 1688 ${window.app.utilts.$t('Browse the list')} â 1689 </div>` 1690 $content.append($addBtn) 1691 $content.append($listBtn) 1692 return $content 1693 } 1694 /** **/ 1695 _setSwiperNode() { 1696 if (this.config.swiper) { 1697 if (this.config.swiper.pagination) { 1698 const $div1 = document.createElement('div') 1699 $div1.classList.add('unit-product-list__pagination', 'swiper-pagination') 1700 this.$container.append($div1) 1701 } 1702 if (this.config.swiper.navigation) { 1703 const $div2 = document.createElement('div') 1704 $div2.classList.add('unit-product-list__button-prev', 'swiper-button-prev') 1705 this.$container.append($div2) 1706 const $div3 = document.createElement('div') 1707 $div3.classList.add('unit-product-list__button-next', 'swiper-button-next') 1708 this.$container.append($div3) 1709 } 1710 if (this.config.swiper.scrollbar) { 1711 const $div4 = document.createElement('div') 1712 $div4.classList.add('unit-product-list__scrollbar', 'swiper-scrollbar') 1713 this.$container.append($div4) 1714 } 1715 } 1716 } 1717}
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.