Skip to Content
🎉 探索 Shopify 的无限可能 结构化知识 + 实战案例,持续更新中...
Liquid 开发第三方集成

第三方集成

本指南将详细介绍如何在 Shopify 主题中集成各种第三方服务,提升网站功能和营销效果。

分析和跟踪集成

1. Google Analytics 4 集成

<!-- snippets/google-analytics.liquid --> {% if settings.google_analytics_id != blank %} <!-- Google Analytics 4 --> <script async src="https://www.googletagmanager.com/gtag/js?id={{ settings.google_analytics_id }}"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '{{ settings.google_analytics_id }}', { send_page_view: false, custom_map: { 'custom_parameter_1': 'shop_name', 'custom_parameter_2': 'customer_type' } }); // 发送页面浏览事件 gtag('event', 'page_view', { page_title: {{ page_title | json }}, page_location: window.location.href, shop_name: {{ shop.name | json }}, customer_type: {% if customer %}{% if customer.orders.size > 0 %}'returning'{% else %}'new'{% endif %}{% else %}'guest'{% endif %} }); // 电商事件跟踪 class GAEcommerce { static viewItem(product) { gtag('event', 'view_item', { currency: '{{ cart.currency.iso_code }}', value: product.price / 100, items: [{ item_id: product.id, item_name: product.title, item_category: product.type, item_variant: product.selected_variant?.title, price: product.price / 100, quantity: 1 }] }); } static addToCart(variant, quantity) { gtag('event', 'add_to_cart', { currency: '{{ cart.currency.iso_code }}', value: (variant.price * quantity) / 100, items: [{ item_id: variant.product.id, item_name: variant.product.title, item_category: variant.product.type, item_variant: variant.title, price: variant.price / 100, quantity: quantity }] }); } static removeFromCart(item) { gtag('event', 'remove_from_cart', { currency: '{{ cart.currency.iso_code }}', value: item.line_price / 100, items: [{ item_id: item.product.id, item_name: item.product.title, item_category: item.product.type, item_variant: item.variant.title, price: item.price / 100, quantity: item.quantity }] }); } static beginCheckout(cart) { gtag('event', 'begin_checkout', { currency: '{{ cart.currency.iso_code }}', value: cart.total_price / 100, items: cart.items.map(item => ({ item_id: item.product.id, item_name: item.product.title, item_category: item.product.type, item_variant: item.variant.title, price: item.price / 100, quantity: item.quantity })) }); } static search(query) { gtag('event', 'search', { search_term: query }); } } // 暴露到全局 window.GAEcommerce = GAEcommerce; </script> {% endif %}

2. Facebook Pixel 集成

<!-- snippets/facebook-pixel.liquid --> {% if settings.facebook_pixel_id != blank %} <!-- Facebook Pixel --> <script> !function(f,b,e,v,n,t,s) {if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)}; if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t,s)}(window, document,'script', 'https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '{{ settings.facebook_pixel_id }}'); fbq('track', 'PageView'); // 电商事件类 class FacebookPixelEcommerce { static viewContent(product) { fbq('track', 'ViewContent', { content_type: 'product', content_ids: [product.id.toString()], content_name: product.title, content_category: product.type, value: product.price / 100, currency: '{{ cart.currency.iso_code }}' }); } static addToCart(variant, quantity) { fbq('track', 'AddToCart', { content_type: 'product', content_ids: [variant.product.id.toString()], content_name: variant.product.title, value: (variant.price * quantity) / 100, currency: '{{ cart.currency.iso_code }}' }); } static initiateCheckout() { {% if cart.item_count > 0 %} fbq('track', 'InitiateCheckout', { content_type: 'product', content_ids: [{% for item in cart.items %}'{{ item.product.id }}'{% unless forloop.last %},{% endunless %}{% endfor %}], value: {{ cart.total_price | money_without_currency }}, currency: '{{ cart.currency.iso_code }}', num_items: {{ cart.item_count }} }); {% endif %} } static search(query) { fbq('track', 'Search', { search_string: query }); } static addToWishlist(product) { fbq('track', 'AddToWishlist', { content_type: 'product', content_ids: [product.id.toString()], content_name: product.title, value: product.price / 100, currency: '{{ cart.currency.iso_code }}' }); } } window.FacebookPixelEcommerce = FacebookPixelEcommerce; </script> <!-- 无JavaScript情况下的跟踪 --> <noscript> <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id={{ settings.facebook_pixel_id }}&ev=PageView&noscript=1"/> </noscript> {% endif %}

3. TikTok Pixel 集成

<!-- snippets/tiktok-pixel.liquid --> {% if settings.tiktok_pixel_id != blank %} <script> !function (w, d, t) { w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)}; ttq.load('{{ settings.tiktok_pixel_id }}'); ttq.page(); }(window, document, 'ttq'); // TikTok 电商事件 class TikTokEcommerce { static viewContent(product) { ttq.track('ViewContent', { content_type: 'product', content_id: product.id.toString(), content_name: product.title, content_category: product.type, value: product.price / 100, currency: '{{ cart.currency.iso_code }}' }); } static addToCart(variant, quantity) { ttq.track('AddToCart', { content_type: 'product', content_id: variant.product.id.toString(), content_name: variant.product.title, value: (variant.price * quantity) / 100, currency: '{{ cart.currency.iso_code }}' }); } static initiateCheckout() { ttq.track('InitiateCheckout', { value: {{ cart.total_price | money_without_currency }}, currency: '{{ cart.currency.iso_code }}' }); } } window.TikTokEcommerce = TikTokEcommerce; </script> {% endif %}

营销工具集成

1. Mailchimp 邮件订阅

<!-- snippets/mailchimp-newsletter.liquid --> <div class="newsletter-signup" data-newsletter> <div class="newsletter-content"> <h3 class="newsletter-title">{{ section.settings.heading | default: '订阅我们的邮件' }}</h3> <p class="newsletter-description">{{ section.settings.description | default: '获取最新产品和优惠信息' }}</p> </div> <form class="newsletter-form" data-newsletter-form> <div class="form-group"> <label for="newsletter-email" class="sr-only">邮箱地址</label> <input type="email" id="newsletter-email" name="email" placeholder="输入您的邮箱" class="newsletter-input" required> <button type="submit" class="newsletter-submit btn btn--primary"> <span class="btn-text">订阅</span> <span class="btn-loading" style="display: none;"> {% render 'loading-spinner' %} </span> </button> </div> <div class="newsletter-message" data-newsletter-message style="display: none;"></div> </form> </div> <script> class MailchimpNewsletter { constructor(element) { this.container = element this.form = element.querySelector('[data-newsletter-form]') this.message = element.querySelector('[data-newsletter-message]') this.submitBtn = this.form.querySelector('button[type="submit"]') this.btnText = this.submitBtn.querySelector('.btn-text') this.btnLoading = this.submitBtn.querySelector('.btn-loading') this.init() } init() { this.form.addEventListener('submit', (e) => { e.preventDefault() this.subscribe() }) } async subscribe() { const email = this.form.email.value.trim() if (!email || !this.isValidEmail(email)) { this.showMessage('请输入有效的邮箱地址', 'error') return } this.setLoading(true) try { // 使用Shopify的客户API或Mailchimp API const response = await fetch('/contact', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ 'form_type': 'customer', 'utf8': '✓', 'contact[email]': email, 'contact[tags]': 'newsletter' }) }) if (response.ok) { this.showMessage('订阅成功!感谢您的订阅。', 'success') this.form.reset() // 发送事件到分析工具 if (window.gtag) { gtag('event', 'sign_up', { method: 'email' }) } if (window.fbq) { fbq('track', 'Subscribe') } } else { throw new Error('订阅失败') } } catch (error) { this.showMessage('订阅失败,请稍后重试', 'error') console.error('Newsletter subscription error:', error) } finally { this.setLoading(false) } } isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) } setLoading(loading) { this.submitBtn.disabled = loading this.btnText.style.display = loading ? 'none' : 'inline' this.btnLoading.style.display = loading ? 'inline' : 'none' } showMessage(text, type) { this.message.textContent = text this.message.className = `newsletter-message newsletter-message--${type}` this.message.style.display = 'block' setTimeout(() => { this.message.style.display = 'none' }, 5000) } } // 初始化邮件订阅 document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('[data-newsletter]').forEach(newsletter => { new MailchimpNewsletter(newsletter) }) }) </script>

2. Klaviyo 邮件营销集成

<!-- snippets/klaviyo-integration.liquid --> {% if settings.klaviyo_public_key != blank %} <script async type="text/javascript" src="https://static.klaviyo.com/onsite/js/klaviyo.js?company_id={{ settings.klaviyo_public_key }}"></script> <script> class KlaviyoIntegration { static identify(customer) { if (window._learnq) { _learnq.push(['identify', { '$email': customer.email, '$first_name': customer.first_name, '$last_name': customer.last_name, '$phone_number': customer.phone, 'customer_id': customer.id.toString() }]); } } static track(event, properties = {}) { if (window._learnq) { _learnq.push(['track', event, properties]); } } static viewedProduct(product) { this.track('Viewed Product', { 'ProductID': product.id.toString(), 'ProductName': product.title, 'ProductURL': window.location.protocol + '//' + window.location.host + product.url, 'ProductImageURL': product.featured_image, 'Price': product.price / 100, 'CompareAtPrice': product.compare_at_price / 100, 'ProductType': product.type, 'ProductVendor': product.vendor, 'ProductTags': product.tags }); } static addedToCart(variant, quantity) { this.track('Added to Cart', { 'ProductID': variant.product.id.toString(), 'ProductName': variant.product.title, 'ProductURL': window.location.protocol + '//' + window.location.host + variant.product.url, 'ProductImageURL': variant.product.featured_image, 'Price': variant.price / 100, 'CompareAtPrice': variant.compare_at_price / 100, 'ProductType': variant.product.type, 'ProductVendor': variant.product.vendor, 'Quantity': quantity, 'VariantID': variant.id.toString(), 'VariantTitle': variant.title }); } static startedCheckout(cart) { const items = cart.items.map(item => ({ 'ProductID': item.product.id.toString(), 'ProductName': item.product.title, 'Quantity': item.quantity, 'Price': item.price / 100, 'ProductURL': window.location.protocol + '//' + window.location.host + item.product.url, 'ProductImageURL': item.product.featured_image, 'VariantID': item.variant.id.toString(), 'VariantTitle': item.variant.title })); this.track('Started Checkout', { '$event_id': cart.token, '$value': cart.total_price / 100, 'Items': items, 'CheckoutURL': window.location.protocol + '//' + window.location.host + '/cart' }); } static subscribeToNewsletter(email) { if (window._learnq) { _learnq.push(['identify', { '$email': email }]); } } } // 自动识别已登录客户 {% if customer %} KlaviyoIntegration.identify({ email: {{ customer.email | json }}, first_name: {{ customer.first_name | json }}, last_name: {{ customer.last_name | json }}, phone: {{ customer.phone | json }}, id: {{ customer.id }} }); {% endif %} window.KlaviyoIntegration = KlaviyoIntegration; </script> {% endif %}

客服和支持工具

1. Intercom 客服聊天

<!-- snippets/intercom-chat.liquid --> {% if settings.intercom_app_id != blank %} <script> window.intercomSettings = { app_id: "{{ settings.intercom_app_id }}", {% if customer %} name: "{{ customer.first_name }} {{ customer.last_name }}", email: "{{ customer.email }}", user_id: "{{ customer.id }}", created_at: {{ customer.created_at | date: '%s' }}, customer_id: "{{ customer.id }}", total_spent: {{ customer.total_spent | money_without_currency }}, orders_count: {{ customer.orders_count }}, tags: "shopify-customer" {% else %} name: "访客", tags: "shopify-visitor" {% endif %} }; </script> <script> (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/{{ settings.intercom_app_id }}';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})(); </script> {% endif %}

2. Zendesk Chat 集成

<!-- snippets/zendesk-chat.liquid --> {% if settings.zendesk_chat_key != blank %} <script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key={{ settings.zendesk_chat_key }}"></script> <script> document.addEventListener('DOMContentLoaded', function() { if (window.zE) { // 设置用户信息 {% if customer %} zE('webWidget', 'prefill', { name: { value: '{{ customer.first_name }} {{ customer.last_name }}', readOnly: true }, email: { value: '{{ customer.email }}', readOnly: true } }); // 设置用户字段 zE('webWidget', 'identify', { name: '{{ customer.first_name }} {{ customer.last_name }}', email: '{{ customer.email }}', external_id: '{{ customer.id }}', organization: '{{ shop.name }}' }); {% endif %} // 自定义聊天触发 window.ZendeskChat = { show: function() { zE('webWidget', 'open'); }, hide: function() { zE('webWidget', 'hide'); }, updateVisitorInfo: function(info) { zE('webWidget', 'identify', info); } }; } }); </script> {% endif %}

支付和金融服务

1. PayPal Express Checkout

<!-- snippets/paypal-express.liquid --> {% if settings.paypal_client_id != blank %} <div id="paypal-button-container" style="display: none;"></div> <script src="https://www.paypal.com/sdk/js?client-id={{ settings.paypal_client_id }}&currency={{ cart.currency.iso_code }}&intent=capture&components=buttons,marks"></script> <script> class PayPalExpress { constructor() { this.init() } init() { if (window.paypal && document.getElementById('paypal-button-container')) { this.renderButton() } } renderButton() { paypal.Buttons({ style: { shape: 'rect', color: 'gold', layout: 'vertical', label: 'paypal' }, createOrder: (data, actions) => { return this.createOrder(actions) }, onApprove: (data, actions) => { return this.onApprove(data, actions) }, onError: (err) => { console.error('PayPal Error:', err) this.showError('支付过程中发生错误,请重试') } }).render('#paypal-button-container') } async createOrder(actions) { try { // 获取当前购物车 const cart = await fetch('/cart.js').then(r => r.json()) const items = cart.items.map(item => ({ name: item.product_title, unit_amount: { currency_code: cart.currency, value: (item.price / 100).toFixed(2) }, quantity: item.quantity })) return actions.order.create({ purchase_units: [{ amount: { currency_code: cart.currency, value: (cart.total_price / 100).toFixed(2), breakdown: { item_total: { currency_code: cart.currency, value: (cart.total_price / 100).toFixed(2) } } }, items: items }] }) } catch (error) { console.error('Create order error:', error) throw error } } async onApprove(data, actions) { try { const order = await actions.order.capture() // 重定向到Shopify结账页面,传递PayPal信息 const checkoutUrl = `/cart/checkout?paypal_order_id=${order.id}` window.location.href = checkoutUrl } catch (error) { console.error('Capture order error:', error) this.showError('支付确认失败,请联系客服') } } showError(message) { // 显示错误消息 const errorDiv = document.createElement('div') errorDiv.className = 'paypal-error' errorDiv.textContent = message const container = document.getElementById('paypal-button-container') container.parentNode.insertBefore(errorDiv, container.nextSibling) setTimeout(() => { errorDiv.remove() }, 5000) } show() { document.getElementById('paypal-button-container').style.display = 'block' } hide() { document.getElementById('paypal-button-container').style.display = 'none' } } // 初始化PayPal Express document.addEventListener('DOMContentLoaded', () => { window.PayPalExpress = new PayPalExpress() }) </script> {% endif %}

2. Stripe Elements 集成

<!-- snippets/stripe-elements.liquid --> {% if settings.stripe_publishable_key != blank %} <script src="https://js.stripe.com/v3/"></script> <div id="stripe-elements-container" style="display: none;"> <div id="card-element"> <!-- Stripe Elements 将在这里插入卡片表单 --> </div> <div id="card-errors" role="alert"></div> <button id="stripe-submit" class="btn btn--primary"> 确认支付 </button> </div> <script> class StripeElements { constructor() { this.stripe = Stripe('{{ settings.stripe_publishable_key }}') this.elements = this.stripe.elements() this.cardElement = null this.init() } init() { this.setupCardElement() this.bindEvents() } setupCardElement() { const style = { base: { color: '#424770', fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: 'antialiased', fontSize: '16px', '::placeholder': { color: '#aab7c4' } }, invalid: { color: '#9e2146', iconColor: '#9e2146' } } this.cardElement = this.elements.create('card', { style }) this.cardElement.mount('#card-element') this.cardElement.on('change', ({ error }) => { const displayError = document.getElementById('card-errors') if (error) { displayError.textContent = error.message } else { displayError.textContent = '' } }) } bindEvents() { const submitButton = document.getElementById('stripe-submit') submitButton.addEventListener('click', () => { this.handleSubmit() }) } async handleSubmit() { const { token, error } = await this.stripe.createToken(this.cardElement) if (error) { const errorElement = document.getElementById('card-errors') errorElement.textContent = error.message } else { // 发送token到后端处理 this.submitFormWithToken(token.id) } } async submitFormWithToken(tokenId) { try { // 创建结账会话 const response = await fetch('/checkout/create-payment-intent', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ payment_method: tokenId, cart_token: {{ cart.token | json }} }) }) const session = await response.json() if (session.url) { window.location.href = session.url } else { throw new Error('Failed to create checkout session') } } catch (error) { console.error('Payment error:', error) this.showError('支付失败,请重试') } } showError(message) { const errorElement = document.getElementById('card-errors') errorElement.textContent = message } show() { document.getElementById('stripe-elements-container').style.display = 'block' } hide() { document.getElementById('stripe-elements-container').style.display = 'none' } } // 初始化Stripe Elements document.addEventListener('DOMContentLoaded', () => { window.StripeElements = new StripeElements() }) </script> {% endif %}

社交媒体集成

1. Instagram Feed

<!-- snippets/instagram-feed.liquid --> <div class="instagram-feed" data-instagram-feed> <div class="instagram-header"> <h3>{{ section.settings.heading | default: 'Instagram动态' }}</h3> {% if settings.instagram_username %} <a href="https://instagram.com/{{ settings.instagram_username }}" target="_blank" class="instagram-follow"> 关注我们 </a> {% endif %} </div> <div class="instagram-grid" data-instagram-grid> <!-- Instagram图片将通过JavaScript加载 --> </div> </div> <script> class InstagramFeed { constructor(element) { this.container = element this.grid = element.querySelector('[data-instagram-grid]') this.accessToken = '{{ settings.instagram_access_token }}' this.limit = {{ section.settings.limit | default: 6 }} if (this.accessToken) { this.loadFeed() } } async loadFeed() { try { const response = await fetch( `https://graph.instagram.com/me/media?fields=id,caption,media_type,media_url,thumbnail_url,permalink&access_token=${this.accessToken}&limit=${this.limit}` ) const data = await response.json() if (data.data) { this.renderFeed(data.data) } } catch (error) { console.error('Instagram feed error:', error) this.showError() } } renderFeed(posts) { const postsHtml = posts .filter(post => post.media_type === 'IMAGE' || post.media_type === 'CAROUSEL_ALBUM') .map(post => ` <a href="${post.permalink}" target="_blank" class="instagram-item" aria-label="查看Instagram帖子"> <img src="${post.media_url}" alt="${this.truncateCaption(post.caption)}" loading="lazy" class="instagram-image"> <div class="instagram-overlay"> <span class="instagram-icon">📷</span> </div> </a> `).join('') this.grid.innerHTML = postsHtml } truncateCaption(caption) { if (!caption) return '' return caption.length > 100 ? caption.substring(0, 100) + '...' : caption } showError() { this.grid.innerHTML = ` <div class="instagram-error"> <p>无法加载Instagram动态</p> </div> ` } } // 初始化Instagram Feed document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('[data-instagram-feed]').forEach(feed => { new InstagramFeed(feed) }) }) </script>

2. 社交分享按钮

<!-- snippets/social-sharing.liquid --> {% comment %} 社交分享按钮组件 参数: - share_title: 分享标题 (可选) - share_url: 分享链接 (可选) - share_image: 分享图片 (可选) {% endcomment %} {% assign share_title = share_title | default: page_title | url_encode %} {% assign share_url = share_url | default: canonical_url | url_encode %} {% assign share_image = share_image | default: page_image | img_url: '1200x630' | url_encode %} <div class="social-sharing"> <span class="social-sharing__label">分享:</span> <div class="social-sharing__buttons"> <!-- Facebook --> <a href="https://www.facebook.com/sharer/sharer.php?u={{ share_url }}" target="_blank" rel="noopener" class="social-sharing__button social-sharing__button--facebook" aria-label="分享到Facebook"> {% render 'icon-facebook' %} </a> <!-- Twitter --> <a href="https://twitter.com/intent/tweet?text={{ share_title }}&url={{ share_url }}" target="_blank" rel="noopener" class="social-sharing__button social-sharing__button--twitter" aria-label="分享到Twitter"> {% render 'icon-twitter' %} </a> <!-- Pinterest --> <a href="https://pinterest.com/pin/create/button/?url={{ share_url }}&media={{ share_image }}&description={{ share_title }}" target="_blank" rel="noopener" class="social-sharing__button social-sharing__button--pinterest" aria-label="分享到Pinterest"> {% render 'icon-pinterest' %} </a> <!-- WhatsApp --> <a href="https://wa.me/?text={{ share_title }}%20{{ share_url }}" target="_blank" rel="noopener" class="social-sharing__button social-sharing__button--whatsapp" aria-label="通过WhatsApp分享"> {% render 'icon-whatsapp' %} </a> <!-- 微信 --> <button type="button" class="social-sharing__button social-sharing__button--wechat" data-wechat-share aria-label="分享到微信"> {% render 'icon-wechat' %} </button> <!-- 复制链接 --> <button type="button" class="social-sharing__button social-sharing__button--copy" data-copy-link="{{ canonical_url }}" aria-label="复制链接"> {% render 'icon-link' %} </button> </div> </div> <!-- 微信分享二维码模态框 --> <div class="wechat-share-modal" data-wechat-modal style="display: none;"> <div class="wechat-share-modal__overlay"></div> <div class="wechat-share-modal__content"> <div class="wechat-share-modal__header"> <h4>微信分享</h4> <button class="wechat-share-modal__close" data-wechat-close> {% render 'icon-close' %} </button> </div> <div class="wechat-share-modal__body"> <div class="wechat-qr-code" data-wechat-qr></div> <p>使用微信扫一扫分享给朋友</p> </div> </div> </div> <script> class SocialSharing { constructor() { this.init() } init() { this.bindEvents() } bindEvents() { // 复制链接 document.addEventListener('click', (e) => { if (e.target.matches('[data-copy-link]')) { e.preventDefault() this.copyLink(e.target.dataset.copyLink) } if (e.target.matches('[data-wechat-share]')) { e.preventDefault() this.showWeChatModal() } }) // 微信模态框事件 const wechatModal = document.querySelector('[data-wechat-modal]') if (wechatModal) { wechatModal.querySelector('[data-wechat-close]').addEventListener('click', () => { this.hideWeChatModal() }) wechatModal.querySelector('.wechat-share-modal__overlay').addEventListener('click', () => { this.hideWeChatModal() }) } } async copyLink(url) { try { await navigator.clipboard.writeText(url) this.showNotification('链接已复制到剪贴板') } catch (error) { // 降级到传统方法 const textArea = document.createElement('textarea') textArea.value = url document.body.appendChild(textArea) textArea.select() document.execCommand('copy') document.body.removeChild(textArea) this.showNotification('链接已复制到剪贴板') } } showWeChatModal() { const modal = document.querySelector('[data-wechat-modal]') const qrContainer = modal.querySelector('[data-wechat-qr]') // 生成二维码 const currentUrl = window.location.href qrContainer.innerHTML = ` <img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(currentUrl)}" alt="微信分享二维码" class="wechat-qr-image"> ` modal.style.display = 'block' document.body.style.overflow = 'hidden' } hideWeChatModal() { const modal = document.querySelector('[data-wechat-modal]') modal.style.display = 'none' document.body.style.overflow = '' } showNotification(message) { const notification = document.createElement('div') notification.className = 'notification notification--success' notification.textContent = message document.body.appendChild(notification) setTimeout(() => { notification.classList.add('notification--show') }, 100) setTimeout(() => { notification.classList.remove('notification--show') setTimeout(() => notification.remove(), 300) }, 3000) } } // 初始化社交分享 document.addEventListener('DOMContentLoaded', () => { new SocialSharing() }) </script>

下一步学习

掌握第三方集成后,建议继续学习:

  1. 测试和部署 - 质量保证流程

第三方集成是提升网站功能和用户体验的重要手段!

最后更新时间: