PageSourceSearch

https://www.meetion.com.cn/assets/js/unit/b2c-header.js

js meetion.com.cn collected 2026-10-04 20:36:46 UTC 12,579 bytes, 319 lines download raw bytes

1class ScriptB2cHeader extends Script {
2  constructor(params) {
3    super(params)
4    this.headDom = document.querySelector(`#${this.attrId}`)
5    this.swiperDom = document.querySelector(`#swiper-${this.attrId}`)
6    this.navItemDom = this.headDom.querySelectorAll('.unit-b2c-header__nav-item')
7    this.bodyDom = this.headDom.querySelector('.unit-b2c-header__body-wrap')
8    this.subNavDom = null
9    this.mHeadDom = this.bodyDom.querySelector('.unit-b2c-header__body-m')
10    this.blockHeader = document.querySelector('[package-block-type="header"]')
11    this.winWidth = document.body.offsetWidth || document.documentElement.offsetWidth
12    this.delayTime = null
13  }
14  /** 初始化,支持异步 */
15  async init() {
16    // 初始化html,因为m端和pc端会有所差异
17    this.initHtml()
18    // 初始化栏目展开二级的事件
19    this.initNavEvent()
20    // 初始化查找信息,装修状态下不用初始
21    if (!Utilts.ins().checkDesign()) {
22      this.initSearch()
23      // 设置购物车数量
24      Utilts.ins().getCartQuantity()
25    }
26  }
27
28
29  /** 初始化查找信息 */
30  initSearch() {
31    const $search = document.querySelector('.unit-b2c-header__search')
32    const $show = $search.querySelector('.search-show')
33    const searchGround = $search.querySelector('.search-form')
34    const $close = $search.querySelector('.search-close')
35    const $searchBtn = $search.querySelector('.search-form .search-btn')
36    const $searchInput = $search.querySelector('.search-input')
37
38    if ($show) {
39      $show.addEventListener('click', function (self) {
40        searchGround.classList.add('active')
41      })
42    }
43    if ($close) {
44      $close.addEventListener('click', function (self) {
45        searchGround.classList.remove('active')
46      })
47    }
48    if ($searchBtn) {
49      $searchBtn.addEventListener('click', () => this._goSearchPage($searchInput))
50      $searchInput.onkeypress = (event) => {
51        if (event.key === 'Enter') {
52          this._goSearchPage($searchInput)
53        }
54      }
55    }
56  }
57
58  // 搜索回车结果
59  _goSearchPage(node) {
60    let keyword = ''
61    if (node && node.value) keyword = node.value
62    // 清除缓存里的搜索参数
63    this.utilts.removeItem('search-pattern')
64    const href = globalThis.Server.getRinseHref(`/search.html?keyword=${keyword}`, window.app.info.site)
65    window.location.href = href
66  }
67  // 添加节点
68  initHtml() {
69    if (this.winWidth > 1200) this._initPcHtml()
70  }
71  // 节点绑定事件
72  initNavEvent() {
73    if (this.winWidth > 1200) this._initPcEvent()
74    else {
75      this._initPhoneEvent()
76      this._initLangNodeEvent()
77      this.toggleMenu()
78    }
79  }
80  /**pc端html初始化 */
81  _initPcHtml() {
82    this.subNavDom = Utilts.ins().createDom(this.swiperDom, 'div', ['unit-b2c-header__nav', 'unit-b2c-header__sub-nav'])
83  }
84  /**pc端绑定事件初始化 */
85  _initPcEvent() {
86    for (const $nav_item of this.navItemDom) {
87      this._firstMenuShowOrHide($nav_item)
88    }
89    this._subMenuShowOrHide()
90  }
91  /**m端绑定事件初始化 */
92  _initPhoneEvent() {
93    const $nav = this.mHeadDom.querySelectorAll('.unit-b2c-header__nav-item')
94    for (const $nav_item of $nav) {
95      const $navDrowmenu = $nav_item.querySelector('.unit-b2c-header__nav-item-inner > .icon-action-bottom-lighter')
96      if ($navDrowmenu) {
97        $navDrowmenu.addEventListener('click', () => {
98          // 判断当前栏目是否显示下拉栏目
99          if (Utilts.ins().hasClass($nav_item, 'active')) {
100            $nav_item.classList.remove('active')
101          } else {
102            $nav_item.classList.add('active')
103            for (const item of Utilts.ins().getSiblings($nav_item)) {
104              item.classList.remove('active')
105            }
106          }
107        })
108      }
109    }
110    // 二级栏目显示下拉栏目
111    let $sons = this.mHeadDom.querySelectorAll('.unit-b2c-header__nav-son-item')
112    for (const $son_item of $sons) {
113      const $sonDrowmenu = $son_item.querySelector('.unit-b2c-header__nav-son-item-inner > .icon-action-bottom-lighter')
114      if ($sonDrowmenu) {
115        $sonDrowmenu.addEventListener('click', () => {
116          if (Utilts.ins().hasClass($son_item, 'active')) {
117            $son_item.classList.remove('active')
118          } else {
119            $son_item.classList.add('active')
120            for (const item of Utilts.ins().getSiblings($son_item)) {
121              item.classList.remove('active')
122            }
123          }
124        })
125      }
126    }
127    // 三级栏目显示下拉栏目
128    let $grandsons = this.mHeadDom.querySelectorAll('.unit-b2c-header__nav-grandson-item')
129    for (const $grandson_item of $grandsons) {
130      const $grandsonDrowmenu = $grandson_item.querySelector('.unit-b2c-header__nav-grandson-item-inner > .icon-action-bottom-lighter')
131      if ($grandsonDrowmenu) {
132        $grandsonDrowmenu.addEventListener('click', () => {
133          if (Utilts.ins().hasClass($grandson_item, 'active')) {
134            $grandson_item.classList.remove('active')
135          } else {
136            $grandson_item.classList.add('active')
137            for (const item of Utilts.ins().getSiblings($grandson_item)) {
138              item.classList.remove('active')
139            }
140          }
141        })
142      }
143    }
144  }
145
146  /**一级菜单绑定鼠标经过和离开事件 */
147  _firstMenuShowOrHide($nav_item) {
148    $nav_item.addEventListener('mouseenter', () => {
149      this._headerAddzIndex()
150      clearTimeout(this.delayTime)
151      // 清空临时下拉栏目内容
152      this.subNavDom.innerHTML = ''
153      this.subNavDom.style.cssText = "height: auto; opacity: 1;"
154      const $navSon = $nav_item.querySelector('.unit-b2c-header__nav-son-wrap')
155      if ($navSon) {
156        let $cloneNode = $navSon.cloneNode(true)
157        // 栏目内容位置对应触发元素
158        this._setStyleText($nav_item, $cloneNode)
159        // 填充鼠标经过栏目对应二级栏目的内容
160        this._setSonItem($cloneNode)
161        this.subNavDom.appendChild($cloneNode)
162      }
163    })
164    // 一级菜单绑定鼠标离开事件
165    $nav_item.addEventListener('mouseleave', () => {
166      this._headerResetzIndex()
167      this.delayTime = setTimeout(() => {
168        // 二级栏目隐藏
169        this.subNavDom.style.cssText = 'height: 0; opacity: 0'
170      }, 500)
171    })
172  }
173
174  /** 二级栏目保持显示或隐藏并清空状态 */
175  _subMenuShowOrHide() {
176    //鼠标放在二级栏目上, 二级栏目保持显示状态
177    this.subNavDom.addEventListener('mouseenter', () => {
178      this._headerAddzIndex()
179      clearTimeout(this.delayTime)
180      this.subNavDom.style.cssText = 'height: auto; opacity: 1'
181    })
182    //鼠标离开二级栏目, 二级栏目隐藏并清空
183    this.subNavDom.addEventListener('mouseleave', () => {
184      this._headerResetzIndex()
185      this.subNavDom.style.cssText = 'height: 0; opacity: 0'
186      this.subNavDom.innerHTML = ''
187    })
188  }
189
190  /** 二级菜单绑定鼠标经过事件 */
191  _setSonItem(parentNode) {
192    let subs = parentNode.querySelectorAll('.unit-b2c-header__nav-son-item')
193    for (const subItem of subs) {
194      // 二级菜单绑定鼠标经过事件
195      subItem.addEventListener('mouseenter', () => {
196        // 栏目内容位置对应触发元素
197        const currentNav = subItem.querySelector('.unit-b2c-header__nav-grandson')
198        if (currentNav) {
199          if (currentNav.style) {
200            const topNum = Utilts.ins().getOffset(subItem).top - Utilts.ins().getOffset(parentNode).top - 2;
201            currentNav.style.cssText = `opacity: 1; height:auto; top: ${topNum}px;left: 100%; max-height: calc(100vh - ${topNum + this.headDom.offsetHeight}px);`
202            // 三级导航栏定位超出屏幕,改成左定位
203            if ((Utilts.ins().getOffset(currentNav).left + currentNav.offsetWidth) > window.innerWidth) {
204              currentNav.style.left = '-100%'
205            }
206          }
207          for (const bro of Utilts.ins().getSiblings(subItem)) {
208            // 其他兄弟元素下的三级栏目隐藏
209            const siblingNav = bro.querySelector('.unit-b2c-header__nav-grandson')
210            if (siblingNav && siblingNav.style) siblingNav.style.cssText = 'opacity: 0; height: 0; overflow: hidden;'
211          }
212
213          this._setGrandsonItem(currentNav)
214        }
215      })
216    }
217  }
218
219  /** 三级菜单绑定鼠标经过事件 */
220  _setGrandsonItem(parentNode) {
221    let subs = parentNode.querySelectorAll('.unit-b2c-header__nav-grandson-item')
222    for (const subitem of subs) {
223      // 三级菜单绑定鼠标经过事件
224      subitem.addEventListener('mouseenter', () => {
225        // 栏目内容位置对应触发元素
226        const currentNav = subitem.querySelector('.unit-b2c-header__nav-grateson')
227        if (currentNav) {
228          if (currentNav.style) {
229            const topNum = Utilts.ins().getOffset(subitem).top - Utilts.ins().getOffset(parentNode).top - 2;
230            currentNav.style.cssText = `opacity: 1; height:auto; top: ${topNum}px;left: 100%; max-height: calc(100vh - ${topNum + this.headDom.offsetHeight}px);`
231            // 三级导航栏定位超出屏幕,改成左定位
232            if ((Utilts.ins().getOffset(currentNav).left + currentNav.offsetWidth) > window.innerWidth) {
233              currentNav.style.left = '-100%'
234            }
235          }
236          for (const bro of Utilts.ins().getSiblings(subitem)) {
237            // 其他兄弟元素下的三级栏目隐藏
238            const siblingNav = bro.querySelector('.unit-b2c-header__nav-grateson')
239            if (siblingNav && siblingNav.style) siblingNav.style.cssText = 'opacity: 0; height: 0; overflow: hidden;'
240          }
241          currentNav.addEventListener('mouseenter', () => {
242            clearTimeout(this.delayTime)
243          })
244        }
245      })
246      subitem.addEventListener('mouseleave', () => {
247        const currentNav = subitem.querySelector('.unit-b2c-header__nav-grateson')
248        if (currentNav) {
249          this.delayTime = setTimeout(() => {
250            // 二级栏目隐藏
251            currentNav.style.cssText = 'opacity: 0; height: 0; overflow: hidden;'
252          }, 100)
253        }
254      })
255    }
256  }
257
258  /** 小语种 */
259  _initLangNodeEvent() {
260    const $language = this.mHeadDom.querySelector('.unit-b2c-header__language-box') || null
261    const $backBtn = this.mHeadDom.querySelector('.lan-btn') || null
262    if (!$language && !$backBtn) return
263    const $list = $language.querySelector('.language')
264    // 语种列表返回菜单
265    $backBtn.addEventListener('click', () => {
266      $list.style.display = 'none'
267    })
268    // 菜单打开语种猎豹
269    $language.querySelector('.open-btn').addEventListener('click', () => {
270      $list.style.display = 'block'
271    })
272  }
273
274  /**m端展开侧边栏 */
275  toggleMenu() {
276    this.headDom.querySelector('.unit-b2c-header__switch').addEventListener('click', () => {
277      if (Utilts.ins().hasClass(this.mHeadDom, 'body-hide')) {
278        this.mHeadDom.classList.remove('body-hide')
279        this.mHeadDom.classList.add('body-show')
280        document.querySelector('body').style.overflow = 'hidden'
281        let mask = Utilts.ins().createDom(this.bodyDom, 'div', [])
282        mask.style.cssText = 'width:100vw;height:calc(100vh - 0px);position: fixed; top:0px; left:0; z-index: 1999;'
283        mask.setAttribute('id', 'nav_mask')
284        mask.addEventListener('click', () => {
285          this.mHeadDom.classList.add('body-hide')
286          this.mHeadDom.classList.remove('body-show')
287          document.querySelector('body').style.overflow = 'initial'
288          Utilts.ins().removeNode(mask)
289        })
290      } else {
291        this.mHeadDom.classList.add('body-hide')
292        this.mHeadDom.classList.remove('body-show')
293        document.querySelector('body').style.overflow = 'initial'
294        Utilts.ins().removeNode(mask)
295      }
296    })
297  }
298
299  /** 栏目内容位置对应触发元素 */
300  _setStyleText($nav_item, $cloneNode) {
301    // 栏目内容位置对应触发元素
302    const top = `top: -5px;`
303    const outLeft = Utilts.ins().getOffset($nav_item).left
304    const $innerNode = this.headDom.querySelector('.unit-b2c-header__nav-inner')
305    const innerLeft = Utilts.ins().getOffset($innerNode).left
306    const left = `left: ${outLeft - innerLeft}px;`
307    $cloneNode.style.cssText = `${top}${left}opacity: 1;`
308  }
309
310  // 显示二级菜单时,添加z-index为了不被挡住
311  _headerAddzIndex() {
312    this.blockHeader.classList.add('header-hover-index')
313  }
314
315  // 菜单离开时,恢复header 层级
316  _headerResetzIndex() {
317    this.blockHeader.classList.remove('header-hover-index')
318  }
319}

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.