PageSourceSearch

https://www.hasungmachinery.com/assets/js/unit/list.js

js hasungmachinery.com collected 2026-10-04 06:54:16 UTC 52,160 bytes, 1,357 lines download raw bytes

1class ScriptList 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-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.config.hover_img = (params.hoverImg === 'true')
18		this.content_type = params.content_type
19		this.content_type_list = params.content_type.split(',')
20		this.modal = null
21		this.info = window.app.info
22		this.open_hover = params.open_hover // hover动画   fadeInUp,fadeOutUp,
23    const that = this
24    this.$carouselEl = this.$unitList
25		// 视频播放方式
26    if (this.config.video) {
27      let methodMap = {
28        default: this.config.video.method,
29        md: this.config.video.method_md,
30        xl: this.config.video.method_xl
31      }
32      this.method = methodMap[this.utilts.getScreen()]
33    }
34
35    if (this.config.swiper.is_swiper) {
36      this.initSwiperEvents()
37    }
38
39	}
40
41  render() {
42    if (this.$unit._zoom && this.$unit._zoom.render) {
43      this.$unit._zoom.render()
44    }
45  }
46
47	async init() {
48		if (!this.$unit) return
49		const that = this
50		this.content_type_list.forEach(item => {
51			if (item !== 'page_content') {
52				this.initLoadData(item)
53			}
54		})
55		this.initMoreData()
56		this.initHoverContent()
57		this.initInquiry()
58    this.initVideoData()
59    this.initVideo()
60    this.initLink()
61		this.initResize()
62		this.initQuoteList()
63		const initContent = () => {
64			// 等待contentRender完成再进行初始化
65			setTimeout(function () {
66				that.initHoverImg()
67			}, 300)
68		}
69		if (this.utilts.checkDesign() || (window.app && window.app.hookEvents && window.app.hookEvents['hookInitContentRender'])) {
70			initContent();
71			// window.addEventListener('hookInitContentRender', initContent, {
72			// 	once: false
73			// })
74		} else {
75			window.addEventListener('hookInitContentRender', initContent, {
76				once: true
77			})
78		}
79
80		// 初始选项卡切换事件
81		this.initTabEvent()
82		// 放大图片
83		if (this.config.target === 'zoom') {
84			await new Load('/assets/plugins/zoom.js')
85      this.$unit._zoom = new ZoomBuilder({
86				attrId: this.attrId,
87				dom: this.$unit,
88				selector: '.unit-list__image[zoom-img="true"]',
89				titleSelector: ".unit-list__title",
90				boxClass: 'list-zoom-box'
91			})
92		}
93    this.initPrevClick()
94	}
95
96/**
97 * 初始化轮播图相关事件
98 */
99initSwiperEvents() {
100  const that = this;
101  /**
102   * 修复当前轮播图异常图片
103   * 检查当前活动幻灯片中的图片,如果src为空但有lazy-src属性,则设置src
104   */
105  const fixEmptySrc = () => {
106    if (this.$carouselEl.swiper) {
107      const swiper = this.$carouselEl.swiper;
108      const activeSlide = swiper.slides[swiper.activeIndex];
109      if (activeSlide) {
110        activeSlide.querySelectorAll('img[lazy-src][src=""], img[lazy-src]:not([src])').forEach(img => {
111          const imgSrc = img.getAttribute('data-src') || img.getAttribute('lazy-src');
112          if (imgSrc) {
113            // 设置异常图片的src
114            img.setAttribute('src', imgSrc);
115          }
116        });
117      }
118    }
119  };
120
121  /**
122   * 当前播放模式视频自动播放
123   * 重置所有视频,并播放当前活动幻灯片中的视频
124   */
125  const _autoplayVideo = () => {
126    if (this.$carouselEl.swiper) {
127      const swiper = this.$carouselEl.swiper;
128      swiper.slides.forEach((slide, index) => {
129        const $baseVideo = slide.querySelector('.base-video');
130        if ($baseVideo) {
131          $baseVideo.resetVideo && $baseVideo.resetVideo();
132          const CURRENT_PLAY = '2'; //当前播放
133          const videoConfig = this.config.video;
134          if (videoConfig?.autoplay && Number(videoConfig.autoplay) > 0 && this.method === CURRENT_PLAY && index === swiper.activeIndex) {
135            setTimeout(() => {
136              $baseVideo.playVideo && $baseVideo.playVideo();
137            });
138          }
139        }
140      });
141    }
142  }
143  // 轮播结束重置视频
144  const _autoResetVideo = () => {
145    if (this.$carouselEl.swiper) {
146      const swiper = this.$carouselEl.swiper;
147      swiper.slides.forEach((slide, index) => {
148        const $baseVideo = slide.querySelector('.base-video');
149        if ($baseVideo) {
150          if (index !== swiper.activeIndex) {
151            $baseVideo.resetVideo && $baseVideo.resetVideo();
152          }
153        }
154      })
155    }
156  }
157
158  if (this.config.swiper.is_swiper) {
159    /**
160     * 监听Swiper初始化
161     * 设置Swiper初始化后需要执行的事件
162     */
163    const listenSwiperInit = () => {
164      // 处理swiper init
165      const _eventsInitSwiper = [];
166      this.$carouselEl._eventsInitSwiper = _eventsInitSwiper;
167      if (this.$carouselEl.swiper) {
168        _eventsInitSwiper.forEach(func => {
169          if (func instanceof Function) {
170            func();
171          }
172        });
173      }
174    };
175
176    /**
177     * 监听Swiper幻灯片切换
178     * 设置幻灯片切换时需要执行的事件
179     */
180    const listenSwiperSlide = () => {
181      /**
182       * 轮播图切换时执行事件
183       * @type {Array}
184       * @private
185       */
186      const _eventsOnSlide = [fixEmptySrc];
187      const _eventsSlideEnd = []
188      const _eventsSlideStart = []
189      const videoConfig = this.config.video;
190      const CURRENT_PLAY = '2'; //当前播放
191      if (videoConfig && this.method === CURRENT_PLAY) {
192        const videoAutoplay = videoConfig.autoplay && parseInt(videoConfig.autoplay) > 0;
193        if (videoAutoplay) {
194          _eventsSlideStart.push(_autoplayVideo);
195        }
196        _eventsSlideEnd.push(_autoResetVideo);
197      }
198      // [carousel]层
199      this.$carouselEl._eventsOnSlide = _eventsOnSlide;
200      this.$carouselEl._eventsSlideStart = _eventsSlideStart;
201      this.$carouselEl._eventsSlideEnd = _eventsSlideEnd;
202    };
203
204    listenSwiperInit();
205    listenSwiperSlide();
206  }
207}
208
209
210	initPrevClick() {
211    const gifHoverImages = this.$unit.querySelectorAll('.unit-list-hover__image')
212    if (gifHoverImages.length) {
213      gifHoverImages.forEach(val => {
214        val.addEventListener('click', () => {
215					if (this.method === '2') val.classList.add('d-none')
216          val.parentNode.parentNode.click()
217        })
218      })
219    }
220  }
221	initVideoData(currentDom) {
222		const doms = currentDom ? currentDom.querySelectorAll('.unit-list__img[video-gif]') : (
223			this.$unitList.querySelectorAll('.unit-list__video[video-gif]') || this.$unitList.querySelectorAll('.unit-list__img[video-gif]')
224		)
225		if (doms.length) {
226			doms.forEach(item => {
227				this.renderHoverImg(item, currentDom ? true : false)
228				const h_dom = item.querySelector('.unit-list-hover__image')
229				const originImg = item.children[0].querySelector('.base-image__item') // hover原图的效果
230				const video_gif = item.getAttribute('video-gif')
231				item.parentNode.onmouseover = e => {
232					if (h_dom && h_dom.classList.contains('hover_img_before_load')) {
233						h_dom.classList.remove('hover_img_before_load')
234						// h_dom.classList.remove('d-none')
235					}
236					originImg.classList.add('opacity0')
237					item.querySelector('.base-video__play')?.classList.add('d-none')
238					item.parentNode?.querySelector('.base-video__play').classList.add('d-none')
239				}
240				item.parentNode.onmouseout = e => {
241					originImg.classList.remove('opacity0')
242					if (h_dom) {
243						h_dom.classList.add('hover_img_before_load')
244					}
245					item.querySelector('.base-video__play')?.classList.remove('d-none')
246					item.parentNode?.querySelector('.base-video__play').classList.remove('d-none')
247				}
248        item.querySelectorAll('img[lazy-src][src=""], img[lazy-src]:not([src])').forEach(img => {
249          const imgSrc = img.getAttribute('data-src') || img.getAttribute('lazy-src');
250          if (imgSrc) {
251            // 设置异常图片的src
252            img.setAttribute('src', imgSrc);
253          }
254        });
255			})
256		}
257	}
258	renderHoverImg(node, flag) {
259		const video_gif = node.getAttribute('video-gif')
260		node.setAttribute('hover-img', true)
261		node.setAttribute('video-gif', video_gif)
262		let hoverImgEl = ''
263		if (node.querySelector('.unit-list-hover__image img')) {
264			hoverImgEl = node.querySelector('.unit-list-hover__image img')
265			hoverImgEl.setAttribute('lazy-src', video_gif)
266			const wrapper = flag ? node.children[0].cloneNode(true) : node.children[0].querySelector('.base-video__thumb').cloneNode(true)
267			wrapper.querySelector('.base-image__item').innerHTML = hoverImgEl.outerHTML
268			node.querySelector('.unit-list-hover__image').innerHTML = wrapper.outerHTML
269			const hoverImg = node.querySelector('.unit-list-hover__image img')
270			new LazyImg(hoverImg)
271			// node.querySelector('.unit-list-hover__image img').setAttribute('lazy-type', '')
272		} else {
273			hoverImgEl = document.createElement('div')
274			// unit-list-hover__image animate__animated hover_img_before_load
275			hoverImgEl.classList.add('unit-list-hover__image', 'hover_img_before_load')
276			const wrapper = flag ? node.children[0].cloneNode(true) : node.children[0].querySelector('.base-video__thumb').cloneNode(true)
277			wrapper.querySelector('.base-image__item').innerHTML = `<img class="base-image__img img-fluid" lazy-src="${video_gif}"  alt="">`
278			hoverImgEl.innerHTML = wrapper.outerHTML
279			const hoverImg = hoverImgEl.querySelector('.unit-list-hover__image img')
280			new LazyImg(hoverImg)
281			if (flag) node.appendChild(hoverImgEl)
282			else node.querySelector('.base-video__preview').appendChild(hoverImgEl)
283			// node.querySelector('.unit-list-hover__image img').setAttribute('lazy-type', '')
284		}
285	}
286	initMoreData() {
287		const moreEle = this.$unitList.querySelector('.show-more-box')
288		const listEles = this.$unitList.querySelectorAll('.unit-list__item')
289		if (moreEle) {
290			moreEle.addEventListener('click', () => {
291				moreEle.classList.add('d-none')
292				listEles.forEach(val => {
293					val.classList.remove('hide-more-box')
294				})
295			})
296		}
297	}
298	initModal() {
299		this.modal = new Modal()
300		const $modal = this.$unit.querySelector('.inquiry-modal-inner')
301		if (!$modal) return
302		this.modal.init({
303			body: $modal,
304			title: window.app.utilts.$t('Free Quote & Information Request'),
305			size: 'lg',
306			className: 'inquiry-modal',
307			onSubmit: () => {
308				$modal.querySelector(`.btn`).click()
309			}
310		})
311	}
312	initInquiry() {
313		let inquiryBtn = this.$unit.querySelectorAll(".unit-list__product.no-price")
314		if (this.config.show_inquiry == 1 && inquiryBtn.length) {
315			this.initModal()
316			Array.from(inquiryBtn).forEach(_val => {
317				_val.querySelector('.unit-list__inquire').addEventListener('click', (e) => {
318					e.preventDefault()
319					e.stopPropagation()
320					this.modal.open()
321				})
322			})
323		}
324	}
325	initQuoteList() {
326		let quoteDiv = this.$unit.querySelectorAll(".unit-list__quote")
327		if (this.config.show_quote_list == 1 && quoteDiv.length) {
328			const productQuoteIdList = window.app.info.productQuoteIdList
329			Array.from(quoteDiv).forEach(_val => {
330				const contentId = _val.getAttribute("content-id")
331				const addBtn = _val.querySelector('.unit-list__quoteAdd')
332				const listBtn = _val.querySelector('.unit-list__quoteList')
333				if (productQuoteIdList.includes(contentId)) {
334					addBtn.style.display = 'none'
335					listBtn.style.display = 'inline-block'
336				}
337				_val.querySelector('.unit-list__quoteAdd').addEventListener('click', (e) => {
338					e.preventDefault()
339					e.stopPropagation()
340					if (this.info.productQuoteIdList.length >= 50) {
341						new Message().warn(window.app.utilts.$t('The number of added products has reached the maximum limit (50). '))
342						return
343					}
344					addBtn.style.display = 'none'
345					listBtn.style.display = 'inline-block'
346					const contentId = _val.getAttribute("content-id")
347					this.info.addProductQuoteId(contentId)
348				})
349			})
350		}
351	}
352
353	/**
354	 * 产品属性搜索客户渲染
355	 */
356	renderList(keyword='') {
357		this.content_type_list.forEach(item => {
358			if (item === 'page_content') {
359				this.pageInfo.page_number = window.app.info.pagination.page_number || 1
360			}
361			this.initLoadData(item,keyword)
362		})
363	}
364
365	/** 初始化选项卡切换事件 */
366	initTabEvent() {
367		if (this.$tabList.length === 0) return
368		this.$tabList.forEach($tab => {
369			$tab.addEventListener('click', () => {
370				// 当前选项卡选中
371				this.$tabList.forEach(p => p.classList.remove('active'))
372				$tab.classList.add('active')
373				// 当前内容选中
374				const tabtype = $tab.dataset.tabtype
375				// 产品选项卡内容dom
376				const $tabTypeItem = this.$unit.querySelectorAll('[tab-type]')
377				$tabTypeItem.forEach($tabContent => {
378					const selected = $tabContent.getAttribute('tab-type') === tabtype
379					if (selected) {
380						$tabContent.classList.remove('d-none')
381					} else {
382						$tabContent.classList.add('d-none')
383					}
384				})
385			})
386		})
387	}
388
389	async initLoadData(type = '',keyword='') {
390		if (type === 'products-discount-now') type = 'now'
391		else if (type === 'products-discount-upcoming') type = 'upcoming'
392
393		const validType = ['now', 'upcoming', 'page_content']
394		if (type && validType.includes(type) && (type !== 'page_content' || window.app.info.page.page_type === 'product_list')) {
395			const num = this.pageInfo.page_number
396			const size = this.pageInfo.page_size
397			const data = await window.app.getProductListPageBySearch(type, num, size,keyword)
398			let tabType = type
399			// if (tabType === 'youMightLike') tabType = 'you might like'
400			// else if (tabType === 'products-similar') tabType = 'similar'
401			const $nodeList = this.$unitList.querySelector('[tab-type="' + tabType + '"]')
402			this.getTabList($nodeList || this.$unitList, data.list)
403      this.initVideoData($nodeList || this.$unitList)
404		}
405	}
406	getTabList($tabNode, list) {
407		const self = this
408		$tabNode.innerHTML = ''
409		if (list.length === 0 && this.$noData) {
410			this.$noData.classList.remove('d-none')
411			return
412		}
413		this.$noData.classList.add('d-none')
414		const params = {
415			open_hover: this.open_hover,
416			attrId: this.attrId, pageInfo: this.pageInfo, colInfo: this.colInfo, config: this.config
417		}
418		this.element = new ScriptListElement(params)
419		for (let index = 0; index < list.length; index++) {
420			const item = list[index];
421			const $itemNode = this.element.getItem(item)
422			if (item.video_gif) {
423				$itemNode.querySelector('.unit-list__img')?.setAttribute('hover-img', true)
424				$itemNode.querySelector('.unit-list__img')?.setAttribute('video-gif', item.video_gif)
425			}
426			this.element.$items.append($itemNode)
427		}
428		$tabNode.append(this.element.$container)
429		if (this.config.swiper.is_swiper) {
430			$tabNode.setAttribute('data-carousel', 0)
431		}
432		window.addEventListener('hookInitContentRender', function () {
433			self.initHoverImg()
434		}, {
435			once: false
436		})
437		window.app.initPlug(this.attrId)
438		this.initQuoteList()
439	}
440
441	initHoverContent() {
442
443	}
444
445	initHoverImg() {
446		const that = this
447		const hoverImgEffect = (this.open_hover || '').replace(/[^A-Za-z0-9,_-]/g, '').split(',')
448		const hoverImgIn = hoverImgEffect[0] || ''
449		const hoverImgOut = hoverImgEffect[1] || ''
450		const hoverImgDuration = hoverImgEffect[2] || ''
451		const doms = this.$unit.querySelectorAll('.unit-list__image[hover-img="true"]')
452		if (doms.length) {
453			doms.forEach((item, index) => {
454				let h_dom = item.querySelector('.unit-list-hover__image')
455				const video_gif = item.getAttribute('video-gif')
456				// if (!h_dom) return
457				let h_img = item.querySelector('.unit-list-hover__image img')
458				const hoverNextImg = h_img && h_img.src
459				let e_in = video_gif ? '' : hoverImgIn ? `animate__${hoverImgIn}` : ''
460				let e_out = video_gif ? '' : hoverImgOut ? `animate__${hoverImgOut}` : ''
461				const style_val = window.getComputedStyle(item)
462				const pt = style_val['paddingTop'] || '0px'
463				const pb = style_val['paddingBottom'] || '0px'
464				const pl = style_val['paddingLeft'] || '0px'
465				const pr = style_val['paddingRight'] || '0px'
466				if (`${pt + pb + pl + pr}` !== '0px0px0px0px' && h_dom) {
467					h_dom.setAttribute('style', `top:${pt};left:${pl};width:calc(100% - ${pl} - ${pr});height:calc(100% - ${pt} - ${pb});`)
468				}
469				let originImg = item.children[0].querySelector('.base-image__item') || item.querySelector('.unit-list__img .base-image__item') // hover原图的效果
470				if (hoverImgDuration) {
471					originImg.classList.add(hoverImgDuration)
472				}
473				h_dom && h_dom.classList.add('hover_img_before_load');
474				item.parentNode.onmouseover = e => {
475					let h_img = item.querySelector('.unit-list-hover__image img')
476					const hoverNextImg = h_img && h_img.src
477					if (h_dom && h_dom.classList.contains('hover_img_before_load')) {
478						h_dom.classList.remove('hover_img_before_load')
479					}
480					if (hoverNextImg) {
481						if (e_in) {
482							originImg.classList.remove(e_in)
483							h_dom.classList.add(e_in, 'animate__animated')
484						}
485						if (e_out) {
486							originImg.classList.add(e_out, 'animate__animated')
487							h_dom.classList.remove(e_out)
488						} else {
489							originImg.classList.add('opacity0')
490						}
491					} else {
492						if (e_in) {
493							originImg.classList.add(e_in, 'animate__animated')
494						}
495						if (e_out) {
496							originImg.classList.remove(e_out)
497						}
498					}
499					if (item.getAttribute('video-gif')) {
500						originImg.classList.add('opacity0')
501						// h_img.setAttribute('src', video_gif)
502						item.querySelector('.base-video__play').classList.add('opacity0')
503					}
504				}
505
506
507				item.parentNode.onmouseout = e => {
508					originImg.classList.remove('opacity0')
509					let h_img = item.querySelector('.unit-list-hover__image img')
510					const hoverNextImg = h_img && h_img.src
511					if (hoverNextImg) {
512						if (e_in) {
513							originImg.classList.add(e_in, 'animate__animated')
514							h_dom.classList.remove(e_in)
515						}
516						if (e_out) {
517							originImg.classList.remove(e_out)
518							h_dom.classList.add(e_out, 'animate__animated')
519						} else {
520							if (h_dom) {
521								h_dom.classList.add('hover_img_before_load')
522							}
523						}
524					} else {
525						if (e_in) {
526							originImg.classList.remove(e_in)
527						}
528						// if (e_out) {
529						// 	originImg.classList.add(e_out, 'animate__animated')
530						// }
531					}
532					if (item.getAttribute('video-gif')) {
533						// h_img.setAttribute('src', '')
534						item.querySelector('.base-video__play').classList.remove('opacity0')
535					}
536				}
537			})
538		}
539	}
540	initVideo() {
541    if (this.utilts.checkDesign()) document.getElementById('video-popup')?.remove() // 删除视频重新渲染,去掉正在播放的视频弹窗
542		const doms = this.$unit.querySelectorAll('[video-src]')
543		if (!doms.length) {
544			return
545		}
546    const slideNext = () => {
547      const swiper = this.$carouselEl.swiper
548      if (swiper && swiper.slideNext) {
549        swiper.slideNext()
550      }
551    }
552		const config = this.config.video
553		doms.forEach(($el, index) => {
554			if (config.autoplay == 1) {
555				setTimeout(() => {
556					$el.querySelector('.unit-list-hover__image')?.classList.add('d-none')
557				}, 0)
558			}
559			let url = $el.getAttribute('video-src')
560			const videothumbDom = $el.querySelector('.base-video__thumb img')
561			var videothumb = videothumbDom?.getAttribute('src') || videothumbDom?.getAttribute('lazy-src')
562			if(!!videothumb){
563				videothumb = globalThis.Server.getTransferImgUrl(videothumb, {convert: {quality: 80, dst: 'webp'}}, 'webp');
564			}
565			const isIframe = /^\s*<iframe[^>]*>[\s\S]*?<\/iframe>\s*$/.test(url)
566			const isMp4 = /\.mp4(\?|$)/i.test(url || '')
567			const showMask = config.show_mask * 1
568			const opacity = showMask?`filter:brightness(${config.opacity});`:''
569      const showControls = config.controls && config.controls.toString() === '1' || false
570      if (url) {
571        // 重播
572        const replayWrap =
573          `<div class="base-video__wrap--replay">
574          <div class="replay-icon">
575            <svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%">
576              <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>
577            </svg>
578          </div>
579        </div>`
580				const videoList = [
581					`<div class="base-video__wrap">
582            ${showControls && this.method=== '2' ? '<div class="base-video__wrap--close">×</div>': ''}
583            ${showControls && this.method=== '2' ? replayWrap : replayWrap}
584            <video
585              style="height:auto;display:block;margin:0 auto;max-width:100%;${opacity}"
586              autoplay
587              controlsList="nodownload"
588              webkit-playsinline="true"
589              playsinline="true"
590              x5-video-player-type="h5-page"
591              preload="metadata"
592              src="${url}"
593              ${config.loop && config.loop.toString() === '1' ? ' loop' : ''}
594              ${config.muted && config.muted.toString() === '1' ? ' muted' : ''}
595              ${showControls ? ' controls' : '' }
596              poster="${videothumb}"
597            ></video>
598          </div>`,
599					'<iframe '+ opacity +' width="100%" frameborder="0" allow="autoplay" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" src="' + url + '"></iframe>'
600				]
601				const parentEle = Utilts.ins().getParentsByAttr($el, 'package-item', 'unit')
602				let swiperContainerEle = ''
603				let swiperHeight
604				if (parentEle && parentEle.length) {
605					swiperContainerEle = parentEle[0].querySelector('.swiper-container')
606					swiperHeight = parentEle[0].offsetHeight
607				}
608				if (this.method === '2') {
609					let videoHtml;
610					let iframeUrl = []
611					if (isIframe) {
612						iframeUrl = globalThis.Server.iframeAutoplay(url).split('<iframe')
613						videoHtml = `<iframe style="filter:brightness(${showMask?config.opacity:'1'})"`+iframeUrl[1]
614					} else if (isMp4) {
615						videoHtml = videoList[0]
616					} else {
617						videoHtml = globalThis.Server.iframeAutoplay(videoList[1])
618					}
619					const stopPlay = (e) => {
620						// 判断在选择隐藏文本与不轮播情况下不显示文本
621						if (!swiperContainerEle.swiper && config.auto_hide == 1) {
622							// swiperContainerEle.querySelector('.unit-list__text').style.opacity = 0
623              $el.closest('.unit-list__item').classList.add('hide-videotext')
624						}
625						if (!swiperContainerEle.swiper) return
626						if (swiperContainerEle) swiperContainerEle.swiper.autoplay.stop()
627						// 轮播模式下是否自动隐藏文本的判断,上面是非轮播模式,不冲突
628						if (parseInt(config.auto_hide) === 1) {
629							// swiperContainerEle.swiper.slides[swiperContainerEle.swiper.activeIndex].querySelector('.unit-list__text').style.opacity = 0
630              $el.closest('.unit-list__item').classList.add('hide-videotext')
631						}
632						// 调用play()方法进行自动播放
633						// swiperContainerEle.getElementsByTagName("video")[0].play()
634						e.target.play()
635					}
636					const startPlay = (e) => {
637						if (!swiperContainerEle.swiper && config.auto_hide == 1) {
638							// swiperContainerEle.querySelector('.unit-list__text').style.opacity = 1
639              $el.closest('.unit-list__item').classList.remove('hide-videotext')
640						}
641						if (!swiperContainerEle.swiper) return
642						// 如果配置不需要自动轮播,则不再恢复自动轮播
643						if (swiperContainerEle && this.config.swiper.autoplay !== '0') swiperContainerEle.swiper.autoplay.start()
644            if (parseInt(config.auto_hide) === 1) {
645              // swiperContainerEle.swiper.slides[swiperContainerEle.swiper.activeIndex].querySelector('.unit-list__text').style.opacity = 1
646              $el.closest('.unit-list__item').classList.remove('hide-videotext')
647            }
648					}
649          const resetVideo = $el.resetVideo = () => {
650            const $preview = $el.querySelector('.base-video__preview')
651            const $video = $el.querySelector('.base-video__preview video')
652            const $replayWrap = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--replay')
653            if ($preview) {
654              const videoWrapDom = $preview.querySelector('.base-video__wrap')
655              if (!this.config.swiper.is_swiper) {
656                $replayWrap.style.display = 'flex'
657                $video.controls = false
658                return
659              }
660              if (videoWrapDom) {
661                videoWrapDom.remove()
662              }
663              $preview.querySelectorAll('video, iframe').forEach(video => {
664                if (video instanceof HTMLVideoElement) {
665                  video.removeEventListener("ended", resetVideo)
666                }
667                video.remove()
668              })
669              $preview.classList.remove('play')
670            }
671          }
672					// 当前播放
673					const playVideo = $el.playVideo = () => {
674						const videothumb = $el.querySelector('.base-video__thumb img')
675            const videotDom = $el.querySelector('.base-video__preview video')
676            var videoPoster = videothumb && (videothumb.currentSrc || videothumb.getAttribute('src') || videothumb.getAttribute('lazy-src'))
677			if(!!videoPoster){
678				videoPoster= globalThis.Server.getTransferImgUrl(videoPoster, {convert: {quality: 80, dst: 'webp'}}, 'webp');
679			}
680            const $preview = $el.querySelector('.base-video__preview')
681            const $videos = $preview.querySelectorAll('video, iframe')
682            $preview.classList.add('play')
683            // $el.getAttribute('videoscale') && $el.classList.add('base-video--scale')
684            $el.classList.add('play')
685            if ($preview && !$videos.length) {
686              const template = document.createElement('template')
687              template.innerHTML = videoHtml
688              const videos = Array.from(template.content.children)
689              videos.forEach(video => {
690                $preview.insertAdjacentElement('beforeend', video)
691              })
692            }
693            if (this.$carouselEl.swiper) {
694              this.$carouselEl.swiper.autoplay.stop()
695            }
696						if (videothumb && videotDom) {
697							let videoPoster = videothumb.getAttribute('src') || videothumb.getAttribute('lazy-src')
698							videoPoster = globalThis.Server.getTransferImgUrl(videoPoster, {convert: {quality: 80, dst: 'webp'}}, 'webp');
699							videotDom.poster = videoPoster
700						}
701						$el.querySelector('.base-video__preview').classList.add('play')
702						// $el.getAttribute('videoscale') && $el.classList.add('base-video--scale')
703						$el.classList.add('play')
704            const closeBtn = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--close')
705            const replayBtn = $el.querySelector('.base-video__preview').querySelector('.replay-icon')
706            if (showControls && closeBtn) {
707              const closeVideo = (event) => {
708                event.stopPropagation()
709                event.preventDefault()
710                const videoWrapDom =  $el.querySelector('.base-video__preview').querySelector('.base-video__wrap')
711                if (videoWrapDom) {
712                  videoWrapDom?.remove()
713                  $el.querySelector('.base-video__preview')?.classList.remove('play')
714                  const gifHoverImages = $el.querySelector('.unit-list-hover__image')
715                  const h_dom = $el.querySelector('.unit-list-hover__image')
716                  h_dom && h_dom.classList.remove('d-none')
717                  gifHoverImages && gifHoverImages?.classList.remove('d-none')
718                  $el.classList.remove('play')
719                }
720								$el.querySelector('.unit-list-hover__image')?.classList.remove('d-none')
721              }
722              closeBtn.addEventListener('click', closeVideo, { once: true })
723            }
724            // console.log('auto_reset', this.config.video.auto_reset)
725            // if (showControls && replayBtn && this.config.video.auto_reset !== '1') {
726            if (showControls && replayBtn ) {
727              const videoDom = $el.querySelector('.base-video__wrap video')
728              const replayWrapDom = $el.querySelector('.base-video__preview').querySelector('.base-video__wrap--replay')
729              // console.log('videoDom', videoDom)
730              const showReplayBtn = (event) => {
731                event.stopPropagation()
732                event.preventDefault()
733                if(replayWrapDom) {
734                  replayWrapDom.style.display = 'flex'
735                  videoDom.controls = false
736                }
737								// 当不设置循环播放,视频重播回到封面图页面。并且图标使用最新设计的图标
738								if (config.loop.toString() !== '1') {
739									closeBtn.click()
740								}
741              }
742              videoDom?.addEventListener('ended', showReplayBtn)
743              const replay = (event) => {
744                event.stopPropagation()
745                event.preventDefault()
746                videoDom.currentTime = 0
747                videoDom.play()
748                replayWrapDom.style.display = 'none'
749                videoDom.controls = true
750              }
751              replayBtn?.addEventListener('click', replay)
752            }
753						let myVideo = $el.querySelectorAll('video')
754            const swiperAutoplay = parseInt(this.config.swiper.autoplay || '0')
755						myVideo.forEach(elVideo => {
756              if (videoPoster) {
757                elVideo.poster = videoPoster
758              }
759              elVideo.removeEventListener('play', stopPlay)
760							elVideo.addEventListener('play', stopPlay)
761							elVideo.removeEventListener('pause', startPlay)
762							elVideo.addEventListener('pause', startPlay)
763              if (this.config.video.auto_reset > 0) {
764                elVideo.removeEventListener("ended", resetVideo);
765                if (swiperAutoplay === 0) {
766                  // 自动轮播的情况下,视频播放结束不自动重置
767                  elVideo.addEventListener("ended", resetVideo, {once: true});
768                }
769              }
770              if (swiperAutoplay > 0 && !elVideo._eventSlideNext) {
771                elVideo._eventSlideNext = slideNext
772                elVideo.addEventListener("ended", slideNext, {once: true});
773              }
774						})
775						// if (myVideo) {
776						// 	myVideo.removeEventListener('play', stopPlay)
777						// 	myVideo.addEventListener('play', stopPlay)
778						// 	myVideo.removeEventListener('pause', startPlay)
779						// 	myVideo.addEventListener('pause', startPlay)
780						// 	if (this.config.video.auto_reset > 0) {
781						// 		myVideo.removeEventListener("ended", resetVideo);
782						// 		myVideo.addEventListener("ended", resetVideo);
783						// 	}
784						// }
785					}
786					const clickPlayVideo = (e) => {
787            e.stopPropagation()
788            e.stopImmediatePropagation()
789            if (!$el.querySelector('.base-video__preview').classList.contains('play')) {
790							// 有视频
791							// e.preventDefault()
792              playVideo()
793						}
794
795						// if (/\.mp4(\?|$)/.test(url) && window.app.utilts.checkScreenMobile()) {
796						// 	// 手机端
797						// 	$el.querySelector('video').requestFullscreen()
798						// }
799            return false
800					}
801					if (config.autoplay.toString() === '1' && /\.mp4(\?|$)/i.test(url) && $el.querySelector('.base-video__preview').classList.value.indexOf('play') === -1) {
802						// 自动播放
803						playVideo()
804						// if (this.config.video.auto_reset > 0) {
805							$el.addEventListener('click', clickPlayVideo, {useCapture: false})
806						// }
807					} else {
808						// 手动播放
809						if (isIframe) {
810							videoHtml = this.config.default_src ? videoHtml : globalThis.Server.iframeAutoplayClear(videoHtml, config.muted && config.muted.toString() === '1')
811						}
812						$el.addEventListener('click', clickPlayVideo, {useCapture: false})
813					}
814				} else {
815					let isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
816					$el.addEventListener('click', (e) => {
817						e.preventDefault()
818						const videothumb = $el.querySelector('.base-video__thumb img')
819						let videoPopupNode = document.getElementById('video-popup')
820						function closeVideoPopupNode() {
821              videoPopupNode.classList.remove("show")
822              videoPopupNode.getElementsByTagName("video")[0].pause()
823							videoPopupNode.innerHTML = ''
824							videoPopupNode.remove()
825            }
826						if (!videoPopupNode || videoPopupNode.innerHTML === '') {
827							videoPopupNode = document.createElement('div')
828							videoPopupNode.innerHTML = `
829							<div class="unit-video-popup__window">
830								<div class="unit-video-popup__close">×</div>
831								<div class="unit-video-popup__content">${videoList.join('')}</div>
832							</div>`
833
834							videoPopupNode.setAttribute('id', 'video-popup')
835							videoPopupNode.className = "unit-video-popup__window-wrap"
836							videoPopupNode.getElementsByClassName("unit-video-popup__close")[0].addEventListener('click', closeVideoPopupNode)
837							document.body.appendChild(videoPopupNode)
838						}
839						let $popupVideo = videoPopupNode.getElementsByTagName("video")[0];
840						if (isIframe) {
841							videoPopupNode.getElementsByTagName("iframe")[0].outerHTML = globalThis.Server.iframeAutoplay(url)
842							$popupVideo.src = ''
843							$popupVideo.style.display = 'none'
844						} else if (isMp4) {
845							let video = videoPopupNode.querySelector("video")
846							if (!video) {
847								videoPopupNode.innerHTML = `<div class="unit-video-popup__window"><div class="unit-video-popup__close">×</div><div class="unit-video-popup__content">${videoList.join('')}</div></div>`
848								videoPopupNode.querySelector(".unit-video-popup__close").addEventListener('click', function () {
849									videoPopupNode.classList.remove("show")
850									videoPopupNode.querySelector("video").pause()
851								})
852							}
853							video = videoPopupNode.querySelector("video")
854							let iframe = videoPopupNode.querySelector("iframe")
855							video.src = url
856							video.style.display = 'block'
857							if (videothumb) {
858								let videoPoster = videothumb.getAttribute('src') || videothumb.getAttribute('lazy-src')
859								videoPoster = globalThis.Server.getTransferImgUrl(videoPoster, {convert: {quality: 80, dst: 'webp'}}, 'webp');
860								video.poster = videoPoster
861							}
862							if (iframe) {
863								iframe.src = ''
864								iframe.style.display = 'none'
865							}
866							$popupVideo = $popupVideo || video
867              const $replay = videoPopupNode.querySelector('.base-video__wrap--replay')
868              if (showControls && $replay) {
869                const showReplayBtn = (event) => {
870                  event.stopPropagation()
871                  event.preventDefault()
872                  if($replay) {
873                    $replay.style.display = 'flex'
874                    $popupVideo.controls = false
875                  }
876                }
877                $popupVideo?.addEventListener('ended', showReplayBtn)
878                const replay = (event) => {
879                  event.stopPropagation()
880                  event.preventDefault()
881                  $popupVideo.currentTime = 0
882                  $popupVideo.play()
883                  $replay.style.display = 'none'
884                  $popupVideo.controls = true
885                }
886                $replay?.addEventListener('click', replay)
887              }
888							if (window.app.utilts.checkScreenMobile()) {
889								const showPopupVideo = (show) => {
890									if (show) {
891										videoPopupNode.style.zIndex = ''
892										videoPopupNode.style.opacity = ''
893									} else {
894										videoPopupNode.style.zIndex = -1
895										videoPopupNode.style.opacity = 0
896									}
897                }
898								if (isiOS) {
899									$popupVideo.style['aspect-ratio'] = '16 / 9';
900									$popupVideo.style['height'] = '56.25vw';
901									$popupVideo.addEventListener('webkitendfullscreen', () => {
902										closeVideoPopupNode()
903										$popupVideo.style['aspect-ratio'] = '';
904                    $popupVideo.style['height'] = 'auto';
905									})
906									let hanlder = function() {
907										// 视频缓冲完毕
908										if (videoPopupNode.classList.contains('show')) {
909											$popupVideo.webkitEnterFullscreen()
910										}
911										$popupVideo.removeEventListener('canplaythrough', hanlder);
912									}
913									$popupVideo.addEventListener('canplaythrough', hanlder);
914                } else {
915                  $popupVideo.requestFullscreen().then(() => {
916                    // 全屏成功
917                    showPopupVideo(0)
918										let tempScrollY = window.scrollY
919                    function updateFullscreenStatus() {
920                      if (document.fullscreenElement !== $popupVideo) {
921                        window.scrollTo(0, tempScrollY);
922												closeVideoPopupNode()
923                        showPopupVideo(1)
924                      }
925                    }
926                    $popupVideo.addEventListener('fullscreenchange', updateFullscreenStatus);
927                  })
928                }
929              }
930							// if (window.app.utilts.checkScreenMobile()) {
931							// 	if (isiOS) {
932							// 		setTimeout(() => { videoPopupNode.getElementsByTagName("video")[0].webkitEnterFullscreen() }, 500)
933							// 	} else {
934							// 		videoPopupNode.getElementsByTagName("video")[0].requestFullscreen()
935							// 	}
936							// }
937						} else {
938							videoPopupNode.getElementsByTagName("iframe")[0].src = url
939							videoPopupNode.getElementsByTagName("iframe")[0].style.display = 'block'
940							$popupVideo.src = ''
941							$popupVideo.style.display = 'none'
942						}
943						videoPopupNode.classList.add('show')
944					})
945				}
946			}
947		})
948	}
949
950	initResize() {
951		if (!this.config.resize?.is_resize) return
952
953		const $container = this.$unitList.querySelector('.resize-container')
954		if (!$container) return
955		const $wrapper = $container.querySelector('.unit-list__items')
956		const $firstItem = $wrapper.firstElementChild
957		const $firstItemInner = $firstItem.querySelector('.unit-list__item-inner')
958		const $laseItem = $wrapper.lastElementChild
959		// const $firstImg = $firstItem.querySelector('.base-image__img')
960		// const $firstText = $firstItem.querySelector('.unit-list__text')
961		const $splitLine = $container.querySelector('.unit-list__split-line')
962
963		let direction = this.config.resize?.direction || 'x';
964		let offsetX = 0;
965		let offsetY = 0;
966
967		// $firstText.setAttribute('style', `width:${$container.offsetWidth * 0.5}px;`)
968		if (direction === 'x') {
969			$firstItemInner.setAttribute('style', `width:${$container.offsetWidth}px;max-width:${$container.offsetWidth}px`)
970			// 监听 container 尺寸变化
971			var observer = new ResizeObserver(function (entries) {
972				entries.forEach(function (entry) {
973					if (entry.target === $container) {
974						// 获取宽度
975						const width = entry.contentRect.width;
976						$firstItemInner.setAttribute('style', `width:${width}px;max-width:${width}px`)
977					}
978				});
979			});
980			// 监听目标元素的宽度变化
981			observer.observe($container);
982		}
983
984		function startDrag(event) {
985			event.preventDefault()
986
987			offsetX = $container.getBoundingClientRect().left;
988			offsetY = $container.getBoundingClientRect().top;
989			document.addEventListener('mouseup', stopDrag)
990			document.addEventListener('mousemove', drag)
991
992			document.addEventListener('touchend', stopDrag)
993			document.addEventListener('touchmove', drag, {
994				passive: false, // 阻止默认滚动行为
995			})
996		}
997
998		function stopDrag(event) {
999			event.preventDefault()
1000
1001			document.removeEventListener('mousemove', drag)
1002			document.removeEventListener('mouseup', stopDrag)
1003
1004			document.removeEventListener('touchmove', drag)
1005			document.removeEventListener('touchend', stopDrag)
1006		}
1007
1008		function drag(event) {
1009			event.preventDefault()
1010			requestAnimationFrame(() => {
1011				if (direction === 'x') {
1012					let containerLeft = $container.getBoundingClientRect().left;
1013					let containerWidth = $container.offsetWidth;
1014					let clientX = 'touches' in event ? event.touches[0].clientX : event.clientX
1015					let x = clientX - offsetX;
1016					// 将拖拽区域限制在容器内部
1017					if (clientX < containerLeft) {
1018						// console.log('左边超出');
1019						x = 0;
1020					}
1021					if (clientX > containerLeft + containerWidth - $splitLine.offsetWidth) {
1022						// console.log('右边超出');
1023						x = containerWidth - $splitLine.offsetWidth
1024					}
1025					$splitLine.style.left = x + "px";
1026					$firstItem.setAttribute('style', `width:${x}px`)
1027					$laseItem.setAttribute('style', `clip-path: inset(0 0 0 ${x}px)`) // fix:透明背景,图片重叠
1028				} else {
1029					let containerTop = $container.getBoundingClientRect().top
1030					let containerHeight = $container.offsetHeight;
1031					let clientY = 'touches' in event ? event.touches[0].clientY : event.clientY
1032					let y = clientY - offsetY;
1033					// 将拖拽区域限制在容器内部
1034					if (clientY < containerTop) {
1035						y = 0;
1036					}
1037					if (clientY > containerTop + containerHeight - $splitLine.offsetHeight) {
1038						y = containerHeight - $splitLine.offsetHeight;
1039					}
1040					$splitLine.style.top = y + "px";
1041					$firstItem.setAttribute('style', `height:${y}px`)
1042					$laseItem.setAttribute('style', `clip-path: inset(${y}px 0 0 0)`)
1043				}
1044			})
1045		}
1046
1047		$splitLine.onmousedown = startDrag;
1048		$splitLine.ontouchstart = startDrag;
1049	}
1050
1051	initLink() {
1052		// 解决.unit-list__text的空白区域点击
1053		const $textContainerList = this.$unitList.querySelectorAll('.unit-list__text[data-href]')
1054
1055		for (const item of $textContainerList) {
1056			const dataHref = item.getAttribute('data-href')
1057			if (item.parentNode.querySelector('.unit-list__video')) {
1058        const $baseVideo = item.parentNode.querySelector('.base-video')
1059        const $preview = item.parentNode.querySelector('.base-video__preview')
1060				item.style.cursor = 'pointer'
1061				item.addEventListener('click', (e) => {
1062          const clickBtn = e.target.closest('.btn') || e.target.classList.contains('btn')
1063					if (e.target.tagName !== 'A' && !clickBtn) {
1064            if (!$preview.classList.contains('play')) {
1065              $baseVideo.playVideo()
1066            }
1067						// item.parentNode.querySelector('.base-video__play').click()
1068					}
1069				})
1070			} else if (!this.utilts.checkDesign()) {
1071				if (dataHref.startsWith('javascript')) continue
1072				item.style.cursor = 'pointer'
1073				item.addEventListener('click', (e) => {
1074          e.stopPropagation()
1075          e.stopImmediatePropagation()
1076					const link = e.target.closest('a[href]');
1077					if (link && link.href && !link.href.startsWith('javascript')) {
1078						e.stopPropagation();
1079						return false;
1080					}
1081					let target = item.getAttribute('data-target')
1082					if (target !== 'block') {
1083						window.open(dataHref, target || '_self')
1084					}
1085				})
1086			}
1087		}
1088	}
1089}
1090
1091/**
1092 * 客户端数据html
1093 */
1094class ScriptListElement {
1095	constructor({ attrId, pageInfo, colInfo, config, open_hover }) {
1096		this.open_hover = open_hover
1097		this.attrId = attrId
1098		this.pageInfo = pageInfo
1099		this.is_swiper = config.swiper.is_swiper
1100		this.colInfo = colInfo
1101		this.config = config
1102		this.init()
1103	}
1104
1105	init() {
1106		this.getMainHtml()
1107	}
1108
1109	getMainHtml() {
1110		this.$container = document.createElement('div')
1111		this.$container.classList.add('swiper-container')
1112		this.$items = this.getItems()
1113		this.$container.append(this.$items)
1114		this._setSwiperNode()
1115	}
1116
1117	getItems() {
1118		const $items = document.createElement('div')
1119		$items.classList.add('unit-list__items', 'swiper-wrapper')
1120		if (!this.is_swiper) $items.classList.add('row')
1121		if (this.is_swiper && !this.swiper.pagination) $items.classList.add('no-swiper-pagination')
1122		return $items
1123	}
1124
1125	/** 获取产品列表项 **/
1126	getItem(item) {
1127		const $item = document.createElement('div')
1128		$item.setAttribute('data-id', item.content_id)
1129		$item.classList.add('animate', 'unit-list__item', 'swiper-slide')
1130		if (!this.is_swiper) {
1131			$item.classList.add(`col-${this.colInfo.cols_col}`)
1132			$item.classList.add(`col-md-${this.colInfo.cols_md}`)
1133			$item.classList.add(`col-xl-${this.colInfo.cols_xl}`)
1134		}
1135		const $listA = document.createElement('div')
1136		$listA.classList.add('unit-list__a')
1137		$listA.append(this.getItemContent(item))
1138		$item.append($listA)
1139
1140		return $item
1141	}
1142	/** 获取产品列表项内容 **/
1143	getItemContent(item) {
1144		const $listInner = document.createElement('div')
1145		$listInner.classList.add('unit-list__item-inner', 'd-flex', 'flex-column')
1146		$listInner.append(this.getLinkImage(item))
1147		$listInner.append(this.getLinkText(item))
1148		return $listInner
1149	}
1150
1151	/**
1152	 * 按钮节点
1153	 */
1154	getLinkImage(item) {
1155		const hoverImgEffect = (this.open_hover || '').replace(/[^A-Za-z0-9,_-]/g, '').split(',')
1156		const hoverImgIn = hoverImgEffect[0] || ''
1157		const hoverImgOut = hoverImgEffect[1] || ''
1158		const hoverImgDuration = hoverImgEffect[2] || ''
1159		const self = this
1160		const subNode = {
1161			//
1162			get baseImage() {
1163				let scale = ''
1164				let effect = 0
1165				if (self.config.image) {
1166					scale = self.config.image.scale || ''
1167					if (scale) scale = Number(scale) * 100 + '%'
1168					effect = self.config.image.effect
1169				}
1170				return `
1171					<div class="base-image ${scale ? 'base-image--scale' : ''} ${effect ? 'base-image--effect-' + effect : ''}" ${scale ? 'style="--img-pt: ' + scale + '"' : ''}>
1172						<div class="base-image__item hover_img_origin base-image__item--default">
1173							<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">
1174						</div>
1175					</div>`
1176			},
1177		}
1178
1179		const $imgBoxs = document.createElement('a')
1180		$imgBoxs.classList.add('unit-list__image')
1181		const href = globalThis.Server.getRinseHref(item.href || 'javascript:;', window.app.info.site)
1182		$imgBoxs.setAttribute('href', href)
1183		$imgBoxs.setAttribute('target', item.target || '_self')
1184
1185		if (item.cover_url && this.config.video.icon === '1') {
1186			const videoNode = document.createElement('div')
1187			videoNode.classList.add('base-video__play')
1188			videoNode.innerHTML = `<i class="iconfont icon-action-play"></i>`
1189			$imgBoxs.appendChild(videoNode)
1190		}
1191
1192		// 产品图片
1193		const $baseImg = document.createElement('div')
1194		// console.log('item*---list', item);
1195		$baseImg.classList.add('unit-list__img')
1196		$baseImg.setAttribute('content-render', 'product_hover,video_icon')
1197		$baseImg.setAttribute('content-type', item.content_type)
1198		$baseImg.setAttribute('content-id', item.content_id);
1199		(item.hover_img || self.config.hover_img) && $baseImg.setAttribute('open-hover', this.open_hover || '')
1200		$baseImg.innerHTML = subNode.baseImage
1201		$imgBoxs.append($baseImg)
1202		return $imgBoxs
1203	}
1204
1205	/**
1206	 * 标题描述,价格
1207	 */
1208	getLinkText(item) {
1209		const self = this
1210		const getShowContent = (className, item, textStyle, title) => {
1211			const $titleBox = document.createElement('div')
1212			$titleBox.classList.add(`unit-list__${className}`)
1213			$titleBox.setAttribute('text-style', textStyle || '')
1214
1215			let $textBox
1216			if (className === 'title') {
1217				$textBox = document.createElement('a')
1218				const href = globalThis.Server.getRinseHref(item.href || 'javascript:;', window.app.info.site)
1219				$textBox.setAttribute('href', href)
1220				$textBox.setAttribute('target', item.target || '_self')
1221			} else {
1222				$textBox = document.createElement('div')
1223			}
1224			$textBox.classList.add('text_ellipsis')
1225			$textBox.setAttribute('_html', item[className + '_sign'] || '')
1226			$textBox.setAttribute('toolbar', 'false')
1227			$textBox.innerHTML = item[className]
1228			$titleBox.append($textBox)
1229
1230			return $titleBox
1231		}
1232		const subNode = {
1233			get priceInfo() {
1234				const min = `<div class="unit-list__price-min"><i>$</i><span>${item.price_min}</span></div>`
1235				let max = ''
1236				if (item.price_max > 0) {
1237					max = `<div class="unit-list__price-max"><i>$</i><span>${item.price_max}</span></div>`
1238				}
1239				return `${min}${max}`
1240			},
1241			get listExtend() {
1242				const noPrice = `
1243						<div class="unit-list__cart text-capitalize">
1244							<i class="iconfont icon-base-cart-lighter"></i>
1245							<a href="${globalThis.Server.getRinseHref(item.href, window.app.info.site)}" target="${item.target || '_self'}">${window.app.utilts.$t('Add to cart')}
1245 </a>
1246						</div>
1247						<div class="unit-list__inquire text-capitalize">
1248							<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>
1249						</div>`
1250				let like = ''
1251				if (self.config.show_like) {
1252					like = `
1253						<div class="unit-list__like" title="${window.app.utilts.$t('Like')}" pro-id="${item.id}">
1254								<i class="iconfont icon-base-collect"></i>
1255						</div>`
1256				}
1257				return `${noPrice}${like}`
1258			}
1259		}
1260
1261		const $textBox = document.createElement('div')
1262		$textBox.classList.add('unit-list__text')
1263
1264		const $textInner = document.createElement('div')
1265		$textInner.classList.add('unit-list__text-inner')
1266
1267		const $content = document.createElement('div')
1268		$content.classList.add('unit-list__content')
1269
1270		$textInner.append($content)
1271		$textBox.append($textInner)
1272
1273		// 标题
1274		if (this.config.show_title && item.title && this.config.has_title) {
1275			const style_title = self.config.style_type_title
1276			const $title = getShowContent('title', item, style_title)
1277			$content.append($title)
1278		}
1279		// 子标题
1280		if (this.config.show_subtitle && item.subtitle && this.config.has_subtitle) {
1281			const style_subtitle = self.config.style_type_subtitle
1282			const $subtitle = getShowContent('subtitle', item, style_subtitle)
1283			$content.append($subtitle)
1284		}
1285		// 描述
1286		if (this.config.show_description && item.description && this.config.has_description) {
1287			const style_description = self.config.style_type_description
1288			const $description = getShowContent('description', item, style_description)
1289			$content.append($description)
1290		}
1291
1292		// ä»·æ ¼
1293		if (this.config.show_read_more) {
1294			const $pricesBox = document.createElement('div')
1295			$pricesBox.classList.add('unit-list__product')
1296			if (Number(item.price_min) <= 0) $pricesBox.classList.add('no-price')
1297
1298			const $listPrice = document.createElement('div')
1299			$listPrice.classList.add('unit-list__price')
1300			$listPrice.innerHTML = subNode.priceInfo
1301			$pricesBox.append($listPrice)
1302
1303			const $extend = document.createElement('div')
1304			$extend.classList.add('unit-list__extend')
1305			$extend.innerHTML = subNode.listExtend
1306			$pricesBox.append($extend)
1307
1308			$textInner.append($pricesBox)
1309		}
1310		if (this.config.show_quote_list == '1') {
1311			$textBox.append(this.getQuoteBtn(item))
1312		}
1313		return $textBox
1314	}
1315
1316	getQuoteBtn(item) {
1317		const self = this
1318		const $content = document.createElement('div')
1319		$content.classList.add('unit-list__quote')
1320		$content.setAttribute("content-id", item.content_id)
1321		const $addBtn = document.createElement('div')
1322		$addBtn.classList.add('unit-list__quoteAdd')
1323		$addBtn.innerHTML = `<i class="iconfont icon-action-add"></i>
1324                        <span>${window.app.utilts.$t('Add to Quote List')}</span>`
1325		const $listBtn = document.createElement('a')
1326		$listBtn.classList.add('unit-list__quoteList')
1327		$listBtn.innerHTML = ` <div>
1328                            ${window.app.utilts.$t('Browse the list')} →
1329                        </div>`
1330		$content.append($addBtn)
1331		$content.append($listBtn)
1332		return $content
1333	}
1334	/** **/
1335	_setSwiperNode() {
1336		if (this.config.swiper) {
1337			if (this.config.swiper.pagination) {
1338				const $div1 = document.createElement('div')
1339				$div1.classList.add('unit-product-list__pagination', 'swiper-pagination')
1340				this.$container.append($div1)
1341			}
1342			if (this.config.swiper.navigation) {
1343				const $div2 = document.createElement('div')
1344				$div2.classList.add('unit-product-list__button-prev', 'swiper-button-prev')
1345				this.$container.append($div2)
1346				const $div3 = document.createElement('div')
1347				$div3.classList.add('unit-product-list__button-next', 'swiper-button-next')
1348				this.$container.append($div3)
1349			}
1350			if (this.config.swiper.scrollbar) {
1351				const $div4 = document.createElement('div')
1352				$div4.classList.add('unit-product-list__scrollbar', 'swiper-scrollbar')
1353				this.$container.append($div4)
1354			}
1355		}
1356	}
1357}

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.