1$(document).ready(function () { 2 // ==================== ç¼åéæ©å¨ ==================== 3 const $tabContainer = $('.oc-maon-sam-product-detail-tab') 4 const $tabBtns = $tabContainer.find('.tab-btns .tab-btn') 5 const $contents = $('.content-div') 6 const $tabsWrapper = $tabContainer.find('.tab-btns') 7 const $box = $tabContainer.find('.tab-btns-content') 8 const $leftBtn = $tabContainer.find('.tab-btn-left') 9 const $rightBtn = $tabContainer.find('.tab-btn-right') 10 11 const $headerMobile = $('.oc-main-sam-header-mobile') 12 const $headerPC = $('.oc-main-sam-header-pc') 13 14 const step = 200 // 左峿»å¨æ¥é¿ï¼å¯æ ¹æ®å®é Tab å®½åº¦è°æ´ 15 16 let isSticky = false 17 let ticking = false 18 19 // ==================== Tab 忢 ==================== 20 function switchTab(target) { 21 $contents.hide() 22 $tabBtns.removeClass('active') 23 24 $('#' + target).show() 25 $tabBtns.filter(`[data-target="${target}"]`).addClass('active') 26 27 // æ»å¨å° Tab åºåé¡¶é¨ 28 const scrollTarget = $tabContainer.offset().top - getHeaderHeight() 29 $('html, body').animate({ scrollTop: scrollTarget }, 300) 30 } 31 32 $tabBtns.on('click', function () { 33 const target = $(this).data('target') 34 switchTab(target) 35 updateStickyBounds() 36 37 }) 38 39 // é»è®¤æ¿æ´»ç¬¬ä¸ä¸ª Tab 40 const $firstBtn = $tabBtns.first() 41 if ($firstBtn.length) { 42 $firstBtn.addClass('active') 43 $contents.first().show() 44 } 45 46 // ==================== è·åå½å Header é«åº¦ ==================== 47 function getHeaderHeight() { 48 if (window.innerWidth <= 1025) { 49 return $headerMobile.hasClass('hide') ? 0 : $headerMobile.outerHeight() 50 } 51 return $headerPC.height() || 0 52 } 53 54 // ==================== Sticky Tabs (ç§»å¨ç«¯) ==================== 55 function handleMobileSticky() { 56 const headerHeight = getHeaderHeight() 57 const tabRect = $tabsWrapper[0].getBoundingClientRect() 58 59 if (tabRect.top <= headerHeight) { 60 $tabsWrapper.css('top', headerHeight + 'px') 61 } else { 62 $tabsWrapper.css('top', '0') 63 } 64 } 65 66 // ==================== Sticky Tabs (PC端ï¼ä½¿ç¨åçæ´æµç ) ==================== 67 const tabsContainer = document.querySelector('.oc-maon-sam-product-detail-tab .tab-btns') 68 const contentArea = document.querySelector('.oc-maon-sam-product-detail-tab .tab-content') 69 const placeholder = document.querySelector('.oc-maon-sam-product-detail-tab .tab-placeholder') 70 71 let stickyTop = 0 72 let contentBottom = 0 73 74 function updateStickyBounds() { 75 if (placeholder) stickyTop = placeholder.offsetTop 76 if (contentArea) contentBottom = contentArea.offsetTop + contentArea.offsetHeight 77 } 78 79 function handlePCSticky() { 80 if (!tabsContainer) return 81 const scrollY = window.scrollY 82 const shouldSticky = scrollY > stickyTop + 5 && scrollY < contentBottom - 5 83 84 if (shouldSticky === isSticky) return 85 86 isSticky = shouldSticky 87 tabsContainer.classList.toggle('sticky', shouldSticky) 88 } 89 90 // ==================== Tab å·¦å³ç®å¤´æ§å¶ ==================== 91 function updateArrowStatus() { 92 if (window.innerWidth > 1025) return 93 94 const scrollLeft = $box.scrollLeft() 95 const clientWidth = $box.outerWidth() 96 const scrollWidth = $box[0].scrollWidth 97 98 $leftBtn.toggle(scrollLeft > 0) 99 $rightBtn.toggle(scrollLeft + clientWidth < scrollWidth - 1) 100 } 101 102 $rightBtn.on('click', function () { 103 $box.animate({ scrollLeft: $box.scrollLeft() + step }, 300, updateArrowStatus) 104 }) 105 106 $leftBtn.on('click', function () { 107 $box.animate({ scrollLeft: $box.scrollLeft() - step }, 300, updateArrowStatus) 108 }) 109 110 $box.on('scroll', updateArrowStatus) 111 112 // ==================== æ»å¨ & Resize äºä»¶ ==================== 113 function onScroll() { 114 if (window.innerWidth <= 1025) { 115 handleMobileSticky() 116 } else { 117 if (ticking) return 118 ticking = true 119 requestAnimationFrame(() => { 120 handlePCSticky() 121 ticking = false 122 }) 123 } 124 } 125 126 $(window).on('scroll', onScroll) 127 $(window).on('resize', () => { 128 updateStickyBounds() 129 handleMobileSticky() 130 updateArrowStatus() 131 }) 132 133 // åå§å
134 function init() { 135 updateStickyBounds() 136 updateArrowStatus() 137 // 馿¬¡å è½½æ¶æ§è¡ä¸æ¬¡ sticky 夿 138 setTimeout(() => { 139 onScroll() 140 }, 100) 141 } 142 143 init() 144})
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.