sobey-monitor-sdk 1.1.3 → 1.1.5
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/index.cjs.js +134 -93
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +134 -93
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +134 -93
- package/dist/index.umd.js.map +1 -1
- package/dist/reporter/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -278,13 +278,22 @@ class Sender {
|
|
|
278
278
|
* 策略:优先使用 sendBeacon(更可靠),不支持或失败时降级为 fetch
|
|
279
279
|
*/
|
|
280
280
|
doSend(data) {
|
|
281
|
+
// 检查配置是否已初始化
|
|
282
|
+
if (!config.isInitialized()) {
|
|
283
|
+
// 配置未初始化,数据放回缓冲区等待下次发送
|
|
284
|
+
this.buffer.unshift(...data);
|
|
285
|
+
this.scheduleFlush();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
281
288
|
const cfg = config.get();
|
|
282
289
|
const dsn = cfg.dsn;
|
|
283
|
-
// dsn
|
|
290
|
+
// dsn 未配置,将数据放回缓冲区等待下次发送
|
|
284
291
|
if (!dsn) {
|
|
285
292
|
if (cfg.debug) {
|
|
286
|
-
console.warn('[Monitor] dsn not configured,
|
|
293
|
+
console.warn('[Monitor] dsn not configured, buffering data for later');
|
|
287
294
|
}
|
|
295
|
+
this.buffer.unshift(...data);
|
|
296
|
+
this.scheduleFlush();
|
|
288
297
|
return;
|
|
289
298
|
}
|
|
290
299
|
const payload = JSON.stringify(data);
|
|
@@ -405,25 +414,83 @@ class Reporter {
|
|
|
405
414
|
}
|
|
406
415
|
}
|
|
407
416
|
/**
|
|
408
|
-
*
|
|
417
|
+
* 发送早期缓存的数据(根据最新配置过滤)
|
|
409
418
|
*/
|
|
410
419
|
flushEarlyBuffer() {
|
|
420
|
+
const cfg = config.get();
|
|
421
|
+
let skippedCount = 0;
|
|
422
|
+
// 全局开关检查:如果 enabled 为 false,清空缓存不上报
|
|
423
|
+
if (cfg.enabled === false) {
|
|
424
|
+
const totalCount = this.earlyBuffer.length;
|
|
425
|
+
this.earlyBuffer = [];
|
|
426
|
+
if (cfg.debug) {
|
|
427
|
+
console.log(`[Monitor] SDK disabled, discarded ${totalCount} early buffered items`);
|
|
428
|
+
}
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
411
431
|
while (this.earlyBuffer.length > 0) {
|
|
412
432
|
const item = this.earlyBuffer.shift();
|
|
413
433
|
if (!item)
|
|
414
434
|
continue;
|
|
435
|
+
// 根据最新配置过滤数据
|
|
415
436
|
switch (item.type) {
|
|
416
437
|
case 'error':
|
|
438
|
+
// 检查错误监控是否启用
|
|
439
|
+
if (cfg.error?.enabled === false) {
|
|
440
|
+
skippedCount++;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
// 根据错误类型检查具体开关
|
|
444
|
+
const errorType = item.data?.type;
|
|
445
|
+
if (errorType === 'js_error' && cfg.error?.jsError === false) {
|
|
446
|
+
skippedCount++;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (errorType === 'promise_error' && cfg.error?.promiseError === false) {
|
|
450
|
+
skippedCount++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (errorType === 'resource_error' && cfg.error?.resourceError === false) {
|
|
454
|
+
skippedCount++;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (errorType === 'http_error' && cfg.error?.httpError === false) {
|
|
458
|
+
skippedCount++;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
417
461
|
this.reportError(item.data);
|
|
418
462
|
break;
|
|
419
463
|
case 'performance':
|
|
464
|
+
// 检查性能监控是否启用
|
|
465
|
+
if (cfg.performance?.enabled === false) {
|
|
466
|
+
skippedCount++;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
420
469
|
this.reportPerformance(item.data);
|
|
421
470
|
break;
|
|
422
471
|
case 'behavior':
|
|
472
|
+
// 检查行为监控是否启用
|
|
473
|
+
if (cfg.behavior?.enabled === false) {
|
|
474
|
+
skippedCount++;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
// 根据行为类型检查具体开关
|
|
478
|
+
const action = item.data?.action;
|
|
479
|
+
if (action === 'pv' && cfg.behavior?.pv === false) {
|
|
480
|
+
skippedCount++;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (action === 'route' && cfg.behavior?.route === false) {
|
|
484
|
+
skippedCount++;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
423
487
|
this.reportBehavior(item.data);
|
|
424
488
|
break;
|
|
425
489
|
}
|
|
426
490
|
}
|
|
491
|
+
if (skippedCount > 0 && cfg.debug) {
|
|
492
|
+
console.log(`[Monitor] Filtered out ${skippedCount} early buffered items based on config`);
|
|
493
|
+
}
|
|
427
494
|
}
|
|
428
495
|
/**
|
|
429
496
|
* 缓存早期数据
|
|
@@ -551,15 +618,16 @@ const reporter = new Reporter();
|
|
|
551
618
|
* 安装 JS 错误监听
|
|
552
619
|
*/
|
|
553
620
|
function installJsErrorHandler() {
|
|
554
|
-
const cfg = config.get();
|
|
555
|
-
if (!cfg.error?.enabled || !cfg.error?.jsError) {
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
621
|
window.addEventListener('error', (event) => {
|
|
559
622
|
// 过滤资源加载错误(由 resourceError 处理)
|
|
560
623
|
if (event.target !== window) {
|
|
561
624
|
return;
|
|
562
625
|
}
|
|
626
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
627
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
628
|
+
if (cfg?.error?.enabled === false || cfg?.error?.jsError === false) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
563
631
|
const errorData = {
|
|
564
632
|
type: 'js_error',
|
|
565
633
|
message: event.message || 'Unknown error',
|
|
@@ -580,9 +648,7 @@ function installJsErrorHandler() {
|
|
|
580
648
|
});
|
|
581
649
|
reporter.reportError(errorData);
|
|
582
650
|
}, true);
|
|
583
|
-
|
|
584
|
-
console.log('[Monitor] JS error handler installed');
|
|
585
|
-
}
|
|
651
|
+
console.log('[Monitor] JS error handler installed');
|
|
586
652
|
}
|
|
587
653
|
|
|
588
654
|
/**
|
|
@@ -592,11 +658,12 @@ function installJsErrorHandler() {
|
|
|
592
658
|
* 安装 Promise 错误监听
|
|
593
659
|
*/
|
|
594
660
|
function installPromiseErrorHandler() {
|
|
595
|
-
const cfg = config.get();
|
|
596
|
-
if (!cfg.error?.enabled || !cfg.error?.promiseError) {
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
661
|
window.addEventListener('unhandledrejection', (event) => {
|
|
662
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
663
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
664
|
+
if (cfg?.error?.enabled === false || cfg?.error?.promiseError === false) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
600
667
|
let message = 'Unhandled Promise rejection';
|
|
601
668
|
let stack;
|
|
602
669
|
const reason = event.reason;
|
|
@@ -625,9 +692,7 @@ function installPromiseErrorHandler() {
|
|
|
625
692
|
});
|
|
626
693
|
reporter.reportError(errorData);
|
|
627
694
|
});
|
|
628
|
-
|
|
629
|
-
console.log('[Monitor] Promise error handler installed');
|
|
630
|
-
}
|
|
695
|
+
console.log('[Monitor] Promise error handler installed');
|
|
631
696
|
}
|
|
632
697
|
|
|
633
698
|
/**
|
|
@@ -637,16 +702,17 @@ function installPromiseErrorHandler() {
|
|
|
637
702
|
* 安装资源错误监听
|
|
638
703
|
*/
|
|
639
704
|
function installResourceErrorHandler() {
|
|
640
|
-
const cfg = config.get();
|
|
641
|
-
if (!cfg.error?.enabled || !cfg.error?.resourceError) {
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
705
|
window.addEventListener('error', (event) => {
|
|
645
706
|
const target = event.target;
|
|
646
707
|
// 只处理资源加载错误(target 不是 window)
|
|
647
708
|
if (!target || target === window || !(target instanceof HTMLElement)) {
|
|
648
709
|
return;
|
|
649
710
|
}
|
|
711
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
712
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
713
|
+
if (cfg?.error?.enabled === false || cfg?.error?.resourceError === false) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
650
716
|
const tagName = target.tagName.toLowerCase();
|
|
651
717
|
// 只监控特定标签的资源
|
|
652
718
|
if (!['img', 'script', 'link', 'video', 'audio', 'source'].includes(tagName)) {
|
|
@@ -675,9 +741,7 @@ function installResourceErrorHandler() {
|
|
|
675
741
|
});
|
|
676
742
|
reporter.reportError(errorData);
|
|
677
743
|
}, true); // 使用捕获阶段
|
|
678
|
-
|
|
679
|
-
console.log('[Monitor] Resource error handler installed');
|
|
680
|
-
}
|
|
744
|
+
console.log('[Monitor] Resource error handler installed');
|
|
681
745
|
}
|
|
682
746
|
|
|
683
747
|
/**
|
|
@@ -692,23 +756,16 @@ const originalFetch = window.fetch;
|
|
|
692
756
|
* 安装 HTTP 错误拦截
|
|
693
757
|
*/
|
|
694
758
|
function installHttpErrorHandler() {
|
|
695
|
-
const cfg = config.get();
|
|
696
|
-
if (!cfg.error?.enabled || !cfg.error?.httpError) {
|
|
697
|
-
return;
|
|
698
|
-
}
|
|
699
759
|
interceptXHR();
|
|
700
760
|
interceptFetch();
|
|
701
|
-
|
|
702
|
-
console.log('[Monitor] HTTP error handler installed');
|
|
703
|
-
}
|
|
761
|
+
console.log('[Monitor] HTTP error handler installed');
|
|
704
762
|
}
|
|
705
|
-
/**
|
|
706
|
-
* 拦截 XMLHttpRequest
|
|
707
|
-
*/
|
|
708
763
|
/**
|
|
709
764
|
* 检查是否是 SDK 自身的请求
|
|
710
765
|
*/
|
|
711
766
|
function isSdkRequest(url) {
|
|
767
|
+
if (!config.isInitialized())
|
|
768
|
+
return false;
|
|
712
769
|
const cfg = config.get();
|
|
713
770
|
if (!cfg.dsn)
|
|
714
771
|
return false;
|
|
@@ -878,10 +935,6 @@ function reportHttpError(httpInfo) {
|
|
|
878
935
|
reporter.reportError(errorData);
|
|
879
936
|
}
|
|
880
937
|
|
|
881
|
-
/**
|
|
882
|
-
* 白屏检测插件
|
|
883
|
-
* 使用 DOM 采样检测页面是否白屏
|
|
884
|
-
*/
|
|
885
938
|
// 采样点 - 页面关键区域
|
|
886
939
|
const SAMPLE_POINTS = [
|
|
887
940
|
{ x: 0.5, y: 0.1 }, // 顶部中间
|
|
@@ -896,10 +949,6 @@ const INVALID_ELEMENTS = ['html', 'body', 'head', 'meta', 'link', 'style', 'scri
|
|
|
896
949
|
* 安装白屏检测
|
|
897
950
|
*/
|
|
898
951
|
function installWhiteScreenDetector() {
|
|
899
|
-
const cfg = config.get();
|
|
900
|
-
if (!cfg.error?.enabled) {
|
|
901
|
-
return;
|
|
902
|
-
}
|
|
903
952
|
// 在页面加载完成后检测
|
|
904
953
|
if (document.readyState === 'complete') {
|
|
905
954
|
scheduleDetection();
|
|
@@ -909,9 +958,7 @@ function installWhiteScreenDetector() {
|
|
|
909
958
|
scheduleDetection();
|
|
910
959
|
});
|
|
911
960
|
}
|
|
912
|
-
|
|
913
|
-
console.log('[Monitor] White screen detector installed');
|
|
914
|
-
}
|
|
961
|
+
console.log('[Monitor] White screen detector installed');
|
|
915
962
|
}
|
|
916
963
|
/**
|
|
917
964
|
* 调度检测(延迟执行,给页面渲染时间)
|
|
@@ -983,10 +1030,6 @@ function installErrorHandlers() {
|
|
|
983
1030
|
* 安装 Web Vitals 采集
|
|
984
1031
|
*/
|
|
985
1032
|
function installWebVitals() {
|
|
986
|
-
const cfg = config.get();
|
|
987
|
-
if (!cfg.performance?.enabled || !cfg.performance?.webVitals) {
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
1033
|
// 页面加载完成后采集
|
|
991
1034
|
if (document.readyState === 'complete') {
|
|
992
1035
|
collectMetrics();
|
|
@@ -997,14 +1040,17 @@ function installWebVitals() {
|
|
|
997
1040
|
setTimeout(collectMetrics, 3000);
|
|
998
1041
|
});
|
|
999
1042
|
}
|
|
1000
|
-
|
|
1001
|
-
console.log('[Monitor] Web Vitals collector installed');
|
|
1002
|
-
}
|
|
1043
|
+
console.log('[Monitor] Web Vitals collector installed');
|
|
1003
1044
|
}
|
|
1004
1045
|
/**
|
|
1005
1046
|
* 采集性能指标
|
|
1006
1047
|
*/
|
|
1007
1048
|
function collectMetrics() {
|
|
1049
|
+
// 检查配置(在采集时检查,而不是安装时)
|
|
1050
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1051
|
+
if (cfg?.performance?.enabled === false || cfg?.performance?.webVitals === false) {
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1008
1054
|
const metrics = {};
|
|
1009
1055
|
// 使用 Performance API
|
|
1010
1056
|
if (!window.performance) {
|
|
@@ -1113,22 +1159,13 @@ function installPerformanceMonitor() {
|
|
|
1113
1159
|
installWebVitals();
|
|
1114
1160
|
}
|
|
1115
1161
|
|
|
1116
|
-
/**
|
|
1117
|
-
* PV (Page View) 统计插件
|
|
1118
|
-
*/
|
|
1119
1162
|
/**
|
|
1120
1163
|
* 安装 PV 统计
|
|
1121
1164
|
*/
|
|
1122
1165
|
function installPVTracker() {
|
|
1123
|
-
|
|
1124
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.pv) {
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1127
|
-
// 页面加载时上报
|
|
1166
|
+
// 页面加载时上报(reporter 会缓存直到 SDK 就绪)
|
|
1128
1167
|
reportPV();
|
|
1129
|
-
|
|
1130
|
-
console.log('[Monitor] PV tracker installed');
|
|
1131
|
-
}
|
|
1168
|
+
console.log('[Monitor] PV tracker installed');
|
|
1132
1169
|
}
|
|
1133
1170
|
/**
|
|
1134
1171
|
* 上报 PV
|
|
@@ -1151,11 +1188,12 @@ function reportPV() {
|
|
|
1151
1188
|
* 安装点击追踪
|
|
1152
1189
|
*/
|
|
1153
1190
|
function installClickTracker() {
|
|
1154
|
-
const cfg = config.get();
|
|
1155
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.click) {
|
|
1156
|
-
return;
|
|
1157
|
-
}
|
|
1158
1191
|
document.addEventListener('click', (event) => {
|
|
1192
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1193
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1194
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.click === false) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1159
1197
|
const target = event.target;
|
|
1160
1198
|
if (!target)
|
|
1161
1199
|
return;
|
|
@@ -1173,9 +1211,7 @@ function installClickTracker() {
|
|
|
1173
1211
|
// data: clickData,
|
|
1174
1212
|
// });
|
|
1175
1213
|
}, true);
|
|
1176
|
-
|
|
1177
|
-
console.log('[Monitor] Click tracker installed');
|
|
1178
|
-
}
|
|
1214
|
+
console.log('[Monitor] Click tracker installed');
|
|
1179
1215
|
}
|
|
1180
1216
|
/**
|
|
1181
1217
|
* 提取点击数据
|
|
@@ -1254,10 +1290,6 @@ const originalReplaceState = history.replaceState;
|
|
|
1254
1290
|
* 安装路由监控
|
|
1255
1291
|
*/
|
|
1256
1292
|
function installRouteTracker() {
|
|
1257
|
-
const cfg = config.get();
|
|
1258
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.route) {
|
|
1259
|
-
return;
|
|
1260
|
-
}
|
|
1261
1293
|
// 拦截 pushState
|
|
1262
1294
|
history.pushState = function (...args) {
|
|
1263
1295
|
const result = originalPushState.apply(this, args);
|
|
@@ -1278,14 +1310,17 @@ function installRouteTracker() {
|
|
|
1278
1310
|
window.addEventListener('hashchange', () => {
|
|
1279
1311
|
handleRouteChange('hashchange');
|
|
1280
1312
|
});
|
|
1281
|
-
|
|
1282
|
-
console.log('[Monitor] Route tracker installed');
|
|
1283
|
-
}
|
|
1313
|
+
console.log('[Monitor] Route tracker installed');
|
|
1284
1314
|
}
|
|
1285
1315
|
/**
|
|
1286
1316
|
* 处理路由变化
|
|
1287
1317
|
*/
|
|
1288
1318
|
function handleRouteChange(trigger) {
|
|
1319
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1320
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1321
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.route === false) {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1289
1324
|
const routeData = {
|
|
1290
1325
|
url: getPageUrl(),
|
|
1291
1326
|
title: getPageTitle(),
|
|
@@ -1320,16 +1355,16 @@ const originalConsole = {
|
|
|
1320
1355
|
* 安装控制台追踪
|
|
1321
1356
|
*/
|
|
1322
1357
|
function installConsoleTracker() {
|
|
1323
|
-
const cfg = config.get();
|
|
1324
|
-
// 默认启用控制台追踪(跟随 behavior.enabled)
|
|
1325
|
-
if (!cfg.behavior?.enabled) {
|
|
1326
|
-
return;
|
|
1327
|
-
}
|
|
1328
1358
|
const levels = ['log', 'info', 'warn', 'error'];
|
|
1329
1359
|
levels.forEach((level) => {
|
|
1330
1360
|
console[level] = function (...args) {
|
|
1331
1361
|
// 调用原始方法
|
|
1332
1362
|
originalConsole[level].apply(console, args);
|
|
1363
|
+
// 检查配置(在调用时检查,而不是安装时)
|
|
1364
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1365
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1333
1368
|
// 添加到面包屑(只记录 warn 和 error)
|
|
1334
1369
|
if (level === 'warn' || level === 'error') {
|
|
1335
1370
|
const message = formatConsoleArgs(args);
|
|
@@ -1344,9 +1379,7 @@ function installConsoleTracker() {
|
|
|
1344
1379
|
}
|
|
1345
1380
|
};
|
|
1346
1381
|
});
|
|
1347
|
-
|
|
1348
|
-
originalConsole.log('[Monitor] Console tracker installed');
|
|
1349
|
-
}
|
|
1382
|
+
originalConsole.log('[Monitor] Console tracker installed');
|
|
1350
1383
|
}
|
|
1351
1384
|
/**
|
|
1352
1385
|
* 格式化控制台参数
|
|
@@ -1378,24 +1411,22 @@ function formatConsoleArgs(args) {
|
|
|
1378
1411
|
* 安装输入追踪
|
|
1379
1412
|
*/
|
|
1380
1413
|
function installInputTracker() {
|
|
1381
|
-
const cfg = config.get();
|
|
1382
|
-
// 默认启用输入追踪(跟随 behavior.enabled)
|
|
1383
|
-
if (!cfg.behavior?.enabled) {
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1386
1414
|
// 监听 input 事件(使用 change 事件减少数据量)
|
|
1387
1415
|
document.addEventListener('change', handleInputChange, true);
|
|
1388
1416
|
// 监听焦点事件
|
|
1389
1417
|
document.addEventListener('focus', handleFocus, true);
|
|
1390
1418
|
document.addEventListener('blur', handleBlur, true);
|
|
1391
|
-
|
|
1392
|
-
console.log('[Monitor] Input tracker installed');
|
|
1393
|
-
}
|
|
1419
|
+
console.log('[Monitor] Input tracker installed');
|
|
1394
1420
|
}
|
|
1395
1421
|
/**
|
|
1396
1422
|
* 处理输入变化
|
|
1397
1423
|
*/
|
|
1398
1424
|
function handleInputChange(event) {
|
|
1425
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1426
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1427
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1399
1430
|
const target = event.target;
|
|
1400
1431
|
if (!target || !isFormElement(target))
|
|
1401
1432
|
return;
|
|
@@ -1410,6 +1441,11 @@ function handleInputChange(event) {
|
|
|
1410
1441
|
* 处理焦点获取
|
|
1411
1442
|
*/
|
|
1412
1443
|
function handleFocus(event) {
|
|
1444
|
+
// 检查配置
|
|
1445
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1446
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1413
1449
|
const target = event.target;
|
|
1414
1450
|
if (!target || !isFormElement(target))
|
|
1415
1451
|
return;
|
|
@@ -1423,6 +1459,11 @@ function handleFocus(event) {
|
|
|
1423
1459
|
* 处理焦点失去
|
|
1424
1460
|
*/
|
|
1425
1461
|
function handleBlur(event) {
|
|
1462
|
+
// 检查配置
|
|
1463
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1464
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1426
1467
|
const target = event.target;
|
|
1427
1468
|
if (!target || !isFormElement(target))
|
|
1428
1469
|
return;
|