1/** 2 * 产åæåºç»ä»¶ 3 */ 4class ScriptProductSortMobile extends Script { 5 constructor(params) { 6 super(params) 7 this.$unit = document.querySelector(`#${this.attrId}`) 8 if (!this.$unit) return 9 this.prefx = 'unit-product-sort-m' 10 this.$main = this.$unit.querySelector(`.${this.prefx}__items`) 11 if(this.$main) this.$main.innerHTML = '' 12 // æåºé¡¹ 13 this.sortName = Utilts.ins().$t('Sort By') 14 this.$drop = this.$unit.querySelectorAll('.unit-header-menu__nav__item-drop') 15 this.templateType = params.templateType 16 // æåºé¡¹ 17 this.sortList = [ 18 { id: 5, name: Utilts.ins().$t('Default'), active: false, sort: 'sort desc,create_time desc' }, 19 { id: 1, name: Utilts.ins().$t('Newest'), active: false, sort: 'create_time desc,id desc' }, 20 { id: 2, name: Utilts.ins().$t('Lowest Price'), active: false, sort: 'price asc' }, 21 { id: 3, name: Utilts.ins().$t('Highest Price'), active: false, sort: 'price desc' }, 22 { id: 4, name: Utilts.ins().$t('Hot Sale'), active: false, sort: 'order desc' }, 23 { id: 5, name: Utilts.ins().$t('Most Popular'), active: false, sort: 'favorite desc' } 24 ] 25 if(this.templateType==='b2b'){ 26 this.sortList = [ 27 { id: 5, name: Utilts.ins().$t('Default'), active: false, sort: 'sort desc,create_time desc' }, 28 { id: 1, name: Utilts.ins().$t('Newest'), active: false, sort: 'create_time desc,id desc' }, 29 ] 30 } 31 this.$maintwo = this.$unit.querySelectorAll(`.unit-header-menu_right_slide_view .unit-attr-search__items`) 32 // this.$maintwo.innerHTML = '' 33 const that = this; 34 /** 35 * éä¸çcheckbox 36 * @type {{}} 37 */ 38 this.checkedAttrs = new Proxy({}, { 39 set(target, p, value) { 40 if (value?.id && value?.product_attr_id) { 41 that.$maintwo.forEach(a=>{ 42 var checkboxWrapNode = a.querySelector(`.unit-attr-search__content--checkbox[data-checkbox_uid="${value.product_attr_id}-${value.id}"]`) 43 checkboxWrapNode && (value.checked ? checkboxWrapNode.classList.add('is_active') : checkboxWrapNode.classList.remove('is_active')) 44 }) 45 } 46 return Reflect.set(target, p, value); 47 } 48 }); 49 //æç´¢é¡¹ 50 this.$mainthree = this.$unit.querySelector('.unit-attr-text-search-right_slide__items') 51 this.product_attr_id = '' 52 this.showSearchItemName = '--Please Selected--' 53 } 54 /** 䏿äºä»¶ */ 55 initDropEvent() { 56 for (let $el of this.$drop) { 57 $el.addEventListener('click', (e) => { 58 e.stopPropagation() 59 e.preventDefault() 60 $el.classList.toggle('active') 61 const $content = $el.parentNode.parentNode.children[1] || null 62 if ($content) { 63 if(this.$droupDowm){ 64 this.$droupDowm.classList.remove('show') 65 } 66 $content.classList.toggle('show') 67 } 68 }) 69 } 70 } 71 async init() { 72 var that = this; 73 if(this.$maintwo){ 74 this.initDropEvent() 75 this.initListeners(); 76 } 77 if(this.$mainthree){ 78 this.createdSearchElement() 79 this.initLoadData() 80 this.initEvent() 81 } 82 if(this.$main){ 83 this.initSort() 84 this.initHideElement() 85 const sortItems = document.querySelector(`#${this.attrId} .unit-product-sort-m__items`) 86 const prefix = this.prefx 87 const unitElem = this.$unit 88 const sortList = this.sortList 89 sortItems.addEventListener('click', function (evt) { 90 const clickElem = evt.target 91 const elemFilterTextReg = new RegExp(`${prefix}__filter(-text)?\\b(?!-)`, 'i') 92 const elemFilterPosiText = new RegExp(`${prefix}__filter-posi(-text)?\\b(?!-)`, 'i') 93 if (elemFilterTextReg.test(clickElem.className) || elemFilterTextReg.test(clickElem.parentElement.className)) { 94 // æå¼ä¸ææåºå表 95 evt.stopPropagation() 96 const itemSearchFilterBox = unitElem.querySelector(`.${prefix}__filter-text`) 97 itemSearchFilterBox && itemSearchFilterBox.classList.toggle('is_active') 98 } else if (clickElem instanceof HTMLParagraphElement && elemFilterPosiText.test(clickElem.parentElement.className)) { 99 // æåºä¸æå表éä¸å ç´ ç¹å» 100 evt.stopPropagation() 101 const list = Array.prototype.filter.call(clickElem.parentElement.children, function (node) { 102 return node instanceof HTMLParagraphElement 103 }) 104 const idx = list.indexOf(clickElem) 105 list.forEach(function (elem) { 106 elem === clickElem ? (elem.classList.add('is_active')) : (elem.classList.remove('is_active')) 107 }) 108 if (idx > -1 && sortList[idx]) { 109 const filter = sortList[idx] 110 window.app.info.product_sort = filter.sort 111 if (window.app.info && window.app.info.renderListView) { 112 window.app.info.renderListView() 113 } 114 } 115 const itemSearchFilterBox = unitElem.querySelector(`.${prefix}__filter-text`) 116 itemSearchFilterBox.classList.toggle('is_active') 117 itemSearchFilterBox.firstChild.innerText = clickElem.innerText 118 } 119 }) 120 document.querySelector('body').addEventListener('touchmove', () => { 121 const itemSearchFilterBox = unitElem.querySelector(`.${prefix}__filter-text`) 122 itemSearchFilterBox && itemSearchFilterBox.classList.remove('is_active') 123 }) 124 } 125 var rightSlideView = document.querySelector(`.unit-header-menu_right_slide_view`); 126 var filterBtn = document.querySelector(`.unit-product-sort__filter_btn`) 127 if(filterBtn){ 128 filterBtn.addEventListener('click', function (evt) { 129 console.log(document.getElementById('app')) 130 if(document.getElementById('app').querySelectorAll('.unit-header-menu_right_slide_view').length>0){ 131 rightSlideView.remove() 132 document.getElementById('app').appendChild(rightSlideView) 133 } 134 rightSlideView.style.display = 'block' 135 document.body.style.overflow = 'hidden' 136 }) 137 var rightSlideClose = document.querySelectorAll(`.unit-header_right_slide-close`) 138 rightSlideClose.forEach(a=>{ 139 a.addEventListener('click', function (evt) { 140 rightSlideView.style.display = 'none' 141 document.body.style.overflow = 'auto' 142 setTimeout(()=>{ 143 document.documentElement.scrollTop=0 144 },200) 145 }) 146 }) 147 var rightSlideDeselect = document.querySelector(`.unit-header_right_slide-deselect`) 148 rightSlideDeselect.addEventListener('click', function (evt) { 149 that.initListeners(true) 150 that.$input.value = '' 151 that.searchData() 152 }) 153 } 154 } 155 initListeners(flat) { 156 const that = this;
157 this.$maintwo.forEach(a=>{ 158 if(flat){ 159 var checkboxList = a.querySelectorAll('.unit-attr-search__content--checkbox'); 160 checkboxList.forEach(i=>{ 161 i.classList.remove('is_active') 162 var checkbox = i.querySelector('input[type="checkbox"]') 163 var checked = false 164 const checkboxInputType = parseInt(checkbox.getAttribute('data-input_type')); 165 const checkboxGroup = parseInt(checkbox.getAttribute('data-product_attr_id')); 166 const checkboxAttr = checkbox.getAttribute('data-attr_param') || 'attr'; // 屿§åæ° 167 const checkboxDataId = parseInt(checkbox.getAttribute('data-id')); 168 that.checkedAttrs[checkbox.value] = { 169 product_attr_id: checkboxGroup, 170 attr: checkboxAttr, 171 id: parseInt(checkbox.getAttribute('data-id')), 172 input_type: checkboxInputType, // åé/å¤é 173 content: checkbox.getAttribute('data-content'), 174 checked 175 }; 176 // æ¾ç¤ºéè 177 if (a.classList?.contains('icon-action-left-lighter')) { 178 evt.stopPropagation(); 179 const hide_cls = 'unit-attr-search__content--hide'; 180 a.classList.toggle('up'); 181 a.parentNode.parentNode.querySelector('.unit-attr-search__content')?.classList?.toggle(hide_cls) 182 } 183 }) 184 }else{ 185 a.addEventListener('click', (evt) => { 186 console.log(evt.target) 187 const el = evt.target; 188 if(this.$droupDowm){ 189 this.$droupDowm.classList.remove('show') 190 } 191 // 屿§çé 192 if (el.classList?.contains('unit-attr-search__content--checkbox') || el.parentNode.classList?.contains('unit-attr-search__content--checkbox')) { 193 evt.stopPropagation(); 194 const pointer = evt.target.classList.contains('unit-attr-search__content--checkbox') ? evt.target : evt.target.parentNode; 195 const checkbox = pointer.querySelector('input[type="checkbox"]'); 196 const checked = !(that.checkedAttrs[checkbox.value]?.checked); 197 const checkboxInputType = parseInt(checkbox.getAttribute('data-input_type')); 198 const checkboxGroup = parseInt(checkbox.getAttribute('data-product_attr_id')); 199 const checkboxAttr = checkbox.getAttribute('data-attr_param') || 'attr'; // 屿§åæ° 200 const checkboxDataId = parseInt(checkbox.getAttribute('data-id')); 201 that.checkedAttrs[checkbox.value] = { 202 product_attr_id: checkboxGroup, 203 attr: checkboxAttr, 204 id: parseInt(checkbox.getAttribute('data-id')), 205 input_type: checkboxInputType, // åé/å¤é 206 content: checkbox.getAttribute('data-content'), 207 checked 208 }; 209 if (checkboxInputType === 2 && checked) { 210 // åé åæ¶ååç»ä¸çå ¶ä»checkboxéä¸ç¶æ 211 for (let k in that.checkedAttrs) { 212 const attr = that.checkedAttrs[k]; 213 if (attr.product_attr_id === checkboxGroup && attr.checked && attr.id !== checkboxDataId) { 214 attr.checked = false; 215 that.checkedAttrs[k] = attr; 216 } 217 } 218 } 219 /** 220 * @type {{[string]?: {product_attr_id: number, content: string[]}}} 221 */ 222 const attr_params = {}; 223 const checkedBoxes = Object.values(that.checkedAttrs).filter(box => box?.checked && box.attr === 'attr'); 224 [...new Set(checkedBoxes.map(box => box.product_attr_id))].forEach(group => attr_params[group] = { 225 product_attr_id: parseInt(group), 226 content: [] 227 }); 228 checkedBoxes.forEach(box => attr_params[box.product_attr_id]?.content?.push(box.content)); 229 window.app.info.attr_params = Object.values(attr_params); 230 const attr_detail_id = Object.values(that.checkedAttrs).filter(box => box?.checked && box.attr === 'attr_detail_id').map(box => parseInt(box.id)) 231 window.app.info.attr_detail_id = Array.from(new Set(attr_detail_id)) 232 // const detailAttr 233 window.app.info.renderListView(); 234 } 235 // æ¾ç¤ºéè 236 if (el.classList?.contains('icon-action-left-lighter')) { 237 evt.stopPropagation(); 238 const hide_cls = 'unit-attr-search__content--hide'; 239 el.classList.toggle('up'); 240 el.parentNode.parentNode.querySelector('.unit-attr-search__content')?.classList?.toggle(hide_cls) 241 } 242 243 }); 244 } 245 }) 246 if(flat){ 247 const attr_params = {}; 248 const checkedBoxes = Object.values(that.checkedAttrs).filter(box => box?.checked && box.attr === 'attr'); 249 [...new Set(checkedBoxes.map(box =>
249 box.product_attr_id))].forEach(group => attr_params[group] = { 250 product_attr_id: parseInt(group), 251 content: [] 252 }); 253 checkedBoxes.forEach(box => attr_params[box.product_attr_id]?.content?.push(box.content)); 254 window.app.info.attr_params = Object.values(attr_params); 255 const attr_detail_id = Object.values(that.checkedAttrs).filter(box => box?.checked && box.attr === 'attr_detail_id').map(box => parseInt(box.id)) 256 window.app.info.attr_detail_id = Array.from(new Set(attr_detail_id)) 257 // const detailAttr 258 window.app.info.renderListView(); 259 } 260 } 261 // ç¹å»é¡µé¢ç©ºç½ï¼æå å·²å±å¼æ ç® 262 initHideElement() { 263 document.querySelector('body').addEventListener('click', () => { 264 this.$itemSearchFilterBox.classList.remove('is_active') 265 }) 266 } 267 268 initSort() { 269 this.$main.innerHTML = '' 270 this.$main.append(this.getSortListElement()) 271 } 272 273 h(tag, props, text) { 274 const $item = document.createElement(tag) 275 for (const key in props) { 276 if (Object.hasOwnProperty.call(props, key)) { 277 const element = props[key]; 278 if (key === 'class') { 279 if (Array.isArray(element)) $item.classList.add(...element) 280 else $item.classList.add(element) 281 } 282 else $item.setAttribute(key, element) 283 } 284 } 285 if (text) $item.innerHTML = text 286 return $item 287 } 288 /** 289 * è·åæåºé¡¹ 290 * @param {Object} data æåºä¿¡æ¯ 291 * @returns 292 */ 293 getSortListElement() { 294 const $itemBox = this.h('div', { class: `${this.prefx}__filter` }) 295 this.$itemSearchFilterBox = this.h('div', { class: `${this.prefx}__filter-text` }) 296 const $span = this.h('span', {}, this.sortName) 297 this.$itemSearchFilterBox.append($span) 298 const $icon = this.h('span', { class: ['iconfont', 'icon-action-bottom-lighter', 'ml-1'] }) 299 this.$itemSearchFilterBox.append($icon) 300 $itemBox.append(this.$itemSearchFilterBox) 301 302 const $filterPosiBox = this.h('div', { class: `${this.prefx}__filter-posi` }) 303 304 const attr = { class: [`${this.prefx}__filter-posi-text`, `${this.prefx}__sanjiao`, `${this.prefx}__isChoose`] } 305 const $filterPosiBoxText = this.h('div', attr) 306 307 this.sortList.forEach((data, index) => { 308 const $pItem = this.h('p', {}, data.name) 309 if (data.active) $pItem.classList.add('is_active') 310 $filterPosiBoxText.append($pItem) 311 }) 312 $filterPosiBox.append($filterPosiBoxText) 313 this.$itemSearchFilterBox.append($filterPosiBox) 314 return $itemBox 315 } 316 // æç´¢æ¡~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 createdSearchElement() { 318 // æ¸ ç©ºæ§çæ°æ® 319 this.$mainthree.innerHTML = '' 320 // å建divBox 321 const $searchBox = document.createElement('div') 322 $searchBox.classList.add('input-group-right_slide') 323 324 const $inputGroup = document.createElement('div') 325 $inputGroup.classList.add('input-group-prepend-right_slide') 326 // åå»ºä¸æå±æ§é¡¹ 327 this.$button = null 328 this.$button = document.createElement('button') 329 this.$button.classList.add('btn', 'btn-outline-secondary-right_slide') 330 const html = `<span class="btn-text text-truncate"> ${this.showSearchItemName} </span> 331 <span class="iconfont icon-action-bottom-lighter ml-1"></span>` 332 this.$button.innerHTML = html 333 $inputGroup.append(this.$button) 334 335 // å建æç´¢ææ¬é¡¹ 336 this.$droupDowm = document.createElement('div') 337 this.$droupDowm.classList.add('dropdown-menu-right_slide') 338 $inputGroup.append(this.$droupDowm) 339 340 this.$input = null 341 this.$input = document.createElement('input') 342 this.$input.classList.add('form-control-right_slide') 343 $inputGroup.append(this.$input) 344 // å建æç´¢å¾æ 345 this.$incofont = null 346 this.$incofont = document.createElement('span') 347 this.$incofont.classList.add('iconfont', 'icon-action-search-lighter', 'btnSearch') 348 349 $searchBox.append($inputGroup) 350 $searchBox.append(this.$input) 351 $searchBox.append(this.$incofont) 352 this.$mainthree.append($searchBox) 353 } 354 async initLoadData() { 355 this.$droupDowm.innerHTML = '' 356 const params = { site_id: window.app.info.site.site_id, type: '1,2,3', status: 1, is_show: 1, language_code: window.app.info.site.language_code } 357 const url = '/product-attr/list-page' 358 const res = await this.utilts.request({ url, method: 'GET', params }) 359 var resList = res.data.list || []; 360 var list = resList.filter(p => p.input_type === 1 && p.status && p.is_show) 361 list = list.map((p, i) => ({ id: p.id, name: p.sign || `name${i}`, type: p.input_type })) 362 if (list.length > 0){ 363 this.product_attr_id = list[0].id 364 for (const item of list) { 365 const $item = document.createElement('div') 366 $item.classList.add('dropdown-item') 367 $item.setAttribute('data-id', item.id) 368 $item.setAttribute('href', '#') 369 $item.innerText = item.name 370 this.$droupDowm.append($item) 371 $item.onclick = () => { 372 this.sibling($item).forEach(a=>{ 373 a.classList.remove('is_active') 374 }) 375 $item.classList.add('is_active') 376 this.product_attr_id = item.id 377 const $btnText = this.$button.querySelector('.btn-text') 378 $btnText.innerText = item.name 379 this.$droupDowm.classList.toggle('show') 380 } 381 } 382 } else {
383 const tip = window.app.utilts.$t('no data') 384 this.$droupDowm.innerHTML = `<div class='dropdown-item' style='color:grey;text-align:center;'>${tip}<div>` 385 } 386 } 387 sibling(elem) { 388 var r = []; 389 var n = elem.parentNode.firstChild; 390 for(; n; n = n.nextSibling) { 391 if(n.nodeType === 1 && n !== elem) { 392 r.push(n); 393 } 394 } 395 return r; 396 } 397 initEvent() { 398 // 䏿屿§åæ¹åäºä»¶ 399 this.$button.addEventListener('click', (event) => { 400 event.stopPropagation() 401 this.$droupDowm.classList.toggle('show') 402 }) 403 404 // æç´¢å¾æ ç¹å»æ¥æ¾äºä»¶ 405 this.$incofont.addEventListener('click', (event) => { 406 event.stopPropagation() 407 this.searchData() 408 }) 409 410 // å车跳转 411 this.$input.addEventListener('keydown', (event) => { 412 event = event || window.event; 413 event.stopPropagation() 414 if (event.keyCode === 13) this.searchData() 415 }) 416 417 // ç¹å»é¡µé¢ç©ºç½ï¼æå å·²å±å¼æ ç® 418 document.querySelector('body').addEventListener('touchmove', () => { 419 this.$droupDowm.classList.remove('show') 420 }) 421 } 422 /** 423 * æç´¢æ°æ® 424 */ 425 searchData() { 426 window.app.info.pagination.page_number = 1 427 const content = this.$input.value 428 this.setAttrParams(content) 429 window.app.info.renderListView() 430 const product_list_el= this.$unit.parentNode.parentNode.parentNode.querySelector('[package-unit-type="product-list"]') 431 const list_el = this.$unit.parentNode.parentNode.parentNode.querySelector('[package-unit-type="list"]') 432 if (!list_el && !product_list_el) return 433 if(list_el) { 434 list_el.parentNode.parentNode.style.overflow = 'auto' 435 window.scrollTo({ top: list_el.getBoundingClientRect().top - 85}) 436 } 437 if(product_list_el) window.scrollTo({ behavior: 'smooth', top: product_list_el.getBoundingClientRect().top - 85}) 438 } 439 440 /** 441 * è®¾ç½®å ¨å±attr_paramsåæ° 442 * @param {string} content æ¥æ¾çå 容 443 * @returns 444 */ 445 setAttrParams(content) { 446 // å¦ææ²¡æå 容,å é¤åå¨ç 447 let attrs = window.app.info.attr_params 448 if (!content) { 449 // æ¸ ç©ºææ¬æ¥æ¾é¡¹ 450 if (attrs.length > 0) { 451 window.app.info.attr_params = attrs.filter(p => typeof p.content !== 'string') 452 } 453 return 454 } 455 // 妿å½å屿§æ¥æ¾åæ°ä¸ºç©ºï¼æ·»å 䏿¡æ°ç»è®°å½ 456 const params = { product_attr_id: this.product_attr_id, content } 457 if (attrs.length === 0) window.app.info.attr_params = [params] 458 else { 459 // æ¯å¦æææ¬æ¥æ¾é¡¹ 460 const attrInfo = attrs.find(p => typeof p.content === 'string') 461 if (attrInfo) { 462 attrInfo.product_attr_id = this.product_attr_id 463 attrInfo.content = content 464 } 465 else window.app.info.attr_params.push(params) 466 } 467 } 468 469 /** 470 * è·å产å屿§åæ° 471 */ 472}
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.