PageSourceSearch

https://www.samaterials.es/js/header.js?v=1788571303

js samaterials.es collected 2026-10-02 20:46:53 UTC 38,612 bytes, 1,265 lines download raw bytes

1// Cookie
2
3initCheckWebAndJump()
4
5/**
6 * Generates a styled HTML string for a cookie consent dialog box.
7 * The dialog box includes a notice about the use of cookies and
8 * provides options for the user to accept or deny cookie usage.
9 * The dialog is styled to be responsive and includes a mask
10 * and container with buttons for user interaction.
11 *
12 * @returns {string} A string containing HTML and CSS for displaying
13 *                   a cookie consent dialog box.
14 */
15function dialogBox () {
16  return `<style>
17    #ip-container-box{
18        box-sizing: border-box;
19    }
20    .ip-mask {
21        width: 100%;
22        height: 100%;
23        opacity: .5;
24        background: #000;
25        top: 0px;
26        box-sizing: border-box;
27        position: fixed;
28        z-index: 552;
29    }
30    .ip-container {
31        padding: 20px;
32        border-radius: 6px;border: 0.5px solid #ccc;
33        box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .25);
34        position: fixed;
35        background: white;
36        bottom: 0;
37        box-sizing: border-box;
38        display: flex;
39        justify-content: space-between;
40        gap: 40px;
41        width: 100%;
42        z-index: 553;
43        align-items: center;
44    }
45    .ip-container .ip-close-icon {
46        position: absolute;
47        right: 4px;
48        top: 3px;
49        cursor: pointer;
50    }
51
52    .ip-container .ip-notice {
53        max-width: 70%;
54    }
55
56    .ip-container .ip-notice .ip-text {
57        font-size: 16px;
58    }
59
60    .ip-container .ip-handle {
61        display: flex;
62        gap: 20px;
63        justify-content: space-around;
64        align-items: center;
65    }
66
67    .ip-container .ip-handle .ip-btn {
68        border-radius: 5px;
69        padding: 13px 55px;
70        min-width: 100px;
71        cursor: pointer;
72    }
73
74    .ip-container .ip-handle .ip-cancel {
75        background: #fff;
76        border: 1px solid #dcdfe6;
77        color: #606266;
78    }
79
80    .ip-container .ip-handle .ip-ok {
81        background: #2F67B3;
82        border: 1px solid #2F67B3;
83        color: #FFFFFF;
84    }
85    @media screen and (max-width: 1000px) {
86        .ip-container .ip-notice {
87            max-width: 100%;
88        }
89        .ip-container {
90            flex-direction: column;
91        }
92        .ip-container .ip-handle .ip-btn {
93            transform: scale(1.2);
94        }
95    }
96</style>
97<div id="ip-container-box">
98    <div class="ip-mask"></div>
99    <div class="ip-container">
100        <div class="ip-notice">
101            <div class="ip-text">
102                We use cookies to make our website work better and improve your experience. By continuing to use the site, you agree to our <a href="https://www.samaterials.com/content/privacy-policy.html" style="display:inline;">Privacy Policy.</a>
103            </div>
104        </div>
105        <div class="ip-handle">
106            <button class="ip-cancel ip-btn" onclick="closeDialog();">Decline</button>
107            <button class="ip-ok ip-btn" onclick="acceptCookie();">Allow</button>
108        </div>
109    </div>
110</div>`
111}
112
113/**
114 * Closes the cookie consent dialog box and stores the user's cookie consent status in local storage as false.
115 */
116function closeDialog () {
117  document.getElementById('ip-container-box').style.display = 'none'
118  storeCookie(false)
119}
120
121/**
122 * Closes the cookie consent dialog box and stores the user's cookie consent status in local storage as true.
123 */
124function acceptCookie () {
125  document.getElementById('ip-container-box').style.display = 'none'
126  storeCookie(true)
127}
128
129/**
130 * Stores the user's cookie consent status in local storage.
131 * @param {boolean} status - The status of cookie consent, where true indicates consent given and false indicates consent denied.
132 */
133function storeCookie (status) {
134  localStorage.setItem('use_cookie', status)
135}
136
137/**
138 * Determine if the country code is in Europe region.
139 * @param {string} country_code Country code in ISO 3166-1 alpha-2 format.
140 * @returns {boolean} true if the country code is in Europe region.
141 */
142function isEurope (country_code) {
143  const EUROPE_COUNTRY_CODE = [
144    // 西欧
145    'AT',
146    'BE',
147    'FR',
148    'DE',
149    'LI',
150    'LU',
151    'MC',
152    'NL',
153    'CH',
154    // 北欧
155    'DK',
156    'FI',
157    'IS',
158    'NO',
159    'SE',
160    // 南欧
161    'AL',
162    'AL',
163    'AD',
164    'BA',
165    'HR',
166    'GR',
167    'IT',
168    'MT',
169    'ME',
170    'MK',
171    'PT',
172    'SM',
173    'RS',
174    'SI',
175    'ES',
176    'VA',
177    // 东欧
178    'BY',
179    'BG',
180    'CZ',
181    'HU',
182    'PL',
183    'RO',
184    'RU',
185    'SK',
186    'UA',
187    // 其他欧洲地区
188    'CY',
189    'TR',
190    'GB',
191    'IE',
192    'FO',
193    'GI',
194    'GG',
195    'IM',
196    'JE',
197  ]
198  if (EUROPE_COUNTRY_CODE.indexOf(country_code) !== -1) {
199    return true
200  } else {
201    return false
202  }
203}
204
205/**
206 * Jump to the corresponding European website based on the country code.
207 * Currently supported countries are Germany, France, Spain, Italy.
208 * @param {string} country_code - Country code, e.g. 'DE' for Germany.
209 */
210function jumpToEuropeWeb (country_code) {
211  var GermanyCode = ['DE', 'DEU']
212  var France = ['FR', 'FRA FR']
213  var Spain = ['ES', 'ESP EN', 'ESP']
214  var Italy = ['IT', 'ITA IT', 'ITA']
215  var currentLocation = location.origin
216  if (GermanyCode.indexOf(country_code) !== -1) {
217    // JumpTO DE
218    if (currentLocation != 'https://www.samaterials.de') {
219      window.location.href = 'https://www.samaterials.de'
220    }
221  } else if (France.indexOf(country_code) !== -1) {
222    // JumpTO FR
223    if (currentLocation != 'https://www.samaterials.fr') {
224      window.location.href = 'https://www.samaterials.fr'
225    }
226  } else if (Spain.indexOf(country_code) !== -1) {
227    // JumpTO ES
228    if (currentLocation != 'https://www.samaterials.es') {
229      window.location.href = 'https://www.samaterials.es'
230    }
231  } else if (Italy.indexOf(country_code) !== -1) {
232    // JumpTO IT
233    if (currentLocation != 'https://www.samaterials.it') {
234      window.location.href = 'https://www.samaterials.it'
235    }
236  } else {
237    console.log(country_code)
238  }
239}
240
241/**
242 * Displays a cookie consent dialog box if the user has not previously
243 * made a cookie consent selection. The function checks local storage
244 * for the user's cookie consent status and shows the dialog only if
245 * the status is not set to 'false' or 'true'.
246 */
247function showCookieDialog () {
248  // 如果已经用户选择过,此时就不在弹出对应的弹窗
249  var isCheck = localStorage.getItem('use_cookie')
250  if (isCheck != 'false' && isCheck != 'true') {
251    const modal = document.createElement('div')
252    modal.innerHTML = dialogBox()
253    document.body.appendChild(modal)
254  }
255}
256
257/**
258 * Checks the user's country and jumps to the corresponding website, then shows a cookie consent dialog box.
259 * If the user is from a European country, the function jumps to the corresponding website and shows the dialog box.
260 * If the user is from a non-European country, the function shows the dialog box on the current website.
261 * The function also stores the user's cookie consent status in local storage.
262 */
263function initCheckWebAndJump () {
264  fetch('https://api.ip.sb/geoip')
265    .then((res) => res.json())
266    .then((data) => {
267      // 欧洲国家展示对应弹窗,非欧国家不展示
268      // 1、DE ,FR, IT ,ES 这些国家的,如果进入到了 非这几个国家的站点,就直接默认跳转,在跳转后的网站出来个cookie弹窗
269      // 2、非DE ,FR, IT ,ES这几个国家的用户访问,任意的sam 站,就是访问哪个就是哪个,在访问的网站出来一个Cookie弹窗
270      if (!data || data.country_code) {
271        var currenyCountry = data.country_code
272        // 检验是否是欧洲国家
273        var isEuropeCountry = isEurope(currenyCountry)
274        if (isEuropeCountry) {
275          jumpToEuropeWeb(currenyCountry)
276          showCookieDialog()
277        }
278        return
279      }
280    })
281}
282
283window.lazyImg = lazyLoad({})
284var isMobile = null
285isMobileFun()
286window.addEventListener('resize', isMobileFun)
287function isMobileFun () {
288  let mobile = $(window).width() < 1025
289  if (isMobile != mobile) {
290    isMobile = mobile
291    var newSetItemEvent = new Event('switchingMobile')
292    newSetItemEvent.newValue = mobile
293    window.dispatchEvent(newSetItemEvent)
294    lazyImg.loadResources()
295    console.log('端切换')
296  }
297}
298// 预留自适应PRODUCT 导航高度方法
299// function updataMenuHeight() {
300// let menuHeight = $('.oc-main-sam-menu-item.special-menu .sub-menu
300-left').height()
301// console.log("导航栏高度", menuHeight);
302// document.querySelector(".oc-main-sam-menu-item.special-menu .thirdly-menu").style.height = menuHeight+"px"
303// }
304
305$(document).ready(function () {
306  initSamProductMenu()
307  try {
308    lazyImg.update()
309    // 加一个延迟5秒保险
310    setTimeout(() => {
311      lazyImg.update()
312    }, 5000)
313    console.log('LoadTime:', (new Date().getTime() - performance.timing.navigationStart) / 1000)
314  } catch (e) { }
315  // updataMenuHeight();
316  // window.addEventListener("switchingMobile", updataMenuHeight)
317  //跳转首页
318  $('.jump-home-page').click(function () {
319    window.location.href = TextPrompt.home_url
320  })
321
322  // pc导航鼠标移入显示下拉菜单
323  // 当鼠标进入.oc-main-sam-menu-item时显示对应的.sub-menu-wrapper
324  $('.oc-main-sam-menu').mouseenter(function () {
325    if ($(this).find('.sub-menu').length == 0) return
326    $(this).find('.sub-menu').show()
327    $('.menu-mask').addClass('show')
328  })
329
330  // 当鼠标离开.oc-main-sam-menu-item时隐藏对应的.sub-menu-wrapper
331  $('.oc-main-sam-menu').mouseleave(function () {
332    if ($(this).find('.sub-menu').length == 0) return
333    $(this).find('.sub-menu').hide()
334    $('.menu-mask').removeClass('show')
335  })
336
337  // 移动端导航
338  // 点击展开导航
339  $('.oc-main-sam-header-mobile .menu-btn').click(function () {
340    var dropdown = $('.oc-main-sam-header-nav-mobile')
341    dropdown.slideDown('fast')
342    $('body').css('overflow', 'hidden')
343  })
344  // 点击关闭导航
345  $('.oc-main-sam-header-nav-mobile .close-icon-wrapper').click(function () {
346    $('.oc-main-sam-header-nav-mobile').slideUp('fast')
347    $('body').css('overflow', '')
348  })
349  // 点击一级展开二级
350  $('.nav-content .first-nav .drop-down-icon').click(function () {
351    var secondNav = $(this).parent().next()
352    if (secondNav.css('display') == 'none') {
353      $(this).css({ transform: 'rotate(180deg)' })
354      $(this).css({ transform: 'rotate(180deg)' })
355      $(this).find('path').attr('fill', '#2C63A0');
356      secondNav.slideDown('fast')
357    } else {
358      $(this).css({ transform: 'rotate(0)' })
359      $(this).find('path').attr('fill', '#221C1C');
360      secondNav.slideUp('fast')
361    }
362  })
363
364  function showSearchInput () {
365    $('.oc-main-sam-header-input').css('display', 'flex');
366    $('.logo-wrapper').css('display', 'none');
367    $('.oc-main-sam-banner').css('marginTop', '1rem');
368    $('.oc-main-sam-header-input input').focus();
369  }
370
371  // 点击搜索图标触发搜索
372  $('.oc-main-sam-header-mobile .btn-wrapper .search-icon-wrapper').click(function () {
373    headerVm.handleSearch(event);
374  });
375
376  $('.oc-main-sam-header-search-input .search-btn').click(function () {
377    headerVm.handleSearch(event);
378  })
379
380  // 点击关闭图标关闭搜索
381  $('.oc-main-sam-header-mobile .oc-main-sam-header-input .close-icon-wrapper').click(function () {
382    $('.oc-main-sam-header-input').css('display', 'none')
383    // 清空搜索框内容
384    $('.oc-main-sam-header-input input').val('')
385
386    $('.logo-wrapper').css('display', 'flex')
387    $('.oc-main-sam-banner').css('marginTop', '1.4rem')
388  })
389
390
391  const header = document.querySelector('.oc-main-sam-header-pc')
392
393  let lastHeaderPcScrollTop = 0
394
395  window.addEventListener('scroll', function () {
396    const currentScrollTop = window.scrollY || document.documentElement.scrollTop
397
398    if (currentScrollTop > lastHeaderPcScrollTop) {
399      // 往下滚动 → 显示
400      header.classList.add('compact')
401    } else {
402      // 往上滚动 → 隐藏
403      header.classList.remove('compact')
404    }
405
406    lastHeaderPcScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop
407  })
408
409  let lastScrollTop = 0;
410  const mobileHeader = $('.oc-main-sam-header-mobile');
411  $(window).on('scroll', function () {
412    const scrollTop = $(this).scrollTop();
413    if (scrollTop > lastScrollTop && scrollTop > 50) {
414      // 向下滚动
415      mobileHeader.removeClass('show').addClass('hide');
416    } else {
417      // 向上滚动
418      mobileHeader.removeClass('hide').addClass('show');
419    }
420    lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
421  });
422
423  // 打开弹窗
424  $('.main-sam-search-icon').click(function () {
425    $('.oc-main-sam-header-search-modal').css('display', 'block')
426    $('.oc-main-sam-header-search-input').css('visibility', 'hidden')
427  })
428
429  // 关闭搜索弹窗
430  $('.close-search-model-btn').click(function () {
431    $('.oc-main-sam-header-search-modal').css('display', 'none')
432    $('.oc-main-sam-header-search-input').css('visibility', 'visible')
433  })
434
435  // 给多个表格添加父级div
436  const tables = document.querySelectorAll('table')
437
438  tables.forEach((table) => {
439    // 创建一个新的div元素
440    const divWrapper = document.createElement('div')
441    divWrapper.className = 'sam-table-wrapper'
442
443    // 获取表格的父级元素
444    const parentElement = table.parentNode
445
446    // 将新创建的div作为表格的兄弟元素插入到表格之前
447    parentElement.insertBefore(divWrapper, table)
448
449    // 将table元素作为子元素添加到新创建的div中
450    divWrapper.appendChild(table)
451  })
452})
453
454
455function initSamProductMenu () {
456  document.querySelectorAll('[data-sam-product-menu]').forEach(function (menu) {
457    var titles = menu.querySelectorAll('[data-sam-nav-key]')
458    var links = menu.querySelectorAll('.thirdly-menu [data-sam-nav-panel]')
459    if (!titles.length) return
460    function activate (id) {
461      var key = String(id)
462      titles.forEach(function (t) {
463        t.classList.toggle('sub-menu-active', t.getAttribute('data-sam-nav-key') === key)
464      })
465      links.forEach(function (a) {
466        a.hidden = a.getAttribute('data-sam-nav-panel') !== key
467      })
468    }
469    titles.forEach(function (t) {
470      t.addEventListener('mouseenter', function () {
471        activate(t.getAttribute('data-sam-nav-key'))
472      })
473    })
474  })
475}
476
477//
478var headerVm = new Vue({
479  el: '#sam-header-search',
480  components: {
481    ElCollapseTransition: ElCollapseTransition,
482  },
483  data: function () {
484    let { document } = TextPrompt || {}
485    return {
486      // 输入框绑定值
487      inputValue: '',
488      // 模糊搜索返回数据
489      searchDatas: [],
490      // 节流标志
491      shearchFlag: true,
492      pageIndex: 1,
493      pageSize: 10,
494      isLoading: false,
495      startY: 0, // 触摸开始时的Y坐标
496      currentY: 0, // 实时的Y坐标
497      isScrolling: false, // 是否正在滚动
498      isSearchFocus: false,
499      searchType: 'products',
500      isProductSearch: false,
501      hotSearch: {
502        total: 0,
503        popular: [],
504        popular_nums: 0,
505      },
506      //模糊查询接口Xhr
507      searchXhr: null,
508      // 搜索结果是纵向展示
509      isBulletColumnDisplay: true,
510      // 搜索结果是否横向展示
511      isBulletHorizontalDisplay: true,
512      documentList: [],
513      documentConfig: [
514        {
515          label: document.sds,
516          key: 'sds',
517        },
518        {
519          label: document.tds,
520          key: 'tds',
521        },
522        {
523          label: document.coa,
524          key: 'coa',
525        },
526        {
527          label: document.brochures,
528          key: 'brochure',
529        },
530      ],
531    }
532  },
533  computed: {
534    website () {
535      return this.languageFlag == 'en' ? 'sam' : 'sam_' + this.languageFlag
536    },
537    // 语言标识
538    languageFlag () {
539      return 'es'
540    },
541    langUrl () {
542      return this.languageFlag == 'en' ? '/' : '/' + this.languageFlag
543    },
544    // 判断输入框是否有值
545    isInput () {
546      if (this.inputValue.trim()) {
547        return true
548      } else {
549        return false
550      }
551    },
552    isSearchModle () {
553      if (this.searchType == 'document') {
554        return this.isSearchFocus && this.searchDatas.isValue
555      }
556      return this.isSearchFocus && this.searchDatas.length > 0
557    },
558    isLargeSearchBulletBox () {
559      let type = this.searchType
560      return type === 'application' || type === 'categories'
561    },
562    isPrductSearchBulletBox () {
563      let searchType = this.searchType
564      return searchType === 'products' || searchType === 'blog' || searchType === 'podcast'
565    },
566    searchPlaceholder () {
567      let types = TextPrompt.searchType || ''
568      // return types[this.searchType]
569      //     ? types.searchTypePlaceholder.replace(
570      //           "{name}",
571      //           types[this.searchType]
572      //       )
573      //     : types.searchPlaceholder;
574      return types.searchPlaceholder
575    },
576  },
577  watch: {
578    searchDatas (list) {
579      this.isSearchFocus
580      if (list.length > 0 && this.isLargeSearchBulletBox && this.$refs.searchResults) {
581        /**
582         * 先判断内容是否能单列纵向展示,如果溢出出现滚动条,则横向展示
583         * 若双列横向内容展示页溢出,则双列纵向展示
584         */
585        this.$nextTick(() => {
586          this.isBulletColumnDisplay = list.length < 9
587          // !this.hasScrollbar(this.$refs.searchColumnResults, false)
588
589          if (!this.isBulletColumnDisplay) {
590            this.isBulletHorizontalDisplay = true
591            setTimeout(() => {
592              this.isBulletHorizontalDisplay = !this.hasScrollbar(this.$refs.searchResults)
593            }, 100)
594          }
595        })
596      } else {
597        this.isBulletColumnDisplay = true
598        this.isBulletHorizontalDisplay = true
599      }
600    },
601  },
602  created () {
603    this.ajaxSetup()
604  },
605  mounted () {
606    this.inputChangeThrottle = this.debounce(this.inputChange, 300)
607    lazyImg.update()
608    this.getHotSearch()
609    $('.oc-main-sam-header-search-input .oc-slect-wrapper').on('change', (e) => {
610      this.searchType = e.value
611      this.resetSearchResults()
612    })
613    if (this.getLastPartOfUrl() == 'productsearch.html') {
614      let { search, type }
614 = this.getQueryParams()
615      if (search) {
616        this.inputValue = search
617      }
618      if (type) {
619        this.searchType = type
620        $('.oc-main-sam-header-search-input .oc-slect-wrapper .oc-slect-label')[0].innerText =
621          TextPrompt.searchType[type]
622        $('.oc-main-sam-header-search-input .oc-slect-wrapper').data('value', type)
623        $('.oc-main-sam-header-search-input .oc-slect-wrapper .oc-slect-ul .oc-select-li').each(
624          (index, item) => {
625            if ($(item).data('value') == type) {
626              $(item).addClass('active-select-li')
627            } else {
628              $(item).removeClass('active-select-li')
629            }
630          },
631        )
632      }
633    }
634  },
635  beforeDestroy () { },
636  methods: {
637    getQueryParams () {
638      const urlParams = new URLSearchParams(window.location.search)
639      const params = {}
640
641      for (let [key, value] of urlParams.entries()) {
642        params[key] = value
643      }
644
645      return params
646    },
647    getLastPartOfUrl () {
648      // 获取当前页面的路径部分
649      const path = window.location.pathname
650
651      // 将路径按斜杠分割成数组
652      const parts = path.split('/')
653
654      // 获取数组的最后一项
655      const lastPart = parts.pop()
656
657      return lastPart
658    },
659    // 全局设置ajax
660    ajaxSetup () {
661      $.ajaxSetup({
662        data: {
663          website: this.website,
664        },
665        query: {
666          website: this.website,
667        },
668      })
669    },
670    jumpHomePage () {
671      window.location.href = TextPrompt.home_url
672    },
673    // 重置搜索结果
674    resetSearchResults (e) {
675      if (this.searchXhr) {
676        this.searchXhr.abort()
677      }
678      this.searchDatas = []
679    },
680    // 输入框输入事件
681    inputChange (e) {
682      // 移动端只查询产品
683      this.searchType = 'products'
684      // 执行模糊搜索获取下拉数据
685      this.getSearchDatas(this.inputValue)
686      // this.searchDatas = []
687      // const container = this.$el.querySelector('.search-down');
688      // if (container) {
689      //     container.scrollTop = 0;
690      // }
691    },
692    debounce (fn, wait) {
693      var timeout = null
694      return function () {
695        if (timeout !== null) clearTimeout(timeout)
696        timeout = setTimeout(fn, wait)
697      }
698    },
699    throttle (func, delay) {
700      var timer = null
701      return function () {
702        var context = this
703        var args = arguments
704        if (!timer) {
705          timer = setTimeout(function () {
706            func.apply(context, args)
707            timer = null
708          }, delay)
709        }
710      }
711    },
712    // 获取热搜词列表
713    getHotSearch () {
714      $.ajax({
715        url: Apis.productWords,
716        type: 'get',
717        dataType: 'json',
718        success: (res) => {
719          console.log('热搜', res)
720
721          if (res.code == 200) {
722            this.hotSearch.popular = res.msg
723            // this.hotSearch = res.data;
724          }
725        },
726      })
727    },
728
729    // 获取模糊搜索结果
730    getSearchDatas (value) {
731      const keywordRegex = new RegExp(value, 'gi')
732      let type = $('.oc-main-sam-header-search-input .oc-slect-wrapper').data('value')
733      if (type != this.searchType) this.searchType = type
734      const searchType = isMobile || this.isProductSearch ? 'products' : this.searchType
735      const params = {
736        keyword: this.inputValue,
737        pageIndex: 1,
738        pageSize: 30,
739        // 移动端或产品搜索情况下搜索产品
740        module: searchType,
741      }
742      //模糊搜索产品
743      if (this.inputValue.length > 1) {
744        this.isLoading = true
745        // if(this.total === this.searchDatas.length) return;
746        console.log('开始搜索!')
747        if (this.searchXhr) {
748          this.searchXhr.abort()
749        }
750        this.searchDatas = []
751        this.searchXhr = $.ajax({
752          //Apis对象在Header.blade.php中定义
753          url: Apis.searchSamNewProductName,
754          data: params,
755          dataType: 'json',
756          type: 'post',
757          success: (res) => {
758            let data = res.data.data || []
759            console.log(res, '搜索成功!', data)
760            this.hotSearch.popular_nums = res.data.product_total || 0
761            this.hotSearch.total = res.data.total || 0
762            this.isLoading = false
763            if (searchType == 'document') {
764              data = res.data || {}
765              let isValue = false
766              console.log('doc', data)
767
768              for (let key in data) {
769                let total = data[key].total || 0
770                data[key].total = total > 1000 ? '1000+' : total
771                if (!data[key].data) data[key].data = []
772                data[key].data = data[key].data.splice(0, 4)
773                data[key].data.forEach((val) => {
774                  val.text = val.title.replace(
775                    keywordRegex,
776                    (match) =>
777                      `<span style="font-weight: 900; color:var(--Color);">${match}</span>`,
778                  )
779                })
780                if (total > 0) isValue = true
781              }
782              this.searchDatas = {
783                //搜索的document是否有值
784                isValue,
785                sds: {},
786                coa: {},
787                tds: {},
788                brochure: {},
789                ...(data || {}),
790              }
791              console.log(this.searchDatas, 'this.searchDatas')
792            } else if (data.length !== 0) {
793              data.forEach((val) => {
794                switch (searchType) {
795                  case 'products':
796                    let url = ''
797                    if (val.images.length !== 0) {
798                      url = val.images[0].url
799                    }
800                    val.image = url
801                    val.text = val.title.replace(
802                      keywordRegex,
803                      (match) =>
804                        `<span style="font-weight: 900; color:var(--Color);">${match}</span>`,
805                    )
806                    val.url = '/' + val.seo_url
807                    break
808                  case 'blog':
809                  case 'application':
810                  case 'categories':
811                  case 'podcast':
812                    val.url = '/' + val.seo_url
813                    val.text = val.title.replace(
814                      keywordRegex,
815                      (match) =>
816                        `<span style="font-weight: 900; color:var(--Color);">${match}</span>`,
817                    )
818                    break
819                  default:
820                    break
821                }
822              })
823              this.searchDatas = data
824              console.log(this.searchDatas, '搜索结果')
825            }
826            this.shearchFlag = true
827          },
828          error: () => {
829            this.shearchFlag = true
830            this.isLoading = false
831          },
832        })
833      } else {
834        this.searchDatas = []
835      }
836    },
837    //记录搜索
838    recordSearch (text) {
839      return new Promise((resolve, reject) => {
840        $.ajax({
841          url: Apis.markSearch,
842          data: {
843            productName: text || this.inputValue, //搜索内容
844            type: this.searchType, //搜索类型
845          },
846          type: 'post',
847          success: (res) => {
848            resolve(res)
849          },
850          error: () => {
851            resolve()
852          },
853        })
854      })
855    },
856    // 点击搜索图标发起搜索
857    handleSearch (e) {
858      e.preventDefault()
859      this.recordSearch() //记录搜索
860      window.location.href = `/productsearch.html?search=${this.inputValue}&type=${this.searchType}`
861    },
862    searchFocus () {
863      if (this.inputValue.trim() != '') {
864        this.getSearchDatas(this.inputValue)
865      }
866      this.isSearchFocus = true
867    },
868    // 关闭搜索
869    searchBlur () {
870      this.isSearchFocus = false
871      // setTimeout(() => {
872      //     // 清空模糊搜索内容
873      //     this.searchDatas = []
874      // }, 200)
875    },
876    closeInput () {
877      this.searchDatas = []
878    },
879    openSearch () {
880      this.isProductSearch = true
881      this.inputValue = ''
882      this.searchDatas = []
883    },
884    // 清空搜索内容
885    clearInputValue () {
886      this.inputValue = ''
887      this.searchDatas = []
888      this.isProductSearch = false
889    },
890    //触摸开始时记录初始位置
891    touchStart (e) {
892      this.startY = e.touches[0].clientY
893      this.isScrolling = false
894    },
895    // 触摸移动时计算偏移量
896    touchMove (e) {
897      this.currentY = e.touches[0].clientY
898      this.isScrolling = true
899    },
900    // 触摸结束时判断是否滚动到底部并触发加载更多
901    touchEnd () {
902      if (this.isScrolling) {
903        const wrapper = this.$refs.scrollWrapper
904        if (
905          wrapper.scrollTop + wrapper.clientHeight >=
906          wrapper.scrollHeight - wrapper.offsetHeight
907        ) {
908          this.loadMoreData()
909        }
910      }
911    },
912    // 加载更多数据的方法
913    loadMoreData () {
914      this.getSearchDatas(this.inputValue)
915    },
916    //#region 移动端加载更多
917    // 判断元素是否有滚动条
918    hasScrollbar (element, direction = true) {
919      return direction
920        ? element.scrollWidth > element.clientWidth
921        : element.scrollHeight > element.clientHeight
922    },
923  },
924})
925
926/**
927 * 懒加载(完美版)可加载`<img>`、`<video>`、`<audio>`等一些引用资源路径的标签
928 * @param {object} params 传参对象
929 * @param {string?} params.lazyAttr 自定义加载的属性(可选)
930 * @param {"src"|"background"} params.loadType 加载的类型(默认为`src`)
931 * @param {string?} params.errorPath 加载失败时显示的资源路径,仅在`loadType`设置为`src`中可用(可选)
932 */
933function lazyLoad (params) {
934  const attr = params.lazyAttr || 'lazy'
935  const type = params.loadType || 'src'
936
937  if (typeof IntersectionObserver == 'undefined') {
938    console.log('使用传统懒加载!')
939    lazyLoadImage(params)
940  }
941
942  /** 更新整个文档的懒加载节点 */
943  function update () {
944    const els = document.querySelectorAll(`[${attr}]`)
945    for (let i = 0; i < els.length; i++) {
946      const el = els[i]
947      observer.observe(el)
948    }
949  }
950  // 加载[pc/m]-src静态资源
951  function loadResources () {
952    $(() => {
953      let key = isMobile ? 'm-src' : 'pc-src'
954      const els = document.querySelectorAll(`[${key}]`)
955      for (let i = 0; i < els.length; i++) {
956        const el = els[i]
957        el.src = el.getAttribute(key)
958        el.removeAttribute(key)
959      }
960    })
961  }
962
963  /**
964   * 加载图片
965   * @param {HTMLImageElement} el 图片节点
966   */
967  function loadImage (el) {
968    const cache = el.src // 缓存当前`src`加载失败时候用
969    el.src = el.getAttribute(attr)
970    el.onerror = function () {
971      el.src = params.errorPath || cache
972    }
973  }
974
975  /**
976   * 加载单个节点
977   * @param {HTMLElement} el
978   */
979  function loadElement (el) {
980    switch (type) {
981      case 'src':
982        loadImage(el)
983        break
984      case 'background':
985        el.style.backgroundImage = `url(${el.getAttribute(attr)})`
986        break
987    }
988    el.removeAttribute(attr)
989    observer.unobserve(el)
990  }
991
992  /**
993   * 监听器
994   * [MDN说明](https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver)
995   */
996  const observer = new IntersectionObserver(function (entries) {
997    for (let i = 0; i < entries.length; i++) {
998      const item = entries[i]
999      if (item.isIntersecting) {
1000        loadElement(item.target)
1001      }
1002    }
1003  })
1004
1005  update()
1006
1007  return {
1008    loadResources,
1009    observer,
1010    update,
1011  }
1012}
1013/**
1014 * 图片懒加载(传统做法)
1015 * @param {object} params 传参对象
1016 * @param {number?} params.toBottom 距离底部像素加载开始加载(可选)
1017 * @param {string?} params.errorImage 加载失败时显示的图片路径(可选)
1018 * @param {string?} params.lazyAttr 自定义加载的属性(可选)
1019 * @param {number?} params.interval 函数节流间隔`毫秒`为单位(可选)
1020 * @param {() => void} params.callback 全部加载完回调(可选)
1021 */
1022function lazyLoadImage (params) {
1023  const doc = document
1024  /** 懒加载属性类型 */
1025  const attr = params.lazyAttr || 'lazy'
1026  /** 函数节流间隔 */
1027  const space = params.interval || 100
1028  /** 距离底部距离 */
1029  const offset = params.toBottom || 0
1030  /** 上一次代码执行时间(节流用) */
1031  let before = 0
1032  /**
1033   * 加载图片
1034   * @param {HTMLImageElement} el 图片节点
1035   */
1036  function loadImage (el) {
1037    /** 缓存当前 src 加载失败时候用 */
1038    const cache = el.src
1039    el.src = el.getAttribute(attr)
1040    el.removeAttribute(attr)
1041    // 图片加载失败
1042    el.onerror = function () {
1043      el.src = params.errorImage || cache
1044    }
1045  }
1046  /** 判断监听图片加载 */
1047  function judgeImages () {
1048    const now = Date.now()
1049    if (now - before < space) return
1050    before = now
1051    const images = doc.querySelectorAll(`[${attr}]`)
1052    const viewHeight = window.innerHeight || doc.documentElement.clientHeight
1053    if (images.length) {
1054      for (let i = 0; i < images.length; i++) {
1055        const imageTop = images[i].getBoundingClientRect().top
1056        if (imageTop <= viewHeight - Math.floor(offset)) {
1057          loadImage(images[i])
1058        }
1059      }
1060    } else {
1061      window.removeEventListener('scroll', judgeImages)
1062      typeof params.callback === 'function' && params.callback()
1063    }
1064  }
1065  judgeImages()
1066  window.addEventListener('scroll', judgeImages)
1067}
1068
1069// 防抖
1070function debounce (func, wait) {
1071  let timeout
1072  return function () {
1073    const context = this
1074    const args = arguments
1075    if (timeout) clearTimeout(timeout)
1076    timeout = setTimeout(() => {
1077      func.apply(context, args)
1078    }, wait)
1079  }
1080}
1081
1082// 节流
1083function throttle (func, limit, immediate) {
1084  let inThrottle
1085  let lastFunc
1086  let lastRan
1087  return function () {
1088    const context = this
1089    const args = arguments
1090    const now = Date.now()
1091    if (!lastRan && immediate) {
1092      func.apply(context, args)
1093      lastRan = true
1094    }
1095    if (inThrottle) {
1096      clearTimeout(lastFunc)
1097      lastFunc = setTimeout(function () {
1098        if (immediate) {
1099          lastRan = false
1100        }
1101        func.apply(context, args)
1102      }, limit)
1103    } else {
1104      func.apply(context, args)
1105      inThrottle = true
1106      lastFunc = setTimeout(function () {
1107        inThrottle = false
1108      }, limit)
1109    }
1110  }
1111}
1112
1113//秒钟格式化 小时:分钟:秒钟
1114function formatSeconds (seconds) {
1115  let hours = Math.floor(seconds / 3600)
1116  let minutes = Math.floor((seconds % 3600) / 60)
1117  let remainingSeconds = seconds % 60
1118
1119  // 格式化每个部分
1120  hours = hours.toString().padStart(2, '0')
1121  minutes = minutes.toString().padStart(2, '0')
1122  remainingSeconds = remainingSeconds.toString().padStart(2, '0')
1123
1124  if (hours === '00') {
1125    return `${minutes}:${remainingSeconds}`
1126  } else {
1127    return `${hours}:${minutes}:${remainingSeconds}`
1128  }
1129}
1130function playPodcastAudio (podcast) {
1131  var newSetItemEvent = new Event('podcastPlay')
1132  newSetItemEvent.podcast = podcast
1133  window.dispatchEvent(newSetItemEvent)
1134}
1135// 滚动到顶部有动画
1136$(document).ready(function () {
1137  var backToTopBtn = $('#oc-top-roll')
1138  // 定义检查并设置回到顶部按钮显示状态的函数
1139  function checkBackToTopVisibility () {
1140    var scrollTop = $(window).scrollTop()
1141
1142    if (scrollTop > $(window).height()) {
1143      backToTopBtn.fadeIn() // 显示按钮
1144    } else {
1145      backToTopBtn.fadeOut() // 隐藏按钮
1146    }
1147  }
1148  // 页面加载时立即检查并设置按钮状态
1149  checkBackToTopVisibility()
1150  // 监听滚动事件
1151  $(window).scroll(checkBackToTopVisibility)
1152  // 给回到顶部按钮添加点击事件
1153  backToTopBtn.click(function (event) {
1154    event.preventDefault()
1155    $('html, body').animate({ scrollTop: 0 }, 'slow')
1156  })
1157})
1158//#endregion 返回顶部
1159
1160//#region LiveChat: custom launcher (click-only init)
1161;(function () {
1162  if (!window.__lc || !window.__lc.asyncInit) return
1163  if (!window.LiveChatWidget || typeof window.LiveChatWidget.init !== 'function') return
1164
1165  var started = false
1166  var ready = false
1167  var eventsBound = false
1168  var launcherBtn = null
1169
1170  var LAUNCHER_ICON_SVG =
1171    '<svg class="sam-lc-launcher__icon" color="inherit" viewBox="0 0 32 32" aria-hidden="true" focusable="false">' +
1172    '<path fill="#FFFFFF" d="M12.63,26.46H8.83a6.61,6.61,0,0,1-6.65-6.07,89.05,89.05,0,0,1,0-11.2A6.5,6.5,0,0,1,8.23,3.25a121.62,121.62,0,0,1,15.51,0A6.51,6.51,0,0,1,29.8,9.19a77.53,77.53,0,0,1,0,11.2,6.61,6.61,0,0,1-6.66,6.07H19.48L12.63,31V26.46"></path>' +
1173    '<path fill="#335DA0" d="M19.57,21.68h3.67a2.08,2.08,0,0,0,2.11-1.81,89.86,89.86,0,0,0,0-10.38,1.9,1.9,0,0,0-1.84-1.74,113.15,113.15,0,0,0-15,0A1.9,1.9,0,0,0,6.71,9.49a74.92,74.92,0,0,0-.06,10.38,2,2,0,0,0,2.1,1.81h3.81V26.5Z"></path>' +
1174    '</svg>'
1175
1176  function setLauncherLoading (on) {
1177    if (!launcherBtn) return
1178    launcherBtn.classList.toggle('is-loading', !!on)
1179    launcherBtn.setAttribute('aria-busy', on ? 'true' : 'false')
1180    launcherBtn.disabled = !!on
1181  }
1182
1183  function hideGreeting () {
1184    try {
1185      window.LiveChatWidget.call('hide_greeting')
1186    } catch (e) { /* ignore */ }
1187    document.documentElement.classList.remove('sam-lc-greeting-visible')
1188  }
1189
1190  function maximizeChat () {
1191    try {
1192      window.LiveChatWidget.call('maximize')
1193    } catch (e) { /* ignore */ }
1194  }
1195
1196  function bindWidgetEvents () {
1197    if (eventsBound) return
1198    eventsBound = true
1199
1200    window.LiveChatWidget.on('visibility_changed', function (data) {
1201      var vis = data && data.visibility
1202      document.documentElement.classList.toggle('sam-lc-chat-open', vis === 'maximized')
1203      if (vis !== 'maximized') setLauncherLoading(false)
1204    })
1205
1206    // Click-to-open path: never show greeting tip
1207    window.LiveChatWidget.on('greeting_displayed', function () {
1208      hideGreeting()
1209      maximizeChat()
1210    })
1211
1212    window.LiveChatWidget.on('greeting_hidden', function () {
1213      document.documentElement.classList.remove('sam-lc-greeting-visible')
1214    })
1215  }
1216
1217  function onWidgetReady () {
1218    ready = true
1219    document.documentElement.classList.add('sam-lc-widget-ready')
1220    hideGreeting()
1221    maximizeChat()
1222  }
1223
1224  function startLiveChat () {
1225    if (ready) {
1226      hideGreeting()
1227      maximizeChat()
1228      return
1229    }
1230
1231    if (started) {
1232      setLauncherLoading(true)
1233      return
1234    }
1235
1236    started = true
1237    bindWidgetEvents()
1238    setLauncherLoading(true)
1239
1240    window.LiveChatWidget.on('ready', onWidgetReady)
1241    window.LiveChatWidget.init()
1242  }
1243
1244  function createLauncher () {
1245    if (document.getElementById('sam-lc-launcher')) return
1246    var btn = document.createElement('button')
1247    btn.type = 'button'
1248    btn.id = 'sam-lc-launcher'
1249    btn.className = 'sam-lc-launcher'
1250    btn.setAttribute('aria-label', 'Chat with us')
1251    btn.title = 'Chat with us'
1252    btn.innerHTML =
1253      '<span class="sam-lc-launcher__btn">' + LAUNCHER_ICON_SVG + '</span>' +
1254      '<span class="sam-lc-launcher__spinner" aria-hidden="true"></span>'
1255    btn.addEventListener('click', function (e) {
1256      e.preventDefault()
1257      startLiveChat()
1258    })
1259    document.body.appendChild(btn)
1260    launcherBtn = btn
1261  }
1262
1263  createLauncher()
1264})()
1265//#endregion LiveChat

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.