zz-shopify-components 0.34.1-beta.23 → 0.34.1-beta.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,247 @@
1
+
2
+ <style>
3
+ .zz-scrollTrigger-block-{{ block.id }} {
4
+ width: 100%;
5
+ height: 100vh;
6
+ background-color: {{ block.settings.background_color }};
7
+ padding: 0;
8
+ margin: 0;
9
+ position: relative;
10
+ {% if block.settings.scroll_direction == 'horizontal' %}
11
+ display: flex;
12
+ overflow-x: hidden;
13
+ {% else %}
14
+ overflow: hidden;
15
+ {% endif %}
16
+ }
17
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item .responsive-width-image,
18
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item .zz-video {
19
+ aspect-ratio: 16 / 9 !important;
20
+ max-width: 45vw !important;
21
+ {% comment %} border-radius: 12px; {% endcomment %}
22
+ }
23
+
24
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item .content-video-container {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ {% comment %} border-radius: 12px; {% endcomment %}
29
+ }
30
+
31
+
32
+ {% if block.settings.scroll_direction == 'horizontal' %}
33
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item {
34
+ width: 100vw;
35
+ height: 100vh;
36
+ flex-shrink: 0;
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ position: relative;
41
+ will-change: transform;
42
+ }
43
+ {% else %}
44
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item {
45
+ width: 100%;
46
+ height: 100vh;
47
+ position: absolute;
48
+ top: 0;
49
+ left: 0;
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ will-change: transform, opacity;
54
+ }
55
+ {% endif %}
56
+
57
+
58
+ @media (max-width: 768px) {
59
+ .zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item {
60
+ height: 100vh;
61
+ width: 100%;
62
+ {% if block.settings.scroll_direction == 'horizontal' %}
63
+ width: 100vw;
64
+ padding: 0 10px;
65
+ {% else %}
66
+ padding: 0 10px;
67
+ {% endif %}
68
+ }
69
+ }
70
+ </style>
71
+
72
+ <div class="zz-scrollTrigger-block zz-scrollTrigger-block-{{ block.id }}" id="zz-scrollTrigger-block-{{ block.id }}">
73
+ {% for item in block.blocks %}
74
+ <div class="zz-scrollTrigger-item">
75
+ {% render item %}
76
+ </div>
77
+ {% endfor %}
78
+ </div>
79
+
80
+ <script>
81
+ document.addEventListener("DOMContentLoaded", () => {
82
+ if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined') {
83
+ return;
84
+ }
85
+
86
+ gsap.registerPlugin(ScrollTrigger);
87
+ ScrollTrigger.config({
88
+ ignoreMobileResize: true,
89
+ autoRefreshEvents: "visibilitychange,DOMContentLoaded,load"
90
+ });
91
+
92
+ if (window.innerWidth < 1024) {
93
+ return;
94
+ }
95
+
96
+ let items = gsap.utils.toArray('#zz-scrollTrigger-block-{{ block.id }} .zz-scrollTrigger-item');
97
+ let scrollTriggerInstances = [];
98
+
99
+ if (items.length > 1) {
100
+ {% if block.settings.scroll_direction == 'horizontal' %}
101
+ const endValue = window.innerHeight * 1.3 * (items.length - 1);
102
+
103
+ const horizontalST = gsap.to(items, {
104
+ xPercent: -100 * (items.length - 1),
105
+ ease: 'none',
106
+ scrollTrigger: {
107
+ trigger: '#zz-scrollTrigger-block-{{ block.id }}',
108
+ start: 'top top',
109
+ end: `+=${endValue}`,
110
+ pin: true,
111
+ scrub: 1,
112
+ markers: false,
113
+ {% if block.settings.enable_snap %}
114
+ snap: {
115
+ snapTo: 1 / (items.length - 1),
116
+ duration: 0.5,
117
+ delay: 0.1,
118
+ directional: false,
119
+ ease: "power2.inOut"
120
+ },
121
+ {% endif %}
122
+ }
123
+ });
124
+ scrollTriggerInstances.push(horizontalST.scrollTrigger);
125
+ {% else %}
126
+ gsap.set(items[0], { y: 0, opacity: 1 });
127
+ gsap.set(items.slice(1), { y: '10vh', opacity: 0 });
128
+
129
+ const endValue = window.innerHeight * 1 * (items.length - 1); // 增加滚动距离让动画更平滑
130
+
131
+ let tl = gsap.timeline({
132
+ scrollTrigger: {
133
+ trigger: '#zz-scrollTrigger-block-{{ block.id }}',
134
+ start: 'top top',
135
+ end: `+=${endValue}`,
136
+ pin: true,
137
+ scrub: 1,
138
+ markers: false,
139
+ {% if block.settings.enable_snap %}
140
+ snap: {
141
+ snapTo: 1 / (items.length - 1),
142
+ duration: 0.2,
143
+ delay: 0.05,
144
+ directional: true,
145
+ ease: "power2.out"
146
+ },
147
+ {% endif %}
148
+ refreshPriority: -1,
149
+ }
150
+ });
151
+ scrollTriggerInstances.push(tl.scrollTrigger);
152
+
153
+ items.forEach((item, index) => {
154
+ if (index < items.length - 1) {
155
+ let currentItem = items[index];
156
+ let nextItem = items[index + 1];
157
+
158
+ tl.to(currentItem, {
159
+ y: '-10vh',
160
+ opacity: 0,
161
+ duration: 0.1,
162
+ ease: "power2.inOut"
163
+ })
164
+ .fromTo(nextItem, {
165
+ y: '10vh',
166
+ opacity: 0
167
+ }, {
168
+ y: 0,
169
+ opacity: 1,
170
+ duration: 0.1,
171
+ ease: "power2.inOut"
172
+ });
173
+ }
174
+ });
175
+ {% endif %}
176
+ }
177
+
178
+ window.addEventListener('beforeunload', () => {
179
+ scrollTriggerInstances.forEach(st => {
180
+ if (st) st.kill();
181
+ });
182
+ });
183
+
184
+ let resizeTimeout;
185
+ {% comment %} window.addEventListener('resize', () => {
186
+ clearTimeout(resizeTimeout);
187
+ resizeTimeout = setTimeout(() => {
188
+ ScrollTrigger.refresh();
189
+ }, 250);
190
+ }); {% endcomment %}
191
+ });
192
+ </script>
193
+
194
+ {% schema %}
195
+ {
196
+ "name": "ZZ ScrollTrigger Block",
197
+ "settings": [
198
+ {
199
+ "type": "select",
200
+ "id": "scroll_direction",
201
+ "label": "滚动方向",
202
+ "options": [
203
+ {
204
+ "value": "vertical",
205
+ "label": "上下切换"
206
+ },
207
+ {
208
+ "value": "horizontal",
209
+ "label": "左右切换"
210
+ }
211
+ ],
212
+ "default": "vertical",
213
+ "info": "选择滚动的方向模式"
214
+ },
215
+ {
216
+ "type": "checkbox",
217
+ "id": "enable_snap",
218
+ "label": "启用吸附",
219
+ "default": false
220
+ },
221
+ {
222
+ "type": "color_background",
223
+ "id": "background_color",
224
+ "label": "背景颜色",
225
+ "default": "transparent"
226
+ }
227
+ ],
228
+ "blocks": [
229
+ {
230
+ "type": "@theme"
231
+ }
232
+ ],
233
+ "presets": [
234
+ {
235
+ "name": "ScrollTrigger滚动容器Block",
236
+ "blocks": [
237
+ {
238
+ "type": "zz-title",
239
+ "settings": {
240
+ "pc_title": "<p>滚动容器Block</p>"
241
+ }
242
+ }
243
+ ]
244
+ }
245
+ ]
246
+ }
247
+ {% endschema %}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zz-shopify-components",
3
- "version": "0.34.1-beta.23",
3
+ "version": "0.34.1-beta.25",
4
4
  "description": "Reusable Shopify components for theme projects",
5
5
  "keywords": [
6
6
  "shopify",
@@ -8,17 +8,59 @@
8
8
  "label": "按钮图片"
9
9
  },
10
10
  {
11
- "type": "number",
12
- "id": "mb_bottom",
13
- "label": "移动端距离底部距离",
14
- "default": 168,
11
+ "type": "number",
12
+ "id": "mb_bottom",
13
+ "label": "移动端距离底部距离",
14
+ "default": 168
15
15
  },
16
16
  {
17
- "type": "number",
18
- "id": "pc_bottom",
19
- "label": "PC端距离底部距离",
20
- "default": 88,
17
+ "type": "number",
18
+ "id": "pc_bottom",
19
+ "label": "PC端距离底部距离",
20
+ "default": 88
21
21
  },
22
+ {
23
+ "type": "text",
24
+ "id": "popup_title",
25
+ "label": "弹层标题",
26
+ "default": "Need help?"
27
+ },
28
+ {
29
+ "type": "textarea",
30
+ "id": "popup_description",
31
+ "label": "弹层描述",
32
+ "default": "Chat with our support team or reach us by email."
33
+ },
34
+ {
35
+ "type": "text",
36
+ "id": "popup_chat_title",
37
+ "label": "聊天模块标题",
38
+ "default": "Chat"
39
+ },
40
+ {
41
+ "type": "text",
42
+ "id": "popup_chat_hours",
43
+ "label": "聊天模块副标题",
44
+ "default": "Office Hours: 24/7"
45
+ },
46
+ {
47
+ "type": "text",
48
+ "id": "popup_email_title",
49
+ "label": "邮箱模块标题",
50
+ "default": "Reach us by email"
51
+ },
52
+ {
53
+ "type": "text",
54
+ "id": "popup_button_label",
55
+ "label": "聊天按钮文案",
56
+ "default": "Chat now"
57
+ },
58
+ {
59
+ "type": "text",
60
+ "id": "support_email_skpt",
61
+ "label": "联系邮箱",
62
+ "default": "support@hoverair.com"
63
+ }
22
64
  ],
23
65
  "presets": [
24
66
  {
@@ -29,133 +71,737 @@
29
71
  }
30
72
  {% endschema %}
31
73
 
32
- <script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=259dcfbd-5663-408e-9b49-e1176a029af0" defer> </script>
74
+ <script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=259dcfbd-5663-408e-9b49-e1176a029af0" defer></script>
33
75
  <script>
34
- document.addEventListener('DOMContentLoaded', function() {
35
- const section = document.getElementById(
36
- 'shopify-section-{{section.id}}'
37
- );
38
- const floatingButton = section.querySelector('.floating-button');
39
- let scrollTimeout;
40
- let isScrolling = false;
41
- let hasInsertedStyle = false;
42
- // 监听点击事件
43
- floatingButton.addEventListener('click', function() {
44
- zE('messenger', 'open');
45
- if (!hasInsertedStyle) {
46
- findTargetIframe();
76
+ document.addEventListener('DOMContentLoaded', function() {
77
+ const section = document.getElementById('shopify-section-{{ section.id }}');
78
+ if (!section) {
79
+ return;
80
+ }
81
+
82
+ const wrapper = section.querySelector('[data-live-chat-wrapper]');
83
+ const floatingButton = section.querySelector('.floating-button');
84
+ const promptPanel = section.querySelector('[data-live-chat-panel]');
85
+ const closeButton = section.querySelector('[data-live-chat-close]');
86
+ const chatNowButton = section.querySelector('[data-live-chat-open]');
87
+ const emailLink = section.querySelector('[data-live-chat-email]');
88
+ const isDesktop = window.matchMedia('(min-width: 1024px)');
89
+
90
+ if (!wrapper || !floatingButton || !promptPanel) {
91
+ return;
92
+ }
93
+
94
+ let scrollTimeout;
95
+ let hasInsertedStyle = false;
96
+ let isLogin = false;
97
+ let promptTimer = null;
98
+ let autoTriggerTimer = null;
99
+ let promptVisible = false;
100
+ let promptSource = '';
101
+ let autoInteractionBound = false;
102
+ let hasHoveredTrigger = false;
103
+ let hasClickedTrigger = false;
104
+ let hasAutoPrompted = false;
105
+
106
+ const autoInteractionEvents = [];
107
+
108
+ function safeZE() {
109
+ return typeof window.zE === 'function';
110
+ }
111
+
112
+ function findTargetIframe() {
113
+ const iframes = document.querySelectorAll('iframe');
114
+ for (let iframe of iframes) {
115
+ const parentDiv = iframe.parentElement;
116
+ const grandParentDiv = parentDiv && parentDiv.parentElement;
117
+
118
+ if (
119
+ grandParentDiv &&
120
+ grandParentDiv.style.visibility === 'visible' &&
121
+ iframe.hasAttribute('tabindex') &&
122
+ iframe.contentDocument &&
123
+ iframe.contentDocument.head
124
+ ) {
125
+ const iframeStyle = document.createElement('style');
126
+ iframeStyle.textContent = `
127
+ .bLfrDm.bLfrDm.bLfrDm {
128
+ color: white !important;
129
+ }
130
+ .cJXunt.cJXunt.cJXunt {
131
+ color: white !important;
132
+ }
133
+ .sc-vrqbdz-3.epyGsD {
134
+ color: white !important;
135
+ }
136
+ .sc-vrqbdz-3.iaizzi {
137
+ color: white !important;
138
+ }
139
+ .sc-vrqbdz-11.jSJVmY.cqORhS {
140
+ color: white !important;
141
+ }
142
+ .bUvNuD.sc-k22q4b-0.ddHFjI {
143
+ color: white !important;
144
+ }
145
+ .sc-vrqbdz-3.ipfCpo {
146
+ color: white !important;
147
+ }
148
+ .sc-vrqbdz-7.fbohUV.cqORhS {
149
+ color: white !important;
150
+ }
151
+ .sc-vrqbdz-3.cSqVoo {
152
+ color: white !important;
153
+ }
154
+ .sc-vrqbdz-11.hMbICW.cqORhS {
155
+ color: white !important;
47
156
  }
157
+ `;
158
+ iframe.contentDocument.head.appendChild(iframeStyle);
159
+ hasInsertedStyle = true;
160
+ return iframe;
161
+ }
162
+ }
163
+
164
+ setTimeout(findTargetIframe, 1000);
165
+ return null;
166
+ }
167
+
168
+ function openMessenger() {
169
+ closePrompt();
170
+ if (!safeZE()) {
171
+ return;
172
+ }
173
+ window.zE('messenger', 'open');
174
+ if (!hasInsertedStyle) {
175
+ findTargetIframe();
176
+ }
177
+ }
178
+
179
+ function clearPromptTimer() {
180
+ if (promptTimer) {
181
+ clearTimeout(promptTimer);
182
+ promptTimer = null;
183
+ }
184
+ }
185
+
186
+ function clearAutoTriggerTimer() {
187
+ if (autoTriggerTimer) {
188
+ clearTimeout(autoTriggerTimer);
189
+ autoTriggerTimer = null;
190
+ }
191
+ }
192
+
193
+ function removeAutoInteractionListeners() {
194
+ if (!autoInteractionBound) {
195
+ return;
196
+ }
197
+
198
+ autoInteractionEvents.forEach(({ target, eventName, handler, options }) => {
199
+ target.removeEventListener(eventName, handler, options);
200
+ });
201
+ autoInteractionEvents.length = 0;
202
+ autoInteractionBound = false;
203
+ }
204
+
205
+ function addAutoInteractionListener(target, eventName, handler, options) {
206
+ target.addEventListener(eventName, handler, options);
207
+ autoInteractionEvents.push({ target, eventName, handler, options });
208
+ }
209
+
210
+ function closePrompt() {
211
+ if (!promptVisible) {
212
+ clearPromptTimer();
213
+ removeAutoInteractionListeners();
214
+ section.dataset.promptVisible = 'false';
215
+ section.dataset.promptSource = '';
216
+ return;
217
+ }
218
+
219
+ promptVisible = false;
220
+ promptSource = '';
221
+ clearPromptTimer();
222
+ removeAutoInteractionListeners();
223
+ promptPanel.classList.remove('is-visible', 'is-auto', 'is-manual');
224
+ floatingButton.setAttribute('aria-expanded', 'false');
225
+ section.dataset.promptVisible = 'false';
226
+ section.dataset.promptSource = '';
227
+ }
228
+
229
+ function bindAutoInteractionClose() {
230
+ if (autoInteractionBound) {
231
+ return;
232
+ }
233
+
234
+ const handleScrollClose = function() {
235
+ closePrompt();
236
+ };
237
+
238
+ const handleOutsideClose = function(event) {
239
+ if (!wrapper.contains(event.target)) {
240
+ closePrompt();
241
+ }
242
+ };
243
+
244
+ addAutoInteractionListener(window, 'scroll', handleScrollClose, { passive: true });
245
+ addAutoInteractionListener(window, 'wheel', handleScrollClose, { passive: true });
246
+ addAutoInteractionListener(window, 'touchmove', handleScrollClose, { passive: true });
247
+ addAutoInteractionListener(document, 'click', handleOutsideClose, true);
248
+ addAutoInteractionListener(document, 'touchstart', handleOutsideClose, { capture: true, passive: true });
249
+ autoInteractionBound = true;
250
+ }
251
+
252
+ function showPrompt(source) {
253
+ clearPromptTimer();
254
+ removeAutoInteractionListeners();
255
+
256
+ promptVisible = true;
257
+ promptSource = source;
258
+ promptPanel.classList.add('is-visible');
259
+ promptPanel.classList.toggle('is-auto', source === 'auto');
260
+ promptPanel.classList.toggle('is-manual', source === 'manual');
261
+ floatingButton.setAttribute('aria-expanded', 'true');
262
+ section.dataset.promptVisible = 'true';
263
+ section.dataset.promptSource = source;
264
+
265
+ if (source === 'auto') {
266
+ bindAutoInteractionClose();
267
+ }
268
+
269
+ const timeout = source === 'auto' && !isDesktop.matches ? 10000 : 15000;
270
+ promptTimer = window.setTimeout(function() {
271
+ closePrompt();
272
+ }, timeout);
273
+ }
274
+
275
+ function scheduleAutoPrompt() {
276
+ if (hasAutoPrompted) {
277
+ return;
278
+ }
279
+
280
+ clearAutoTriggerTimer();
281
+ autoTriggerTimer = window.setTimeout(function() {
282
+ if (hasAutoPrompted || promptVisible || document.hidden) {
283
+ return;
284
+ }
285
+
286
+ if (isDesktop.matches) {
287
+ if (hasHoveredTrigger) {
288
+ return;
289
+ }
290
+ } else if (hasClickedTrigger) {
291
+ return;
292
+ }
293
+
294
+ hasAutoPrompted = true;
295
+ showPrompt('auto');
296
+ }, 10000);
297
+ }
298
+
299
+ function handleFloatingButtonClick(event) {
300
+ event.preventDefault();
301
+ hasClickedTrigger = true;
302
+
303
+ if (isDesktop.matches) {
304
+ showPrompt('manual');
305
+ return;
306
+ }
307
+
308
+ openMessenger();
309
+ }
310
+
311
+ function handleDesktopEnter() {
312
+ if (!isDesktop.matches) {
313
+ return;
314
+ }
315
+
316
+ hasHoveredTrigger = true;
317
+ showPrompt('manual');
318
+ }
319
+
320
+ function handleDesktopLeave() {
321
+ if (!isDesktop.matches) {
322
+ return;
323
+ }
324
+
325
+ if (promptSource === 'manual') {
326
+ closePrompt();
327
+ }
328
+ }
329
+
330
+ function handleScrollVisibility() {
331
+ floatingButton.classList.add('hidden');
332
+ closePrompt();
333
+ clearTimeout(scrollTimeout);
334
+ scrollTimeout = window.setTimeout(function() {
335
+ floatingButton.classList.remove('hidden');
336
+ }, 500);
337
+ }
338
+
339
+ function handleViewportChange() {
340
+ closePrompt();
341
+ scheduleAutoPrompt();
342
+ }
343
+
344
+ function checkLogin() {
345
+ if (isLogin) {
346
+ return;
347
+ }
348
+
349
+ if (window.__ZZ_ANALYTICS_CONTEXT__ && window.__ZZ_ANALYTICS_CONTEXT__.huid) {
350
+ const params = {
351
+ email_verified: true,
352
+ external_id: window.__ZZ_ANALYTICS_CONTEXT__.huid
353
+ };
354
+
355
+ if (window.__ZZ_ANALYTICS_CONTEXT__.email) {
356
+ params.email = window.__ZZ_ANALYTICS_CONTEXT__.email;
357
+ }
358
+
359
+ if (window.__ZZ_ANALYTICS_CONTEXT__.firstName || window.__ZZ_ANALYTICS_CONTEXT__.lastName) {
360
+ const nameParts = [];
361
+ if (window.__ZZ_ANALYTICS_CONTEXT__.firstName) {
362
+ nameParts.push(window.__ZZ_ANALYTICS_CONTEXT__.firstName);
363
+ }
364
+ if (window.__ZZ_ANALYTICS_CONTEXT__.lastName) {
365
+ nameParts.push(window.__ZZ_ANALYTICS_CONTEXT__.lastName);
366
+ }
367
+ params.name = nameParts.join(' ');
368
+ }
369
+
370
+ handleLogin(params);
371
+ }
372
+ }
373
+
374
+ function handleLogin(params) {
375
+ const { email_verified } = params;
376
+ isLogin = true;
377
+
378
+ if (!safeZE()) {
379
+ return;
380
+ }
381
+
382
+ window.zE('messenger', 'loginUser', function(callback) {
383
+ Promise.resolve(requestMessagingJwt(params))
384
+ .then(function(jwt) {
385
+ callback(jwt);
386
+ })
387
+ .catch(function() {
388
+ return;
389
+ });
390
+ }, function(error) {
391
+ if (error && email_verified) {
392
+ handleLogin(Object.assign({}, params, { email_verified: false }));
393
+ }
394
+ });
395
+ }
396
+
397
+ async function requestMessagingJwt(params) {
398
+ const response = await fetch('https://static.zerozeroplatform.com/zendesk-jwt', {
399
+ method: 'POST',
400
+ headers: {
401
+ 'Content-Type': 'application/json'
402
+ },
403
+ body: JSON.stringify(params || {})
404
+ });
405
+
406
+ if (!response.ok) {
407
+ throw new Error('Failed to fetch messaging jwt');
408
+ }
409
+
410
+ const data = await response.json();
411
+ if (!data || !data.jwt) {
412
+ throw new Error('Messaging jwt request failed');
413
+ }
414
+
415
+ return data.jwt;
416
+ }
417
+
418
+ function bindMessengerEvents() {
419
+ if (!safeZE()) {
420
+ return;
421
+ }
422
+
423
+ try {
424
+ window.zE('messenger:on', 'open', function() {
425
+ section.classList.add('is-messenger-open');
48
426
  });
49
-
50
- // 监听滚动事件
51
- window.addEventListener('scroll', function() {
52
- isScrolling = true;
53
- floatingButton.classList.add('hidden');
54
-
55
- // 清除之前的定时器
56
- clearTimeout(scrollTimeout);
57
-
58
- // 设置500毫秒后显示按钮
59
- scrollTimeout = setTimeout(function() {
60
- isScrolling = false;
61
- floatingButton.classList.remove('hidden');
62
- }, 500);
427
+ window.zE('messenger:on', 'close', function() {
428
+ section.classList.remove('is-messenger-open');
63
429
  });
430
+ } catch (error) {
431
+ return;
432
+ }
433
+ }
64
434
 
65
- // 综合查找方法
66
- function findTargetIframe() {
67
-
68
- const iframes = document.querySelectorAll('iframe');
69
- for (let iframe of iframes) {
70
- const parentDiv = iframe.parentElement;
71
- const grandParentDiv = parentDiv?.parentElement;
72
-
73
- // 检查结构是否符合要求
74
- if (grandParentDiv &&
75
- grandParentDiv.style.visibility === 'visible' &&
76
- iframe.hasAttribute('tabindex')) {
77
-
78
- // 向iframe中加入css样式
79
- const iframeStyle = document.createElement('style');
80
- iframeStyle.textContent = `
81
- .bLfrDm.bLfrDm.bLfrDm {
82
- color: white !important;
83
- }
84
- .cJXunt.cJXunt.cJXunt {
85
- color: white !important;
86
- }
87
- .sc-vrqbdz-3.epyGsD {
88
- color: white !important;
89
- }
90
- .sc-vrqbdz-3.iaizzi {
91
- color: white !important;
92
- }
93
- .sc-vrqbdz-11.jSJVmY.cqORhS {
94
- color: white !important;
95
- }
96
-
97
- .bUvNuD.sc-k22q4b-0.ddHFjI {
98
- color: white !important;
99
- }
100
- .sc-vrqbdz-3.ipfCpo {
101
- color: white !important;
102
- }
103
- .sc-vrqbdz-7.fbohUV.cqORhS {
104
- color: white !important;
105
- }
106
- .sc-vrqbdz-3.cSqVoo {
107
- color: white !important;
108
- }
109
- .sc-vrqbdz-11.hMbICW.cqORhS {
110
- color: white !important;
111
- }
112
-
113
- `;
114
- iframe.contentDocument.head.appendChild(iframeStyle);
115
- return iframe;
116
- }
117
- }
118
-
119
- setTimeout(findTargetIframe, 1000);
120
- return null;
121
- }
435
+ floatingButton.addEventListener('click', handleFloatingButtonClick);
436
+ wrapper.addEventListener('mouseenter', handleDesktopEnter);
437
+ wrapper.addEventListener('mouseleave', handleDesktopLeave);
438
+ window.addEventListener('scroll', handleScrollVisibility, { passive: true });
439
+
440
+ if (typeof isDesktop.addEventListener === 'function') {
441
+ isDesktop.addEventListener('change', handleViewportChange);
442
+ }
443
+
444
+ closeButton.addEventListener('click', function(event) {
445
+ event.preventDefault();
446
+ console.log('closeButton click');
447
+ closePrompt();
122
448
  });
123
- </script>
124
449
 
450
+ if (chatNowButton) {
451
+ chatNowButton.addEventListener('click', function(event) {
452
+ event.preventDefault();
453
+ openMessenger();
454
+ });
455
+ }
125
456
 
457
+ if (emailLink) {
458
+ emailLink.addEventListener('click', function() {
459
+ closePrompt();
460
+ });
461
+ }
462
+
463
+ if (typeof subscribe === 'function') {
464
+ subscribe('zz:user-session-updated', checkLogin);
465
+ }
466
+
467
+ bindMessengerEvents();
468
+ checkLogin();
469
+ scheduleAutoPrompt();
470
+ });
471
+ </script>
126
472
 
127
473
  {% if section.settings.button_image %}
128
- <button class="floating-button tw-fixed tw-z-[9999] tw-right-[16px] max-lg:tw-w-[48px] max-lg:tw-h-[48px] lg:tw-w-[64px] lg:tw-h-[64px]">
129
- {{
130
- section.settings.button_image
131
- | image_url: width: 128
132
- | image_tag:
133
- alt: "chat",
134
- class: "tw-w-full tw-h-full tw-object-cover"
135
- }}
474
+ <div class="live-chat-entry" data-live-chat-wrapper>
475
+ <div
476
+ class="live-chat-prompt is-visible"
477
+ data-live-chat-panel
478
+ role="dialog"
479
+ aria-modal="false"
480
+ aria-label="{{ section.settings.popup_title | escape }}"
481
+ >
482
+ <button type="button" class="live-chat-prompt__close--mobile lg:tw-hidden" data-live-chat-close aria-label="{{ 'accessibility.close' | t }}">
483
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
484
+ <path d="M6.34668 6.34326L17.6604 17.657" stroke="#2D2D2D" stroke-width="1.5" stroke-linecap="round"/>
485
+ <path d="M6.34668 17.6567L17.6604 6.34303" stroke="#2D2D2D" stroke-width="1.5" stroke-linecap="round"/>
486
+ </svg>
487
+
488
+ </button>
489
+ <div class="live-chat-prompt__content">
490
+ <p class="live-chat-prompt__title">{{ section.settings.popup_title | escape }}</p>
491
+ <div class="live-chat-prompt__body">
492
+ <div class="live-chat-prompt__card live-chat-prompt__card--chat">
493
+ <div class="live-chat-prompt__card-main">
494
+ <span class="live-chat-prompt__icon live-chat-prompt__icon--chat" aria-hidden="true">
495
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
496
+ <path d="M5.05554 13.5821V10.0328C5.05554 6.19751 8.16468 3.08838 12 3.08838C15.8353 3.08838 18.9444 6.19751 18.9444 10.0328V14.6987C18.9444 17.9861 16.2795 20.6511 12.9921 20.6511" stroke="black" stroke-width="1.2"/>
497
+ <path d="M7.99414 10.7126C8.49417 10.7126 8.90039 11.1189 8.90039 11.6189V13.6257C8.90031 14.1257 8.49411 14.531 7.99414 14.531H6.00586C5.50588 14.531 5.09969 14.1257 5.09961 13.6257V10.7126H7.99414Z" stroke="black" stroke-width="1.2"/>
498
+ <path d="M16.0059 10.7126C15.5058 10.7126 15.0996 11.1189 15.0996 11.6189V13.6257C15.0997 14.1257 15.5059 14.531 16.0059 14.531H17.9941C18.4941 14.531 18.9003 14.1257 18.9004 13.6257V10.7126H16.0059Z" stroke="black" stroke-width="1.2"/>
499
+ <path d="M12.7793 19.3147H12.2783C12.0012 19.3147 11.7764 19.5395 11.7764 19.8167C11.7766 20.0936 12.0013 20.3176 12.2783 20.3176H13.2812V19.8167C13.2812 19.5395 13.0564 19.3147 12.7793 19.3147Z" fill="black" stroke="black" stroke-width="2.00717"/>
500
+ </svg>
501
+
502
+ </span>
503
+ <div class="live-chat-prompt__copy">
504
+ <p class="live-chat-prompt__label">{{ section.settings.popup_chat_title | escape }}</p>
505
+ <p class="live-chat-prompt__meta tw-mt-[8px] tw-mb-[8px] lg:tw-mb-[12px]">{{ section.settings.popup_chat_hours | escape }}</p>
506
+ <button type="button" class="live-chat-prompt__cta" data-live-chat-open>
507
+ {{ section.settings.popup_button_label | escape }}
508
+ </button>
509
+ </div>
510
+ </div>
511
+
512
+ </div>
513
+ <div class="live-chat-prompt__divider" aria-hidden="true"> </div>
514
+ <a href="mailto:{{ section.settings.support_email_skpt | escape }}" class="live-chat-prompt__card live-chat-prompt__card--email" data-live-chat-email>
515
+ <div class="live-chat-prompt__card-main">
516
+ <span class="live-chat-prompt__icon live-chat-prompt__icon--email" aria-hidden="true">
517
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" focusable="false">
518
+ <rect x="4.2" y="6" width="15.6" height="12" rx="1.5" stroke="currentColor" stroke-width="1.5"></rect>
519
+ <path d="M5.5 7.5L12 12.3L18.5 7.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
520
+ </svg>
521
+ </span>
522
+ <div class="live-chat-prompt__copy">
523
+ <p class="live-chat-prompt__label">{{ section.settings.popup_email_title | escape }}</p>
524
+ <p class="live-chat-prompt__email-text">{{ section.settings.support_email_skpt | escape }}</p>
525
+ </div>
526
+ </div>
527
+ </a>
528
+ </div>
529
+ </div>
530
+ </div>
531
+
532
+ <button
533
+ class="floating-button tw-fixed tw-z-[9999] tw-right-[16px] max-lg:tw-w-[48px] max-lg:tw-h-[48px] lg:tw-w-[64px] lg:tw-h-[64px]"
534
+ aria-haspopup="dialog"
535
+ aria-expanded="false"
536
+ type="button"
537
+ >
538
+ {{
539
+ section.settings.button_image
540
+ | image_url: width: 128
541
+ | image_tag:
542
+ alt: section.settings.popup_button_label,
543
+ class: "tw-w-full tw-h-full tw-object-cover"
544
+ }}
136
545
  </button>
546
+ </div>
137
547
  {% endif %}
138
548
 
139
-
140
549
  <style>
141
- .sc-16za5ry-1 {
142
- color: white !important;
550
+ .sc-16za5ry-1 {
551
+ color: white !important;
552
+ }
553
+
554
+ .iATHzY {
555
+ color: white !important;
556
+ }
557
+
558
+ #shopify-section-{{ section.id }} .live-chat-entry {
559
+ position: fixed;
560
+ right: 16px;
561
+ bottom: {{ section.settings.mb_bottom }}px;
562
+ z-index: 9999;
563
+ display: flex;
564
+ flex-direction: column;
565
+ align-items: flex-end;
566
+ pointer-events: none;
567
+ }
568
+
569
+ #shopify-section-{{ section.id }} .live-chat-entry > * {
570
+ pointer-events: auto;
571
+ }
572
+
573
+ #shopify-section-{{ section.id }} .floating-button {
574
+ transition: opacity 0.3s ease, transform 0.3s ease;
575
+ opacity: 1;
576
+ bottom: auto;
577
+ right: auto;
578
+ position: relative;
579
+ border: 0;
580
+ background: transparent;
581
+ padding: 0;
582
+ cursor: pointer;
583
+ }
584
+
585
+ #shopify-section-{{ section.id }} .floating-button.hidden {
586
+ opacity: 0;
587
+ }
588
+
589
+ #shopify-section-{{ section.id }} .floating-button img {
590
+ display: block;
591
+ }
592
+
593
+ #shopify-section-{{ section.id }} .live-chat-prompt {
594
+ width: 318px;
595
+ border-radius: 16px;
596
+ background: #ffffff;
597
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
598
+ color: #2d2d2d;
599
+ opacity: 0;
600
+ visibility: hidden;
601
+ transform: translateY(12px);
602
+ transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
603
+ margin-bottom: 12px;
604
+ position: relative;
605
+ overflow: visible;
606
+ }
607
+
608
+ #shopify-section-{{ section.id }} .live-chat-prompt.is-visible {
609
+ opacity: 1;
610
+ visibility: visible;
611
+ transform: translateY(0);
612
+ }
613
+
614
+ #shopify-section-{{ section.id }} .live-chat-prompt__content {
615
+ padding: 20px 24px;
616
+ }
617
+
618
+ #shopify-section-{{ section.id }} .live-chat-prompt__title {
619
+ margin: 0;
620
+ font-family: Poppins, sans-serif;
621
+ font-size: 20px;
622
+ line-height: 1.5;
623
+ font-weight: 500;
624
+ letter-spacing: 0;
625
+ }
626
+
627
+ #shopify-section-{{ section.id }} .live-chat-prompt__body {
628
+ display: flex;
629
+ flex-direction: column;
630
+ gap: 24px;
631
+ margin-top: 18px;
632
+ }
633
+
634
+ #shopify-section-{{ section.id }} .live-chat-prompt__card {
635
+ color: #2d2d2d;
636
+ text-decoration: none;
637
+ }
638
+
639
+ #shopify-section-{{ section.id }} .live-chat-prompt__card-main {
640
+ display: flex;
641
+ align-items: flex-start;
642
+ gap: 12px;
643
+ min-width: 0;
644
+ flex: 1 1 auto;
645
+ }
646
+
647
+ #shopify-section-{{ section.id }} .live-chat-prompt__icon {
648
+ width: 24px;
649
+ height: 24px;
650
+ flex: 0 0 24px;
651
+ display: inline-flex;
652
+ align-items: center;
653
+ justify-content: center;
654
+ color: #2d2d2d;
655
+ }
656
+
657
+ #shopify-section-{{ section.id }} .live-chat-prompt__copy {
658
+ min-width: 0;
659
+ }
660
+
661
+ #shopify-section-{{ section.id }} .live-chat-prompt__label,
662
+ #shopify-section-{{ section.id }} .live-chat-prompt__meta,
663
+ #shopify-section-{{ section.id }} .live-chat-prompt__email-text {
664
+ letter-spacing: 0;
665
+ }
666
+
667
+ #shopify-section-{{ section.id }} .live-chat-prompt__label {
668
+ font-family: Poppins, sans-serif;
669
+ font-size: 16px;
670
+ line-height: 1.5;
671
+ font-weight: 500;
672
+ color: #2d2d2d;
673
+ }
674
+
675
+ #shopify-section-{{ section.id }} .live-chat-prompt__meta {
676
+ font-family: Poppins, sans-serif;
677
+ font-size: 14px;
678
+ line-height: 1.5;
679
+ font-weight: 400;
680
+ color: #2d2d2d;
681
+ }
682
+
683
+ #shopify-section-{{ section.id }} .live-chat-prompt__email-text {
684
+ font-family: Poppins, sans-serif;
685
+ font-size: 14px;
686
+ line-height: 1.5;
687
+ font-weight: 400;
688
+ color: #378ddd;
689
+ word-break: break-word;
690
+ }
691
+
692
+ #shopify-section-{{ section.id }} .live-chat-prompt__cta {
693
+ border: 0;
694
+ border-radius: 4px;
695
+ background: #fc6c0f;
696
+ color: #ffffff;
697
+ font-family: Poppins, sans-serif;
698
+ font-size: 14px;
699
+ line-height: 1;
700
+ font-weight: 600;
701
+ letter-spacing: 0;
702
+ padding: 10px 20px;
703
+ min-height: 36px;
704
+ cursor: pointer;
705
+ white-space: nowrap;
706
+ flex: 0 0 auto;
707
+ }
708
+
709
+ #shopify-section-{{ section.id }} .live-chat-prompt__divider {
710
+ width: 100%;
711
+ height: 1px;
712
+ background: rgba(45, 45, 45, 0.1);
713
+ }
714
+
715
+
716
+
717
+ #shopify-section-{{ section.id }}.is-messenger-open .live-chat-entry {
718
+ opacity: 0;
719
+ visibility: hidden;
720
+ pointer-events: none;
721
+ }
722
+
723
+ @media (min-width: 1024px) {
724
+ #shopify-section-{{ section.id }} .live-chat-entry {
725
+ bottom: {{ section.settings.pc_bottom }}px;
726
+ }
727
+
728
+ #shopify-section-{{ section.id }} .live-chat-prompt {
729
+ margin-bottom: 16px;
730
+ }
731
+
732
+ }
733
+
734
+ @media (max-width: 1023px) {
735
+ #shopify-section-{{ section.id }} .live-chat-entry {
736
+ right: 16px;
737
+ align-items: flex-end;
143
738
  }
144
- .iATHzY {
145
- color: white !important;
739
+
740
+ #shopify-section-{{ section.id }} .live-chat-prompt {
741
+
742
+ width: 252px;
743
+ border-radius: 10px;
744
+ align-self: stretch;
745
+ margin-bottom: 12px;
746
+ border-radius: 10px;
747
+ transform: translateY(16px);
146
748
  }
147
- #shopify-section-{{ section.id }} .floating-button {
148
- transition: opacity 0.3s ease;
149
- opacity: 1;
150
- bottom: {{ section.settings.mb_bottom }}px;
749
+ #shopify-section-{{ section.id }} .live-chat-prompt__label {
750
+ font-size: 14px;
151
751
  }
152
- #shopify-section-{{ section.id }} .floating-button.hidden {
153
- opacity: 0;
752
+ #shopify-section-{{ section.id }} .live-chat-prompt__meta {
753
+ font-size: 12px;
154
754
  }
155
- @media (min-width: 1024px) {
156
- #shopify-section-{{ section.id }} .floating-button {
157
- bottom: {{ section.settings.pc_bottom }}px;
158
- }
755
+
756
+ #shopify-section-{{ section.id }} .live-chat-prompt.is-visible {
757
+ transform: translateY(0);
159
758
  }
160
-
759
+
760
+ #shopify-section-{{ section.id }} .live-chat-prompt__content {
761
+ padding:20px 24px;
762
+ }
763
+
764
+ #shopify-section-{{ section.id }} .live-chat-prompt__title {
765
+ font-size: 16px;
766
+ color: #2D2D2D;
767
+ line-height: 1.5;
768
+ }
769
+
770
+ #shopify-section-{{ section.id }} .live-chat-prompt__body {
771
+ margin-top: 16px;
772
+ gap: 20px;
773
+ }
774
+
775
+ #shopify-section-{{ section.id }} .live-chat-prompt__card {
776
+ align-items: flex-start;
777
+ }
778
+
779
+ #shopify-section-{{ section.id }} .live-chat-prompt__card--chat {
780
+ flex-direction: column;
781
+ align-items: stretch;
782
+ gap: 16px;
783
+ }
784
+
785
+ #shopify-section-{{ section.id }} .live-chat-prompt__card-main {
786
+ width: 100%;
787
+ }
788
+
789
+ #shopify-section-{{ section.id }} .live-chat-prompt__close--mobile {
790
+ position: absolute;
791
+ top: -16px;
792
+ border: 1px solid rgba(45, 45, 45, 0.08);
793
+ box-shadow: 0px 4px 4px 0px #0000001A;
794
+ border-radius: 9999px;
795
+ background: #f6f6f6;
796
+ color: #2d2d2d;
797
+ padding: 0;
798
+ width: 32px;
799
+ height: 32px;
800
+ cursor: pointer;
801
+ display: inline-flex;
802
+ align-items: center;
803
+ justify-content: center;
804
+ left: -16px;
805
+ }
806
+ }
161
807
  </style>