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.esm.js
CHANGED
|
@@ -274,13 +274,22 @@ class Sender {
|
|
|
274
274
|
* 策略:优先使用 sendBeacon(更可靠),不支持或失败时降级为 fetch
|
|
275
275
|
*/
|
|
276
276
|
doSend(data) {
|
|
277
|
+
// 检查配置是否已初始化
|
|
278
|
+
if (!config.isInitialized()) {
|
|
279
|
+
// 配置未初始化,数据放回缓冲区等待下次发送
|
|
280
|
+
this.buffer.unshift(...data);
|
|
281
|
+
this.scheduleFlush();
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
277
284
|
const cfg = config.get();
|
|
278
285
|
const dsn = cfg.dsn;
|
|
279
|
-
// dsn
|
|
286
|
+
// dsn 未配置,将数据放回缓冲区等待下次发送
|
|
280
287
|
if (!dsn) {
|
|
281
288
|
if (cfg.debug) {
|
|
282
|
-
console.warn('[Monitor] dsn not configured,
|
|
289
|
+
console.warn('[Monitor] dsn not configured, buffering data for later');
|
|
283
290
|
}
|
|
291
|
+
this.buffer.unshift(...data);
|
|
292
|
+
this.scheduleFlush();
|
|
284
293
|
return;
|
|
285
294
|
}
|
|
286
295
|
const payload = JSON.stringify(data);
|
|
@@ -401,25 +410,83 @@ class Reporter {
|
|
|
401
410
|
}
|
|
402
411
|
}
|
|
403
412
|
/**
|
|
404
|
-
*
|
|
413
|
+
* 发送早期缓存的数据(根据最新配置过滤)
|
|
405
414
|
*/
|
|
406
415
|
flushEarlyBuffer() {
|
|
416
|
+
const cfg = config.get();
|
|
417
|
+
let skippedCount = 0;
|
|
418
|
+
// 全局开关检查:如果 enabled 为 false,清空缓存不上报
|
|
419
|
+
if (cfg.enabled === false) {
|
|
420
|
+
const totalCount = this.earlyBuffer.length;
|
|
421
|
+
this.earlyBuffer = [];
|
|
422
|
+
if (cfg.debug) {
|
|
423
|
+
console.log(`[Monitor] SDK disabled, discarded ${totalCount} early buffered items`);
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
407
427
|
while (this.earlyBuffer.length > 0) {
|
|
408
428
|
const item = this.earlyBuffer.shift();
|
|
409
429
|
if (!item)
|
|
410
430
|
continue;
|
|
431
|
+
// 根据最新配置过滤数据
|
|
411
432
|
switch (item.type) {
|
|
412
433
|
case 'error':
|
|
434
|
+
// 检查错误监控是否启用
|
|
435
|
+
if (cfg.error?.enabled === false) {
|
|
436
|
+
skippedCount++;
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
// 根据错误类型检查具体开关
|
|
440
|
+
const errorType = item.data?.type;
|
|
441
|
+
if (errorType === 'js_error' && cfg.error?.jsError === false) {
|
|
442
|
+
skippedCount++;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (errorType === 'promise_error' && cfg.error?.promiseError === false) {
|
|
446
|
+
skippedCount++;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (errorType === 'resource_error' && cfg.error?.resourceError === false) {
|
|
450
|
+
skippedCount++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (errorType === 'http_error' && cfg.error?.httpError === false) {
|
|
454
|
+
skippedCount++;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
413
457
|
this.reportError(item.data);
|
|
414
458
|
break;
|
|
415
459
|
case 'performance':
|
|
460
|
+
// 检查性能监控是否启用
|
|
461
|
+
if (cfg.performance?.enabled === false) {
|
|
462
|
+
skippedCount++;
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
416
465
|
this.reportPerformance(item.data);
|
|
417
466
|
break;
|
|
418
467
|
case 'behavior':
|
|
468
|
+
// 检查行为监控是否启用
|
|
469
|
+
if (cfg.behavior?.enabled === false) {
|
|
470
|
+
skippedCount++;
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
// 根据行为类型检查具体开关
|
|
474
|
+
const action = item.data?.action;
|
|
475
|
+
if (action === 'pv' && cfg.behavior?.pv === false) {
|
|
476
|
+
skippedCount++;
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (action === 'route' && cfg.behavior?.route === false) {
|
|
480
|
+
skippedCount++;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
419
483
|
this.reportBehavior(item.data);
|
|
420
484
|
break;
|
|
421
485
|
}
|
|
422
486
|
}
|
|
487
|
+
if (skippedCount > 0 && cfg.debug) {
|
|
488
|
+
console.log(`[Monitor] Filtered out ${skippedCount} early buffered items based on config`);
|
|
489
|
+
}
|
|
423
490
|
}
|
|
424
491
|
/**
|
|
425
492
|
* 缓存早期数据
|
|
@@ -547,15 +614,16 @@ const reporter = new Reporter();
|
|
|
547
614
|
* 安装 JS 错误监听
|
|
548
615
|
*/
|
|
549
616
|
function installJsErrorHandler() {
|
|
550
|
-
const cfg = config.get();
|
|
551
|
-
if (!cfg.error?.enabled || !cfg.error?.jsError) {
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
617
|
window.addEventListener('error', (event) => {
|
|
555
618
|
// 过滤资源加载错误(由 resourceError 处理)
|
|
556
619
|
if (event.target !== window) {
|
|
557
620
|
return;
|
|
558
621
|
}
|
|
622
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
623
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
624
|
+
if (cfg?.error?.enabled === false || cfg?.error?.jsError === false) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
559
627
|
const errorData = {
|
|
560
628
|
type: 'js_error',
|
|
561
629
|
message: event.message || 'Unknown error',
|
|
@@ -576,9 +644,7 @@ function installJsErrorHandler() {
|
|
|
576
644
|
});
|
|
577
645
|
reporter.reportError(errorData);
|
|
578
646
|
}, true);
|
|
579
|
-
|
|
580
|
-
console.log('[Monitor] JS error handler installed');
|
|
581
|
-
}
|
|
647
|
+
console.log('[Monitor] JS error handler installed');
|
|
582
648
|
}
|
|
583
649
|
|
|
584
650
|
/**
|
|
@@ -588,11 +654,12 @@ function installJsErrorHandler() {
|
|
|
588
654
|
* 安装 Promise 错误监听
|
|
589
655
|
*/
|
|
590
656
|
function installPromiseErrorHandler() {
|
|
591
|
-
const cfg = config.get();
|
|
592
|
-
if (!cfg.error?.enabled || !cfg.error?.promiseError) {
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
657
|
window.addEventListener('unhandledrejection', (event) => {
|
|
658
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
659
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
660
|
+
if (cfg?.error?.enabled === false || cfg?.error?.promiseError === false) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
596
663
|
let message = 'Unhandled Promise rejection';
|
|
597
664
|
let stack;
|
|
598
665
|
const reason = event.reason;
|
|
@@ -621,9 +688,7 @@ function installPromiseErrorHandler() {
|
|
|
621
688
|
});
|
|
622
689
|
reporter.reportError(errorData);
|
|
623
690
|
});
|
|
624
|
-
|
|
625
|
-
console.log('[Monitor] Promise error handler installed');
|
|
626
|
-
}
|
|
691
|
+
console.log('[Monitor] Promise error handler installed');
|
|
627
692
|
}
|
|
628
693
|
|
|
629
694
|
/**
|
|
@@ -633,16 +698,17 @@ function installPromiseErrorHandler() {
|
|
|
633
698
|
* 安装资源错误监听
|
|
634
699
|
*/
|
|
635
700
|
function installResourceErrorHandler() {
|
|
636
|
-
const cfg = config.get();
|
|
637
|
-
if (!cfg.error?.enabled || !cfg.error?.resourceError) {
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
701
|
window.addEventListener('error', (event) => {
|
|
641
702
|
const target = event.target;
|
|
642
703
|
// 只处理资源加载错误(target 不是 window)
|
|
643
704
|
if (!target || target === window || !(target instanceof HTMLElement)) {
|
|
644
705
|
return;
|
|
645
706
|
}
|
|
707
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
708
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
709
|
+
if (cfg?.error?.enabled === false || cfg?.error?.resourceError === false) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
646
712
|
const tagName = target.tagName.toLowerCase();
|
|
647
713
|
// 只监控特定标签的资源
|
|
648
714
|
if (!['img', 'script', 'link', 'video', 'audio', 'source'].includes(tagName)) {
|
|
@@ -671,9 +737,7 @@ function installResourceErrorHandler() {
|
|
|
671
737
|
});
|
|
672
738
|
reporter.reportError(errorData);
|
|
673
739
|
}, true); // 使用捕获阶段
|
|
674
|
-
|
|
675
|
-
console.log('[Monitor] Resource error handler installed');
|
|
676
|
-
}
|
|
740
|
+
console.log('[Monitor] Resource error handler installed');
|
|
677
741
|
}
|
|
678
742
|
|
|
679
743
|
/**
|
|
@@ -688,23 +752,16 @@ const originalFetch = window.fetch;
|
|
|
688
752
|
* 安装 HTTP 错误拦截
|
|
689
753
|
*/
|
|
690
754
|
function installHttpErrorHandler() {
|
|
691
|
-
const cfg = config.get();
|
|
692
|
-
if (!cfg.error?.enabled || !cfg.error?.httpError) {
|
|
693
|
-
return;
|
|
694
|
-
}
|
|
695
755
|
interceptXHR();
|
|
696
756
|
interceptFetch();
|
|
697
|
-
|
|
698
|
-
console.log('[Monitor] HTTP error handler installed');
|
|
699
|
-
}
|
|
757
|
+
console.log('[Monitor] HTTP error handler installed');
|
|
700
758
|
}
|
|
701
|
-
/**
|
|
702
|
-
* 拦截 XMLHttpRequest
|
|
703
|
-
*/
|
|
704
759
|
/**
|
|
705
760
|
* 检查是否是 SDK 自身的请求
|
|
706
761
|
*/
|
|
707
762
|
function isSdkRequest(url) {
|
|
763
|
+
if (!config.isInitialized())
|
|
764
|
+
return false;
|
|
708
765
|
const cfg = config.get();
|
|
709
766
|
if (!cfg.dsn)
|
|
710
767
|
return false;
|
|
@@ -874,10 +931,6 @@ function reportHttpError(httpInfo) {
|
|
|
874
931
|
reporter.reportError(errorData);
|
|
875
932
|
}
|
|
876
933
|
|
|
877
|
-
/**
|
|
878
|
-
* 白屏检测插件
|
|
879
|
-
* 使用 DOM 采样检测页面是否白屏
|
|
880
|
-
*/
|
|
881
934
|
// 采样点 - 页面关键区域
|
|
882
935
|
const SAMPLE_POINTS = [
|
|
883
936
|
{ x: 0.5, y: 0.1 }, // 顶部中间
|
|
@@ -892,10 +945,6 @@ const INVALID_ELEMENTS = ['html', 'body', 'head', 'meta', 'link', 'style', 'scri
|
|
|
892
945
|
* 安装白屏检测
|
|
893
946
|
*/
|
|
894
947
|
function installWhiteScreenDetector() {
|
|
895
|
-
const cfg = config.get();
|
|
896
|
-
if (!cfg.error?.enabled) {
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
948
|
// 在页面加载完成后检测
|
|
900
949
|
if (document.readyState === 'complete') {
|
|
901
950
|
scheduleDetection();
|
|
@@ -905,9 +954,7 @@ function installWhiteScreenDetector() {
|
|
|
905
954
|
scheduleDetection();
|
|
906
955
|
});
|
|
907
956
|
}
|
|
908
|
-
|
|
909
|
-
console.log('[Monitor] White screen detector installed');
|
|
910
|
-
}
|
|
957
|
+
console.log('[Monitor] White screen detector installed');
|
|
911
958
|
}
|
|
912
959
|
/**
|
|
913
960
|
* 调度检测(延迟执行,给页面渲染时间)
|
|
@@ -979,10 +1026,6 @@ function installErrorHandlers() {
|
|
|
979
1026
|
* 安装 Web Vitals 采集
|
|
980
1027
|
*/
|
|
981
1028
|
function installWebVitals() {
|
|
982
|
-
const cfg = config.get();
|
|
983
|
-
if (!cfg.performance?.enabled || !cfg.performance?.webVitals) {
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
986
1029
|
// 页面加载完成后采集
|
|
987
1030
|
if (document.readyState === 'complete') {
|
|
988
1031
|
collectMetrics();
|
|
@@ -993,14 +1036,17 @@ function installWebVitals() {
|
|
|
993
1036
|
setTimeout(collectMetrics, 3000);
|
|
994
1037
|
});
|
|
995
1038
|
}
|
|
996
|
-
|
|
997
|
-
console.log('[Monitor] Web Vitals collector installed');
|
|
998
|
-
}
|
|
1039
|
+
console.log('[Monitor] Web Vitals collector installed');
|
|
999
1040
|
}
|
|
1000
1041
|
/**
|
|
1001
1042
|
* 采集性能指标
|
|
1002
1043
|
*/
|
|
1003
1044
|
function collectMetrics() {
|
|
1045
|
+
// 检查配置(在采集时检查,而不是安装时)
|
|
1046
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1047
|
+
if (cfg?.performance?.enabled === false || cfg?.performance?.webVitals === false) {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1004
1050
|
const metrics = {};
|
|
1005
1051
|
// 使用 Performance API
|
|
1006
1052
|
if (!window.performance) {
|
|
@@ -1109,22 +1155,13 @@ function installPerformanceMonitor() {
|
|
|
1109
1155
|
installWebVitals();
|
|
1110
1156
|
}
|
|
1111
1157
|
|
|
1112
|
-
/**
|
|
1113
|
-
* PV (Page View) 统计插件
|
|
1114
|
-
*/
|
|
1115
1158
|
/**
|
|
1116
1159
|
* 安装 PV 统计
|
|
1117
1160
|
*/
|
|
1118
1161
|
function installPVTracker() {
|
|
1119
|
-
|
|
1120
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.pv) {
|
|
1121
|
-
return;
|
|
1122
|
-
}
|
|
1123
|
-
// 页面加载时上报
|
|
1162
|
+
// 页面加载时上报(reporter 会缓存直到 SDK 就绪)
|
|
1124
1163
|
reportPV();
|
|
1125
|
-
|
|
1126
|
-
console.log('[Monitor] PV tracker installed');
|
|
1127
|
-
}
|
|
1164
|
+
console.log('[Monitor] PV tracker installed');
|
|
1128
1165
|
}
|
|
1129
1166
|
/**
|
|
1130
1167
|
* 上报 PV
|
|
@@ -1147,11 +1184,12 @@ function reportPV() {
|
|
|
1147
1184
|
* 安装点击追踪
|
|
1148
1185
|
*/
|
|
1149
1186
|
function installClickTracker() {
|
|
1150
|
-
const cfg = config.get();
|
|
1151
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.click) {
|
|
1152
|
-
return;
|
|
1153
|
-
}
|
|
1154
1187
|
document.addEventListener('click', (event) => {
|
|
1188
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1189
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1190
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.click === false) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1155
1193
|
const target = event.target;
|
|
1156
1194
|
if (!target)
|
|
1157
1195
|
return;
|
|
@@ -1169,9 +1207,7 @@ function installClickTracker() {
|
|
|
1169
1207
|
// data: clickData,
|
|
1170
1208
|
// });
|
|
1171
1209
|
}, true);
|
|
1172
|
-
|
|
1173
|
-
console.log('[Monitor] Click tracker installed');
|
|
1174
|
-
}
|
|
1210
|
+
console.log('[Monitor] Click tracker installed');
|
|
1175
1211
|
}
|
|
1176
1212
|
/**
|
|
1177
1213
|
* 提取点击数据
|
|
@@ -1250,10 +1286,6 @@ const originalReplaceState = history.replaceState;
|
|
|
1250
1286
|
* 安装路由监控
|
|
1251
1287
|
*/
|
|
1252
1288
|
function installRouteTracker() {
|
|
1253
|
-
const cfg = config.get();
|
|
1254
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.route) {
|
|
1255
|
-
return;
|
|
1256
|
-
}
|
|
1257
1289
|
// 拦截 pushState
|
|
1258
1290
|
history.pushState = function (...args) {
|
|
1259
1291
|
const result = originalPushState.apply(this, args);
|
|
@@ -1274,14 +1306,17 @@ function installRouteTracker() {
|
|
|
1274
1306
|
window.addEventListener('hashchange', () => {
|
|
1275
1307
|
handleRouteChange('hashchange');
|
|
1276
1308
|
});
|
|
1277
|
-
|
|
1278
|
-
console.log('[Monitor] Route tracker installed');
|
|
1279
|
-
}
|
|
1309
|
+
console.log('[Monitor] Route tracker installed');
|
|
1280
1310
|
}
|
|
1281
1311
|
/**
|
|
1282
1312
|
* 处理路由变化
|
|
1283
1313
|
*/
|
|
1284
1314
|
function handleRouteChange(trigger) {
|
|
1315
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1316
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1317
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.route === false) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1285
1320
|
const routeData = {
|
|
1286
1321
|
url: getPageUrl(),
|
|
1287
1322
|
title: getPageTitle(),
|
|
@@ -1316,16 +1351,16 @@ const originalConsole = {
|
|
|
1316
1351
|
* 安装控制台追踪
|
|
1317
1352
|
*/
|
|
1318
1353
|
function installConsoleTracker() {
|
|
1319
|
-
const cfg = config.get();
|
|
1320
|
-
// 默认启用控制台追踪(跟随 behavior.enabled)
|
|
1321
|
-
if (!cfg.behavior?.enabled) {
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
1354
|
const levels = ['log', 'info', 'warn', 'error'];
|
|
1325
1355
|
levels.forEach((level) => {
|
|
1326
1356
|
console[level] = function (...args) {
|
|
1327
1357
|
// 调用原始方法
|
|
1328
1358
|
originalConsole[level].apply(console, args);
|
|
1359
|
+
// 检查配置(在调用时检查,而不是安装时)
|
|
1360
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1361
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1329
1364
|
// 添加到面包屑(只记录 warn 和 error)
|
|
1330
1365
|
if (level === 'warn' || level === 'error') {
|
|
1331
1366
|
const message = formatConsoleArgs(args);
|
|
@@ -1340,9 +1375,7 @@ function installConsoleTracker() {
|
|
|
1340
1375
|
}
|
|
1341
1376
|
};
|
|
1342
1377
|
});
|
|
1343
|
-
|
|
1344
|
-
originalConsole.log('[Monitor] Console tracker installed');
|
|
1345
|
-
}
|
|
1378
|
+
originalConsole.log('[Monitor] Console tracker installed');
|
|
1346
1379
|
}
|
|
1347
1380
|
/**
|
|
1348
1381
|
* 格式化控制台参数
|
|
@@ -1374,24 +1407,22 @@ function formatConsoleArgs(args) {
|
|
|
1374
1407
|
* 安装输入追踪
|
|
1375
1408
|
*/
|
|
1376
1409
|
function installInputTracker() {
|
|
1377
|
-
const cfg = config.get();
|
|
1378
|
-
// 默认启用输入追踪(跟随 behavior.enabled)
|
|
1379
|
-
if (!cfg.behavior?.enabled) {
|
|
1380
|
-
return;
|
|
1381
|
-
}
|
|
1382
1410
|
// 监听 input 事件(使用 change 事件减少数据量)
|
|
1383
1411
|
document.addEventListener('change', handleInputChange, true);
|
|
1384
1412
|
// 监听焦点事件
|
|
1385
1413
|
document.addEventListener('focus', handleFocus, true);
|
|
1386
1414
|
document.addEventListener('blur', handleBlur, true);
|
|
1387
|
-
|
|
1388
|
-
console.log('[Monitor] Input tracker installed');
|
|
1389
|
-
}
|
|
1415
|
+
console.log('[Monitor] Input tracker installed');
|
|
1390
1416
|
}
|
|
1391
1417
|
/**
|
|
1392
1418
|
* 处理输入变化
|
|
1393
1419
|
*/
|
|
1394
1420
|
function handleInputChange(event) {
|
|
1421
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1422
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1423
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1395
1426
|
const target = event.target;
|
|
1396
1427
|
if (!target || !isFormElement(target))
|
|
1397
1428
|
return;
|
|
@@ -1406,6 +1437,11 @@ function handleInputChange(event) {
|
|
|
1406
1437
|
* 处理焦点获取
|
|
1407
1438
|
*/
|
|
1408
1439
|
function handleFocus(event) {
|
|
1440
|
+
// 检查配置
|
|
1441
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1442
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1409
1445
|
const target = event.target;
|
|
1410
1446
|
if (!target || !isFormElement(target))
|
|
1411
1447
|
return;
|
|
@@ -1419,6 +1455,11 @@ function handleFocus(event) {
|
|
|
1419
1455
|
* 处理焦点失去
|
|
1420
1456
|
*/
|
|
1421
1457
|
function handleBlur(event) {
|
|
1458
|
+
// 检查配置
|
|
1459
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1460
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1422
1463
|
const target = event.target;
|
|
1423
1464
|
if (!target || !isFormElement(target))
|
|
1424
1465
|
return;
|