1import { Controller } from "@hotwired/stimulus" 2import { showToast } from "utils/toast" 3 4// ä¸»é¡µäº¤äºæ§å¶å¨ 5export default class extends Controller { 6 static targets = ["ctaButton", "pricingButton", "backgroundVideo"] 7 static values = { 8 teamContactMessage: String, 9 loadingText: String 10 } 11 12 connect() { 13 console.log("Homepage controller connected") 14 this.setupSmoothScrolling() 15 this.setupButtonAnimations() 16 this.initializeBackgroundVideo() 17 } 18 19 // åå§åèæ¯è§é¢ - å»¶è¿å 载以æå页é¢å è½½é度 20 initializeBackgroundVideo() { 21 const heroVideo = this.element.querySelector('[data-video-src]') 22 23 if (heroVideo) { 24 // çå¾ é¡µé¢å è½½å®æååå è½½è§é¢ 25 if (document.readyState === 'complete') { 26 this.loadHeroVideo(heroVideo) 27 } else { 28 window.addEventListener('load', () => { 29 // 页é¢å è½½å®æååçå¾ 1ç§ï¼ç¡®ä¿å ³é®å 容已渲æ 30 setTimeout(() => { 31 this.loadHeroVideo(heroVideo) 32 }, 1000) 33 }) 34 } 35 } 36 } 37 38 loadHeroVideo(video) { 39 const videoSrc = video.dataset.videoSrc 40 if (!videoSrc) return 41 42 // 设置è§é¢æº 43 const source = document.createElement('source') 44 source.src = videoSrc 45 source.type = 'video/mp4' 46 video.appendChild(source) 47 48 // ç¡®ä¿è§é¢å±æ§æ£ç¡®è®¾ç½® 49 video.muted = true 50 video.playsInline = true 51 video.loop = true 52 53 // å è½½å¹¶ææ¾è§é¢ 54 video.load() 55 video.play().catch(error => { 56 console.log('èæ¯è§é¢ææ¾å¤±è´¥:', error) 57 }) 58 } 59 60 // è®¾ç½®å¹³æ»æ»å¨ 61 setupSmoothScrolling() { 62 document.querySelectorAll('a[href^="#"]').forEach(anchor => { 63 anchor.addEventListener('click', function (e) { 64 e.preventDefault() 65 const target = document.querySelector(this.getAttribute('href')) 66 if (target) { 67 target.scrollIntoView({ 68 behavior: 'smooth', 69 block: 'start' 70 }) 71 } 72 }) 73 }) 74 } 75 76 // 设置æé®å¨ç» 77 setupButtonAnimations() { 78 // ä¸ºææ CTA æé®æ·»å ç¹å»ææ 79 document.querySelectorAll('.cta-button, .bg-info-600, .bg-ink-900').forEach(button => { 80 button.addEventListener('click', function(e) { 81 // æ·»å æé®ç¹å»å¨ç» 82 this.style.transform = 'scale(0.95)' 83 setTimeout(() => { 84 this.style.transform = 'scale(1)' 85 }, 150) 86 }) 87 }) 88 } 89 90 // å¢éçéå®èç³» 91 contactSales(event) { 92 event.preventDefault() 93 94 // ææ¡ç±æå¡ç«¯éè¿ data-value æ³¨å ¥ï¼å·²æ¬å°åï¼ 95 const customMessage = event.currentTarget.dataset.homepageSalesMessage 96 showToast('success', customMessage || this.teamContactMessageValue) 97 } 98 99 // å¤ç注åæé®ç¹å» 100 handleSignup(event) { 101 // å¯ä»¥å¨è¿éæ·»å åæè·è¸ª 102 console.log("User clicked signup button") 103 104 // 妿éè¦ï¼å¯ä»¥å¨è¿éæ·»å å è½½ç¶æ 105 const button = event.currentTarget 106 const originalText = button.textContent 107 108 // å è½½ææ¡ç±æå¡ç«¯éè¿ data-value æ³¨å ¥ï¼å·²æ¬å°åï¼ 109 button.textContent = this.loadingTextValue 110 button.style.opacity = "0.8" 111 112 // æ¢å¤æé®ç¶æï¼ä»¥é²å¯¼èªå¤±è´¥ï¼ 113 setTimeout(() => { 114 button.textContent = originalText 115 button.style.opacity = "1" 116 }, 2000) 117 } 118 119}
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.