customer-chat-sdk 1.1.0 → 1.1.1
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.
- package/dist/core/IconManager.d.ts +12 -0
- package/dist/core/IconManager.d.ts.map +1 -1
- package/dist/core/IframeManager.d.ts +3 -2
- package/dist/core/IframeManager.d.ts.map +1 -1
- package/dist/customer-sdk.cjs.js +212 -79
- package/dist/customer-sdk.esm.js +212 -79
- package/dist/customer-sdk.min.js +2 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/customer-sdk.esm.js
CHANGED
|
@@ -13,8 +13,12 @@ class IconManager {
|
|
|
13
13
|
this.iconStartY = 0;
|
|
14
14
|
this.dragMoveHandler = null;
|
|
15
15
|
this.dragEndHandler = null;
|
|
16
|
+
this.checkDragHandler = null; // 临时拖动检测监听器
|
|
17
|
+
this.dragStartHandler = null; // 拖动开始事件监听器
|
|
18
|
+
this.touchStartHandler = null; // 触摸开始事件监听器
|
|
16
19
|
this.iconPosition = null; // 图标位置配置
|
|
17
20
|
this.debug = false; // debug 模式标志
|
|
21
|
+
this.isClickEnabled = true; // 是否允许点击(iframe 打开时禁用)
|
|
18
22
|
this.iconPosition = position || null;
|
|
19
23
|
this.debug = debug;
|
|
20
24
|
}
|
|
@@ -30,7 +34,7 @@ class IconManager {
|
|
|
30
34
|
this.iconElement.className = 'customer-sdk-icon';
|
|
31
35
|
// 直接设置样式 - 图标容器
|
|
32
36
|
const defaultStyle = {
|
|
33
|
-
position: '
|
|
37
|
+
position: 'absolute',
|
|
34
38
|
width: '30px',
|
|
35
39
|
height: '30px',
|
|
36
40
|
backgroundColor: 'transparent', // 移除背景色,让图片直接显示
|
|
@@ -39,7 +43,7 @@ class IconManager {
|
|
|
39
43
|
alignItems: 'center',
|
|
40
44
|
justifyContent: 'center',
|
|
41
45
|
cursor: 'pointer',
|
|
42
|
-
zIndex: '
|
|
46
|
+
zIndex: '1000002', // 确保图标始终在最上层(遮罩层 999998,iframe 容器 999999)
|
|
43
47
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
|
|
44
48
|
userSelect: 'none',
|
|
45
49
|
transition: 'transform 0.2s ease',
|
|
@@ -266,9 +270,11 @@ class IconManager {
|
|
|
266
270
|
// 绑定事件处理器(用于后续清理)
|
|
267
271
|
this.dragMoveHandler = this.handleDragMove.bind(this);
|
|
268
272
|
this.dragEndHandler = this.handleDragEnd.bind(this);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
this.iconElement.addEventListener('
|
|
273
|
+
this.dragStartHandler = this.handleDragStart.bind(this);
|
|
274
|
+
// 只在图标上监听开始事件(保存引用以便后续移除)
|
|
275
|
+
this.iconElement.addEventListener('mousedown', this.dragStartHandler);
|
|
276
|
+
this.touchStartHandler = this.handleDragStart.bind(this);
|
|
277
|
+
this.iconElement.addEventListener('touchstart', this.touchStartHandler, { passive: false });
|
|
272
278
|
}
|
|
273
279
|
/**
|
|
274
280
|
* 开始拖动
|
|
@@ -291,12 +297,33 @@ class IconManager {
|
|
|
291
297
|
const rect = this.iconElement.getBoundingClientRect();
|
|
292
298
|
this.iconStartX = rect.left;
|
|
293
299
|
this.iconStartY = rect.top;
|
|
294
|
-
//
|
|
295
|
-
|
|
296
|
-
this.iconElement.style.cursor = 'grabbing';
|
|
300
|
+
// 注意:不要在这里立即移除 transition 和设置 cursor
|
|
301
|
+
// 只有在真正开始拖动时才修改样式,避免点击时图标位置跳动
|
|
297
302
|
// 只在真正开始拖动时添加document事件监听
|
|
298
303
|
// 先添加一个临时的move监听器来检测是否真的在拖动
|
|
299
304
|
const checkDrag = (moveEvent) => {
|
|
305
|
+
// 检测事件目标:如果事件发生在iframe或其他元素上,停止检测拖动
|
|
306
|
+
const target = moveEvent.target;
|
|
307
|
+
if (target && target !== this.iconElement && !this.iconElement?.contains(target)) {
|
|
308
|
+
// 检查是否是iframe相关元素
|
|
309
|
+
const isIframeElement = target.tagName === 'IFRAME' ||
|
|
310
|
+
target.closest('iframe') ||
|
|
311
|
+
target.closest('.customer-sdk-container') ||
|
|
312
|
+
target.closest('.customer-sdk-overlay');
|
|
313
|
+
if (isIframeElement) {
|
|
314
|
+
// 如果事件发生在iframe相关元素上,停止检测并清理监听器
|
|
315
|
+
if (this.checkDragHandler) {
|
|
316
|
+
if ('touches' in moveEvent) {
|
|
317
|
+
document.removeEventListener('touchmove', this.checkDragHandler);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
document.removeEventListener('mousemove', this.checkDragHandler);
|
|
321
|
+
}
|
|
322
|
+
this.checkDragHandler = null;
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
300
327
|
const moveX = 'touches' in moveEvent ? moveEvent.touches[0].clientX : moveEvent.clientX;
|
|
301
328
|
const moveY = 'touches' in moveEvent ? moveEvent.touches[0].clientY : moveEvent.clientY;
|
|
302
329
|
const deltaX = moveX - this.dragStartX;
|
|
@@ -304,12 +331,20 @@ class IconManager {
|
|
|
304
331
|
// 如果移动距离超过5px,开始拖动
|
|
305
332
|
if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
|
|
306
333
|
this.isDragging = true;
|
|
307
|
-
//
|
|
308
|
-
if (
|
|
309
|
-
|
|
334
|
+
// 只有在真正开始拖动时才移除 transition 和设置 cursor
|
|
335
|
+
if (this.iconElement) {
|
|
336
|
+
this.iconElement.style.transition = 'none';
|
|
337
|
+
this.iconElement.style.cursor = 'grabbing';
|
|
310
338
|
}
|
|
311
|
-
|
|
312
|
-
|
|
339
|
+
// 移除临时监听器
|
|
340
|
+
if (this.checkDragHandler) {
|
|
341
|
+
if ('touches' in moveEvent) {
|
|
342
|
+
document.removeEventListener('touchmove', this.checkDragHandler);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
document.removeEventListener('mousemove', this.checkDragHandler);
|
|
346
|
+
}
|
|
347
|
+
this.checkDragHandler = null;
|
|
313
348
|
}
|
|
314
349
|
// 添加正式的事件监听器
|
|
315
350
|
if (this.dragMoveHandler && this.dragEndHandler) {
|
|
@@ -324,13 +359,15 @@ class IconManager {
|
|
|
324
359
|
}
|
|
325
360
|
}
|
|
326
361
|
};
|
|
362
|
+
// 保存 checkDrag 引用,以便后续清理
|
|
363
|
+
this.checkDragHandler = checkDrag;
|
|
327
364
|
// 添加临时检测监听器
|
|
328
365
|
if ('touches' in e) {
|
|
329
|
-
document.addEventListener('touchmove',
|
|
366
|
+
document.addEventListener('touchmove', this.checkDragHandler, { passive: false });
|
|
330
367
|
document.addEventListener('touchend', this.dragEndHandler);
|
|
331
368
|
}
|
|
332
369
|
else {
|
|
333
|
-
document.addEventListener('mousemove',
|
|
370
|
+
document.addEventListener('mousemove', this.checkDragHandler);
|
|
334
371
|
document.addEventListener('mouseup', this.dragEndHandler);
|
|
335
372
|
}
|
|
336
373
|
}
|
|
@@ -342,20 +379,9 @@ class IconManager {
|
|
|
342
379
|
return;
|
|
343
380
|
const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
|
|
344
381
|
const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// 检查是否是iframe相关元素
|
|
349
|
-
const isIframeElement = target.tagName === 'IFRAME' ||
|
|
350
|
-
target.closest('iframe') ||
|
|
351
|
-
target.closest('.customer-sdk-container') ||
|
|
352
|
-
target.closest('.customer-sdk-overlay');
|
|
353
|
-
if (isIframeElement) {
|
|
354
|
-
// 如果事件发生在iframe相关元素上,停止拖动
|
|
355
|
-
this.handleDragEnd();
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
382
|
+
// 注意:拖动过程中不检测 iframe 元素,因为用户可能只是想将图标拖动到 iframe 附近或上方
|
|
383
|
+
// 只有在拖动开始时(checkDrag 阶段)才检测 iframe,防止误判为拖动
|
|
384
|
+
// 一旦开始拖动,就应该允许拖动到任何位置,包括 iframe 上方
|
|
359
385
|
// 计算从拖动开始位置到当前位置的距离
|
|
360
386
|
const deltaX = clientX - this.dragStartX;
|
|
361
387
|
const deltaY = clientY - this.dragStartY;
|
|
@@ -390,10 +416,15 @@ class IconManager {
|
|
|
390
416
|
/**
|
|
391
417
|
* 结束拖动
|
|
392
418
|
*/
|
|
393
|
-
handleDragEnd(
|
|
419
|
+
handleDragEnd(_e) {
|
|
394
420
|
if (!this.iconElement)
|
|
395
421
|
return;
|
|
396
|
-
// 清理document
|
|
422
|
+
// 清理document上的所有事件监听器(包括临时检测监听器)
|
|
423
|
+
if (this.checkDragHandler) {
|
|
424
|
+
document.removeEventListener('mousemove', this.checkDragHandler);
|
|
425
|
+
document.removeEventListener('touchmove', this.checkDragHandler);
|
|
426
|
+
this.checkDragHandler = null;
|
|
427
|
+
}
|
|
397
428
|
if (this.dragMoveHandler) {
|
|
398
429
|
document.removeEventListener('mousemove', this.dragMoveHandler);
|
|
399
430
|
document.removeEventListener('touchmove', this.dragMoveHandler);
|
|
@@ -402,6 +433,8 @@ class IconManager {
|
|
|
402
433
|
document.removeEventListener('mouseup', this.dragEndHandler);
|
|
403
434
|
document.removeEventListener('touchend', this.dragEndHandler);
|
|
404
435
|
}
|
|
436
|
+
// 恢复样式(如果之前被修改过)
|
|
437
|
+
// 注意:如果只是点击(没有拖动),这些样式可能没有被修改,但恢复操作是安全的
|
|
405
438
|
this.iconElement.style.transition = 'transform 0.2s ease';
|
|
406
439
|
this.iconElement.style.cursor = 'pointer';
|
|
407
440
|
// 如果只是点击(没有拖动),触发点击事件
|
|
@@ -414,10 +447,52 @@ class IconManager {
|
|
|
414
447
|
* 处理点击事件
|
|
415
448
|
*/
|
|
416
449
|
handleClick() {
|
|
450
|
+
// 如果点击被禁用(iframe 打开时),不执行点击回调
|
|
451
|
+
if (!this.isClickEnabled) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
417
454
|
if (this.onClickCallback) {
|
|
418
455
|
this.onClickCallback();
|
|
419
456
|
}
|
|
420
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* 禁用点击和拖拽(iframe 打开时调用)
|
|
460
|
+
*/
|
|
461
|
+
disableClick() {
|
|
462
|
+
this.isClickEnabled = false;
|
|
463
|
+
// 移除拖动事件监听器
|
|
464
|
+
if (this.iconElement) {
|
|
465
|
+
if (this.dragStartHandler) {
|
|
466
|
+
this.iconElement.removeEventListener('mousedown', this.dragStartHandler);
|
|
467
|
+
}
|
|
468
|
+
if (this.touchStartHandler) {
|
|
469
|
+
this.iconElement.removeEventListener('touchstart', this.touchStartHandler);
|
|
470
|
+
}
|
|
471
|
+
// 禁用所有鼠标事件(包括点击和拖拽)
|
|
472
|
+
this.iconElement.style.pointerEvents = 'none';
|
|
473
|
+
this.iconElement.style.cursor = 'default';
|
|
474
|
+
}
|
|
475
|
+
// 清理可能正在进行的拖动
|
|
476
|
+
this.forceCleanupDragEvents();
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* 启用点击和拖拽(iframe 关闭时调用)
|
|
480
|
+
*/
|
|
481
|
+
enableClick() {
|
|
482
|
+
this.isClickEnabled = true;
|
|
483
|
+
// 重新添加拖动事件监听器
|
|
484
|
+
if (this.iconElement) {
|
|
485
|
+
if (this.dragStartHandler) {
|
|
486
|
+
this.iconElement.addEventListener('mousedown', this.dragStartHandler);
|
|
487
|
+
}
|
|
488
|
+
if (this.touchStartHandler) {
|
|
489
|
+
this.iconElement.addEventListener('touchstart', this.touchStartHandler, { passive: false });
|
|
490
|
+
}
|
|
491
|
+
// 恢复鼠标事件
|
|
492
|
+
this.iconElement.style.pointerEvents = 'auto';
|
|
493
|
+
this.iconElement.style.cursor = 'pointer';
|
|
494
|
+
}
|
|
495
|
+
}
|
|
421
496
|
/**
|
|
422
497
|
* 创建消息徽章(简化版)
|
|
423
498
|
*/
|
|
@@ -483,7 +558,7 @@ class IframeManager {
|
|
|
483
558
|
this.config = {
|
|
484
559
|
src: '',
|
|
485
560
|
mode: 'auto', // 默认自动检测设备类型
|
|
486
|
-
width:
|
|
561
|
+
width: 450, // PC 模式默认宽度
|
|
487
562
|
height: 600,
|
|
488
563
|
allowClose: true,
|
|
489
564
|
...config
|
|
@@ -523,9 +598,9 @@ class IframeManager {
|
|
|
523
598
|
try {
|
|
524
599
|
const actualMode = this.getActualMode();
|
|
525
600
|
const isPC = actualMode === 'popup';
|
|
526
|
-
//
|
|
601
|
+
// PC模式:创建或显示遮罩层
|
|
527
602
|
if (isPC) {
|
|
528
|
-
this.createOverlay();
|
|
603
|
+
this.createOverlay(); // createOverlay 内部会检查是否已存在
|
|
529
604
|
}
|
|
530
605
|
// 显示已创建的容器
|
|
531
606
|
if (this.containerElement) {
|
|
@@ -540,8 +615,18 @@ class IframeManager {
|
|
|
540
615
|
opacity: '1',
|
|
541
616
|
display: 'block'
|
|
542
617
|
});
|
|
543
|
-
//
|
|
544
|
-
|
|
618
|
+
// 关键优化:避免重复移动容器导致 iframe 重新加载
|
|
619
|
+
// 只有当容器不在遮罩层内时才移动,且确保遮罩层在 DOM 中
|
|
620
|
+
if (this.overlayElement) {
|
|
621
|
+
// 如果遮罩层不在 DOM 中,先添加到 DOM
|
|
622
|
+
if (!this.overlayElement.parentNode) {
|
|
623
|
+
document.body.appendChild(this.overlayElement);
|
|
624
|
+
}
|
|
625
|
+
// 只有当容器不在遮罩层内时才移动(避免重复移动导致 iframe 重新加载)
|
|
626
|
+
if (this.containerElement.parentNode !== this.overlayElement) {
|
|
627
|
+
this.overlayElement.appendChild(this.containerElement);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
545
630
|
}
|
|
546
631
|
else {
|
|
547
632
|
// 移动端模式:直接全屏显示,不需要遮罩层
|
|
@@ -578,22 +663,27 @@ class IframeManager {
|
|
|
578
663
|
if (!this.isOpen) {
|
|
579
664
|
return;
|
|
580
665
|
}
|
|
581
|
-
// 隐藏容器但保留DOM
|
|
666
|
+
// 隐藏容器但保留DOM元素(不移动容器,避免 iframe 重新加载)
|
|
582
667
|
if (this.containerElement) {
|
|
583
668
|
Object.assign(this.containerElement.style, {
|
|
584
669
|
visibility: 'hidden',
|
|
585
670
|
opacity: '0',
|
|
586
671
|
display: 'none'
|
|
587
672
|
});
|
|
673
|
+
// 注意:不移动容器,保持容器在当前位置(遮罩层或 body),避免 iframe 重新加载
|
|
588
674
|
}
|
|
589
|
-
//
|
|
675
|
+
// 隐藏遮罩层但不移除(仅PC模式,避免重新创建导致 iframe 重新加载)
|
|
590
676
|
if (this.overlayElement) {
|
|
591
|
-
this.overlayElement.
|
|
592
|
-
|
|
677
|
+
Object.assign(this.overlayElement.style, {
|
|
678
|
+
visibility: 'hidden',
|
|
679
|
+
opacity: '0',
|
|
680
|
+
display: 'none'
|
|
681
|
+
});
|
|
682
|
+
// 不移除遮罩层,下次显示时直接显示即可
|
|
593
683
|
}
|
|
594
684
|
// 恢复body滚动(移动端模式)
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
685
|
+
const actualModeForScroll = this.getActualMode();
|
|
686
|
+
if (actualModeForScroll === 'fullscreen') {
|
|
597
687
|
this.preventBodyScroll(false);
|
|
598
688
|
}
|
|
599
689
|
this.isOpen = false;
|
|
@@ -641,9 +731,29 @@ class IframeManager {
|
|
|
641
731
|
}
|
|
642
732
|
}
|
|
643
733
|
/**
|
|
644
|
-
*
|
|
734
|
+
* 创建遮罩层(PC模式使用)
|
|
645
735
|
*/
|
|
646
736
|
createOverlay() {
|
|
737
|
+
// 如果遮罩层已存在,直接显示即可
|
|
738
|
+
if (this.overlayElement && this.overlayElement.parentNode) {
|
|
739
|
+
Object.assign(this.overlayElement.style, {
|
|
740
|
+
visibility: 'visible',
|
|
741
|
+
opacity: '1',
|
|
742
|
+
display: 'flex'
|
|
743
|
+
});
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
// 如果遮罩层存在但不在 DOM 中,重新添加到 DOM
|
|
747
|
+
if (this.overlayElement && !this.overlayElement.parentNode) {
|
|
748
|
+
document.body.appendChild(this.overlayElement);
|
|
749
|
+
Object.assign(this.overlayElement.style, {
|
|
750
|
+
visibility: 'visible',
|
|
751
|
+
opacity: '1',
|
|
752
|
+
display: 'flex'
|
|
753
|
+
});
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
// 创建新的遮罩层
|
|
647
757
|
this.overlayElement = document.createElement('div');
|
|
648
758
|
this.overlayElement.className = 'customer-sdk-overlay';
|
|
649
759
|
Object.assign(this.overlayElement.style, {
|
|
@@ -659,7 +769,7 @@ class IframeManager {
|
|
|
659
769
|
justifyContent: 'center',
|
|
660
770
|
cursor: this.config.allowClose ? 'pointer' : 'default'
|
|
661
771
|
});
|
|
662
|
-
//
|
|
772
|
+
// 点击遮罩层关闭(只添加一次事件监听器)
|
|
663
773
|
if (this.config.allowClose) {
|
|
664
774
|
this.overlayElement.addEventListener('click', (e) => {
|
|
665
775
|
if (e.target === this.overlayElement) {
|
|
@@ -711,45 +821,59 @@ class IframeManager {
|
|
|
711
821
|
'allow-pointer-lock', // 允许指针锁定
|
|
712
822
|
'allow-storage-access-by-user-activation' // 允许用户激活的存储访问
|
|
713
823
|
].join(' '));
|
|
714
|
-
//
|
|
824
|
+
// 根据设备类型设置模式
|
|
715
825
|
const actualMode = this.getActualMode();
|
|
716
826
|
const isPC = actualMode === 'popup';
|
|
717
827
|
this.iframeElement.scrolling = isPC ? 'auto' : 'no'; // PC显示滚动条,移动端禁用
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
828
|
+
// PC 模式:使用配置的宽度和高度
|
|
829
|
+
// 移动端:使用全屏
|
|
830
|
+
const containerStyles = isPC ? {
|
|
831
|
+
// PC 弹窗模式
|
|
832
|
+
width: `${this.config.width || 450}px`,
|
|
833
|
+
height: `${this.config.height || 600}px`,
|
|
834
|
+
maxWidth: '90vw',
|
|
835
|
+
maxHeight: '90vh',
|
|
723
836
|
backgroundColor: '#ffffff',
|
|
724
|
-
borderRadius:
|
|
725
|
-
boxShadow:
|
|
726
|
-
? '0 20px 40px rgba(0, 0, 0, 0.15)'
|
|
727
|
-
: '0 -4px 16px rgba(0, 0, 0, 0.25)',
|
|
837
|
+
borderRadius: '12px',
|
|
838
|
+
boxShadow: '0 20px 40px rgba(0, 0, 0, 0.15)',
|
|
728
839
|
border: 'none',
|
|
729
840
|
position: 'fixed',
|
|
730
841
|
zIndex: '999999',
|
|
731
|
-
// PC
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
842
|
+
// PC模式:居中显示
|
|
843
|
+
top: '50%',
|
|
844
|
+
left: '50%',
|
|
845
|
+
transform: 'translate(-50%, -50%)',
|
|
846
|
+
overflow: 'hidden',
|
|
847
|
+
// 初始隐藏的关键样式
|
|
848
|
+
visibility: 'hidden',
|
|
849
|
+
opacity: '0',
|
|
850
|
+
display: 'none'
|
|
851
|
+
} : {
|
|
852
|
+
// 移动端全屏模式(强制 100% 宽度和高度)
|
|
853
|
+
width: '100%',
|
|
854
|
+
height: '100%',
|
|
855
|
+
maxWidth: '100%',
|
|
856
|
+
maxHeight: '100%',
|
|
857
|
+
backgroundColor: '#ffffff',
|
|
858
|
+
borderRadius: '12px 12px 0 0',
|
|
859
|
+
boxShadow: '0 -4px 16px rgba(0, 0, 0, 0.25)',
|
|
860
|
+
border: 'none',
|
|
861
|
+
position: 'fixed',
|
|
862
|
+
zIndex: '999999',
|
|
863
|
+
// 全屏模式 - 占满整个屏幕
|
|
864
|
+
top: '0',
|
|
865
|
+
left: '0',
|
|
866
|
+
bottom: '0',
|
|
867
|
+
right: '0',
|
|
868
|
+
transform: 'none',
|
|
869
|
+
overflow: 'hidden',
|
|
746
870
|
// 初始隐藏的关键样式
|
|
747
871
|
visibility: 'hidden',
|
|
748
872
|
opacity: '0',
|
|
749
873
|
display: 'none'
|
|
750
874
|
};
|
|
751
875
|
Object.assign(this.containerElement.style, containerStyles);
|
|
752
|
-
// iframe
|
|
876
|
+
// iframe填充整个容器
|
|
753
877
|
const iframeStyles = {
|
|
754
878
|
width: '100%',
|
|
755
879
|
height: '100%',
|
|
@@ -883,6 +1007,7 @@ class IframeManager {
|
|
|
883
1007
|
}
|
|
884
1008
|
/**
|
|
885
1009
|
* 获取当前显示模式
|
|
1010
|
+
* PC 模式使用弹窗,移动端使用全屏
|
|
886
1011
|
*/
|
|
887
1012
|
getActualMode() {
|
|
888
1013
|
if (this.config.mode === 'auto') {
|
|
@@ -935,9 +1060,14 @@ class IframeManager {
|
|
|
935
1060
|
break;
|
|
936
1061
|
case 'resize_iframe':
|
|
937
1062
|
case 'resize':
|
|
938
|
-
|
|
1063
|
+
// PC模式支持 resize,移动端忽略
|
|
1064
|
+
const actualMode = this.getActualMode();
|
|
1065
|
+
if (actualMode === 'popup' && data.width && data.height) {
|
|
939
1066
|
this.resizeIframe(data.width, data.height);
|
|
940
1067
|
}
|
|
1068
|
+
else if (this.debug) {
|
|
1069
|
+
console.log('Resize request ignored (fullscreen mode)');
|
|
1070
|
+
}
|
|
941
1071
|
break;
|
|
942
1072
|
case 'new-message':
|
|
943
1073
|
// 新消息通知 - 触发回调让外层处理
|
|
@@ -956,12 +1086,12 @@ class IframeManager {
|
|
|
956
1086
|
}
|
|
957
1087
|
}
|
|
958
1088
|
/**
|
|
959
|
-
* 调整iframe
|
|
1089
|
+
* 调整iframe大小(PC模式支持)
|
|
960
1090
|
*/
|
|
961
1091
|
resizeIframe(width, height) {
|
|
962
|
-
if (this.
|
|
963
|
-
this.
|
|
964
|
-
this.
|
|
1092
|
+
if (this.containerElement) {
|
|
1093
|
+
this.containerElement.style.width = `${width}px`;
|
|
1094
|
+
this.containerElement.style.height = `${height}px`;
|
|
965
1095
|
}
|
|
966
1096
|
}
|
|
967
1097
|
}
|
|
@@ -20699,9 +20829,9 @@ class CustomerServiceSDK {
|
|
|
20699
20829
|
// 创建iframe管理器(自动检测设备类型)
|
|
20700
20830
|
this.iframeManager = new IframeManager({
|
|
20701
20831
|
src: iframeUrl,
|
|
20702
|
-
mode: 'auto', //
|
|
20703
|
-
width:
|
|
20704
|
-
height: 600,
|
|
20832
|
+
mode: 'auto', // 自动根据设备类型选择模式(PC弹窗,移动端全屏)
|
|
20833
|
+
width: options?.width || 450, // PC模式宽度(像素,默认450px),移动端不使用
|
|
20834
|
+
height: options?.height || 600, // PC模式高度(像素),移动端不使用(强制全屏)
|
|
20705
20835
|
allowClose: true,
|
|
20706
20836
|
debug: this.debug, // 传递 debug 标志
|
|
20707
20837
|
onMessage: (messageType, _data) => {
|
|
@@ -20713,8 +20843,9 @@ class CustomerServiceSDK {
|
|
|
20713
20843
|
// checkScreenshot 消息由 ScreenshotManager 处理,不需要在这里处理
|
|
20714
20844
|
},
|
|
20715
20845
|
onClose: () => {
|
|
20716
|
-
// iframe
|
|
20846
|
+
// iframe关闭时,清理图标拖动事件监听器,并重新启用图标点击
|
|
20717
20847
|
this.iconManager?.forceCleanupDragEvents();
|
|
20848
|
+
this.iconManager?.enableClick();
|
|
20718
20849
|
},
|
|
20719
20850
|
...options
|
|
20720
20851
|
});
|
|
@@ -20725,6 +20856,8 @@ class CustomerServiceSDK {
|
|
|
20725
20856
|
// 打开iframe时清除红点通知
|
|
20726
20857
|
this.clearNotification();
|
|
20727
20858
|
this.iframeManager?.show();
|
|
20859
|
+
// iframe 打开后,禁用图标点击(防止重复打开)
|
|
20860
|
+
this.iconManager?.disableClick();
|
|
20728
20861
|
});
|
|
20729
20862
|
// 初始化截图管理器(如果启用了截图功能)
|
|
20730
20863
|
if (config.screenshot) {
|