@dolphinweex/weex-harmony 0.1.26 → 0.1.28

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dolphinweex/weex-harmony",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "weex harmony adapter",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -59,7 +59,6 @@ export default {
59
59
  },
60
60
  methods: {
61
61
  onPageFinish() {
62
- console.log('加载完毕🥳','----->👉');
63
62
  this.$refs["iframe"].contentWindow.$midea_harmony_native = window.$midea_harmony_native;
64
63
  this.$refs["iframe"].contentWindow.isIframe = true;
65
64
  this.$refs["iframe"].contentWindow.postMessage(JSON.stringify(window.$midea_harmony_native), '*');
@@ -4,8 +4,9 @@
4
4
  :class="{ editMode: data.isEditing }"
5
5
  :style="gridItemStyle"
6
6
  >
7
+ <div class="items-container">
7
8
  <div class="grid-items-wrapper">
8
- <transition-group name="grid-fade" tag="div" class="grid-inner-wrapper">
9
+ <transition-group name="grid-fade" tag="div" class="grid-inner-wrapper">
9
10
  <div
10
11
  v-for="(item, index) in processedList"
11
12
  :key="item.itemView.id"
@@ -110,7 +111,7 @@
110
111
  </div>
111
112
  </transition-group>
112
113
  </div>
113
-
114
+ </div>
114
115
 
115
116
  <!-- 拖拽克隆元素 -->
116
117
  <div v-if="isDragClone" class="drag-clone" :style="dragCloneStyle">
@@ -200,10 +201,6 @@ export default {
200
201
  lastBestTarget: null,
201
202
  targetChangeTime: null,
202
203
  pendingTarget: null,
203
- weexListInnerEl: null,
204
- weexRefreshEl: null,
205
- originListInnerStyle: null,
206
- originRefreshStyle: null,
207
204
  };
208
205
  },
209
206
  computed: {
@@ -211,7 +208,6 @@ export default {
211
208
  return {
212
209
  '--grid-cols': this.data.spanCount || this.cols,
213
210
  '--grid-gap': `${this.data.spaceSize || 8}px`,
214
- '--grid-margin': `${(this.data.layoutConfig.marginStart ) + (this.data.layoutConfig.marginEnd )}px`,
215
211
  marginTop: this.data.layoutConfig.marginTop * scla,
216
212
  marginBottom: this.data.layoutConfig.marginBottom * scla,
217
213
  marginLeft: this.data.layoutConfig.marginStart * scla,
@@ -246,63 +242,30 @@ export default {
246
242
  },
247
243
  },
248
244
  methods: {
249
- searchDom(){
250
- //在 slider组件内部时 阻止默认行为和冒泡都无法在长按的时候 阻止其滚动行为 只能查找去禁止
251
- const currentEl = this.$el;
252
- let parentEl = currentEl.parentElement;
253
- let searchDepth = 0; // 搜索深度计数器
254
- while (parentEl && !parentEl.classList.contains('weex-list-inner') && searchDepth < 5) {
255
- parentEl = parentEl.parentElement;
256
- searchDepth++;
257
- }
258
-
259
- if (parentEl) {
260
- this.weexListInnerEl = parentEl;
261
- this.originListInnerStyle = parentEl.style.touchAction || '';
262
-
263
- // 在weex-list-inner中查找weex-refresh子元素
264
- const refreshEl = parentEl.querySelector('.weex-refresh');
265
- if (refreshEl) {
266
- this.weexRefreshEl = refreshEl;
267
- this.originRefreshStyle = refreshEl.style.height || '';
268
- }
269
- }
270
- },
271
245
  updateListItem(data) {
272
246
  console.log('updateListItem收到数据:', JSON.stringify(data));
273
247
  const id = data.itemView.id;
274
248
  const index = this.processedList.findIndex(
275
- (item) => item.itemView.id === id
249
+ (item) => item.itemView.id == id
276
250
  );
277
251
  const dataIndex = this.data.list.findIndex(
278
- (item) => item.itemView.id === id
252
+ (item) => item.itemView.id == id
279
253
  );
280
- // 更新原始数据以确保watch能触发
281
- if (dataIndex !== -1) {
282
- // 使用Vue的$set确保响应式更新
283
- this.$set(this.data.list, dataIndex, JSON.parse(JSON.stringify(data)));
284
- }
254
+
285
255
  if (index === -1) {
286
256
  return;
287
257
  }
288
258
 
289
-
290
-
291
259
  // 检查是否有动画URL的变化
292
260
  const oldBgAnimUrl = this.processedList[index].bgAnimView.animUrl || '';
293
261
  const oldLoadingAnimUrl =
294
262
  this.processedList[index].loadingAnimView.animUrl || '';
295
263
  const oldFrontAnimUrl =
296
264
  this.processedList[index].frontAnimView.animUrl || '';
265
+
297
266
  const newBgAnimUrl = data.bgAnimView.animUrl || '';
298
267
  const newLoadingAnimUrl = data.loadingAnimView.animUrl || '';
299
268
  const newFrontAnimUrl = data.frontAnimView.animUrl || '';
300
-
301
- const hasAnimUrlChanged =
302
- oldBgAnimUrl !== newBgAnimUrl ||
303
- oldLoadingAnimUrl !== newLoadingAnimUrl ||
304
- oldFrontAnimUrl !== newFrontAnimUrl;
305
-
306
269
  // 同时更新processedList和原始data.list数据
307
270
  this.processedList[index] = data;
308
271
  this.processedList = [...this.processedList];
@@ -314,83 +277,80 @@ export default {
314
277
  }
315
278
 
316
279
  // 如果动画URL有变化,重新初始化相关的Lottie动画
317
- if (hasAnimUrlChanged) {
280
+ console.log('检测到动画URL变化,重新初始化动画');
318
281
 
319
- // 等待下一帧DOM更新完成后再操作
320
- this.$nextTick(() => {
321
- // 清理旧的动画实例
322
- const itemId = data.itemView.id;
323
-
324
- // 清除所有相关的动画实例
325
- const animKeys = [
326
- `bg-${itemId}`,
327
- `loading-${itemId}`,
328
- `front-${itemId}`,
329
- ];
330
- animKeys.forEach((key) => {
331
- if (this.lottieAnimations[key]) {
332
- const anim = this.lottieAnimations[key];
333
- try {
334
- anim.removeEventListener('complete');
335
- anim.removeEventListener('DOMLoaded');
336
- anim.removeEventListener('data_ready');
337
- anim.removeEventListener('loaded_images');
338
- anim.removeEventListener('loopComplete');
339
- } catch (e) {
340
- }
341
- anim.destroy();
342
- delete this.lottieAnimations[key];
282
+ // 等待下一帧DOM更新完成后再操作
283
+ this.$nextTick(() => {
284
+ // 清理旧的动画实例
285
+ const itemId = String(data.itemView.id);
286
+
287
+ // 清除所有相关的动画实例
288
+ const animKeys = [
289
+ `bg-${itemId}`,
290
+ `loading-${itemId}`,
291
+ `front-${itemId}`,
292
+ ];
293
+ animKeys.forEach((key) => {
294
+ if (this.lottieAnimations[key]) {
295
+ console.log(`销毁动画实例: ${key}`);
296
+ const anim = this.lottieAnimations[key];
297
+ try {
298
+ anim.removeEventListener('complete');
299
+ } catch (e) {
300
+ console.warn(`移除事件监听器失败: ${e.message}`);
343
301
  }
344
- });
302
+ anim.destroy();
303
+ delete this.lottieAnimations[key];
304
+ }
305
+ });
345
306
 
307
+ console.log('清理完成,开始重新初始化动画');
346
308
 
347
- // 延迟一点时间确保DOM完全更新
348
- setTimeout(() => {
349
- // 重新初始化背景动画
350
- if (newBgAnimUrl) {
351
- this.loadLottieAnimation(
352
- data.bgAnimView,
353
- `bgAnim-${itemId}`,
354
- `bg-${itemId}`,
355
- data
356
- );
357
- }
309
+ // 延迟一点时间确保DOM完全更新
310
+ setTimeout(() => {
311
+ // 重新初始化背景动画
312
+ if (oldBgAnimUrl !== newBgAnimUrl) {
313
+ this.loadLottieAnimation(
314
+ data.bgAnimView,
315
+ `bgAnim-${itemId}`,
316
+ `bg-${itemId}`,
317
+ data
318
+ );
319
+ }
358
320
 
359
- // 重新初始化加载动画
360
- if (newLoadingAnimUrl) {
361
- this.loadLottieAnimation(
362
- data.loadingAnimView,
363
- `loadingAnim-${itemId}`,
364
- `loading-${itemId}`,
365
- data
366
- );
367
- }
321
+ if (oldLoadingAnimUrl !== newLoadingAnimUrl) {
322
+ this.loadLottieAnimation(
323
+ data.loadingAnimView,
324
+ `loadingAnim-${itemId}`,
325
+ `loading-${itemId}`,
326
+ data
327
+ );
328
+ }
368
329
 
369
- // 重新初始化前景动画
370
- if (newFrontAnimUrl) {
371
- this.loadLottieAnimation(
372
- data.frontAnimView,
373
- `frontAnim-${itemId}`,
374
- `front-${itemId}`,
375
- data
376
- );
377
- }
378
- }, 100); // 增加延迟确保DOM已更新和旧动画已完全销毁
379
- });
380
- }
330
+ if (oldFrontAnimUrl !== newFrontAnimUrl) {
331
+ this.loadLottieAnimation(
332
+ data.frontAnimView,
333
+ `frontAnim-${itemId}`,
334
+ `front-${itemId}`,
335
+ data
336
+ );
337
+ }
338
+ }, 100); // 增加延迟确保DOM已更新和旧动画已完全销毁
339
+ });
381
340
  },
382
341
  getListData(callback) {
383
342
  let data = Array.from(this.processedList);
384
- data = data.map((item)=>({
343
+ data = data.map((item) => ({
385
344
  ...item,
386
345
  itemView: {
387
346
  ...item.itemView,
388
- id:String(item.itemView.id)
389
- }
390
- }))
347
+ id: String(item.itemView.id),
348
+ },
349
+ }));
391
350
  callback({ listData: data });
392
351
  },
393
352
  rightIconClick(e) {
353
+ console.log('rightIconClick执行,阻止事件冒泡');
394
354
  e.preventDefault();
395
355
  e.stopPropagation();
396
356
  this.$emit('onClickRightIcon', e);
@@ -405,7 +365,9 @@ export default {
405
365
  selectIconClick(e, item, index) {
406
366
  e.preventDefault();
407
367
  e.stopPropagation(); // 阻止事件冒泡到itemViewClick
408
- item.itemView.isSelected = !item.itemView.isSelected;
368
+ if (item.selectIcon.visibility) {
369
+ item.itemView.isSelected = !item.itemView.isSelected;
370
+ }
409
371
  const target = {
410
372
  ...item.itemView,
411
373
  id: String(item.itemView.id),
@@ -413,7 +375,7 @@ export default {
413
375
  ...e,
414
376
  };
415
377
  this.$emit('onClickSelectIcon', target);
416
- this.$emit('onSelectItems',target)
378
+ this.$emit('onSelectItems', target);
417
379
  return false;
418
380
  },
419
381
 
@@ -422,25 +384,31 @@ export default {
422
384
  if (e.defaultPrevented) {
423
385
  return;
424
386
  }
425
- e.preventDefault();
426
- e.stopPropagation();
427
- // 确保取消任何长按计时器
428
- this.cancelLongPress();
429
- if (this.data.isEditing) {
430
- item.itemView.isSelected = !item.itemView.isSelected;
431
- this.$emit('onSelectItems',target)
432
- return;
433
- }
434
387
  const target = {
435
388
  ...item.itemView,
436
389
  id: String(item.itemView.id),
437
390
  index,
438
391
  ...e,
439
392
  };
393
+ console.log('itemViewClick');
394
+ // 确保取消任何长按计时器
395
+ this.cancelLongPress();
396
+ if (this.data.isEditing) {
397
+ if (item.selectIcon.visibility) {
398
+ item.itemView.isSelected = !item.itemView.isSelected;
399
+ }
400
+ return;
401
+ }
402
+ e.preventDefault();
403
+ e.stopPropagation();
404
+
440
405
  this.$emit('onClickItem', target);
406
+ this.data.isEditing&&item.selectIcon.visibility&&this.$emit('onSelectItems', target);
407
+
441
408
  },
442
409
 
443
410
  actionClick(e, item, index) {
411
+ console.log('actionClick执行,阻止事件冒泡');
444
412
  e.preventDefault();
445
413
  e.stopPropagation(); // 阻止事件冒泡到itemViewClick
446
414
 
@@ -459,44 +427,51 @@ export default {
459
427
 
460
428
  // 新增方法:清理除指定项目外的所有动画实例
461
429
  cleanupOtherAnimations(currentItemId) {
430
+ console.log('清理其他项目的动画实例,当前项目ID:', currentItemId);
462
431
 
463
- // 遍历所有动画实例
464
432
  Object.keys(this.lottieAnimations).forEach((key) => {
465
- // 检查是否为其他项目的动画
466
433
  if (!key.includes(`-${currentItemId}`)) {
467
434
  if (this.lottieAnimations[key]) {
435
+ console.log(`销毁其他项目的动画实例: ${key}`);
468
436
  const anim = this.lottieAnimations[key];
469
437
 
470
- // 移除所有事件监听器
471
- try {
472
- anim.removeEventListener('complete');
473
- anim.removeEventListener('DOMLoaded');
474
- anim.removeEventListener('data_ready');
475
- anim.removeEventListener('loaded_images');
476
- anim.removeEventListener('loopComplete');
477
- } catch (e) {
478
- console.warn(`移除事件监听器失败: ${e.message}`);
479
- }
480
-
481
- anim.destroy();
482
- delete this.lottieAnimations[key];
438
+ // 不要立即销毁,而是先停止动画
439
+ anim.pause();
483
440
 
484
- // 提取项目ID和动画类型
485
- const parts = key.split('-');
486
- if (parts.length === 2) {
487
- const animType = parts[0]; // bg, loading, front
488
- const itemId = parts[1];
489
-
490
- // 隐藏对应的动画容器
491
- this.$nextTick(() => {
492
- const refName = `${animType}Anim-${itemId}`;
493
- const animContainer =
494
- this.$refs[refName] && this.$refs[refName][0];
495
- if (animContainer) {
496
- animContainer.style.display = 'none';
441
+ // 使用 setTimeout 延迟销毁,给新动画一个启动的时间
442
+ setTimeout(() => {
443
+ try {
444
+ if (this.lottieAnimations[key] === anim) {
445
+ anim.removeEventListener('complete');
446
+ anim.destroy();
447
+ delete this.lottieAnimations[key];
448
+
449
+ // 提取项目ID和动画类型
450
+ const parts = key.split('-');
451
+ if (parts.length === 2) {
452
+ const animType = parts[0];
453
+ const itemId = parts[1];
454
+
455
+ // 延迟隐藏对应的动画容器
456
+ this.$nextTick(() => {
457
+ const refName = `${animType}Anim-${itemId}`;
458
+ const animContainer =
459
+ this.$refs[refName] && this.$refs[refName][0];
460
+ if (animContainer) {
461
+ // 使用 opacity 过渡而不是直接设置 display: none
462
+ animContainer.style.opacity = '0';
463
+ animContainer.style.transition = 'opacity 0.2s';
464
+ setTimeout(() => {
465
+ animContainer.style.display = 'none';
466
+ }, 200);
467
+ }
468
+ });
469
+ }
497
470
  }
498
- });
499
- }
471
+ } catch (e) {
472
+ console.warn(`清理动画失败: ${e.message}`);
473
+ }
474
+ }, 50);
500
475
  }
501
476
  }
502
477
  });
@@ -530,12 +505,12 @@ export default {
530
505
  // 使用mergeDate合并全局数据和项目数据
531
506
  processedItem[type] = this.mergeDate(item[type] || {}, type);
532
507
  });
533
-
534
508
  return processedItem;
535
509
  });
536
510
  },
537
511
  getItemStyle(item, type) {
538
512
  const result = this.mergeDate(item[type] || {}, type);
513
+ console.log(type, this.applyNormalAttribute(result), 'ggg');
539
514
  return this.applyNormalAttribute(result);
540
515
  },
541
516
  mergeDate(target, type) {
@@ -605,30 +580,34 @@ export default {
605
580
  return;
606
581
  }
607
582
  this.$emit('onDragEventStart', e);
583
+
584
+ // 只在编辑模式下阻止事件冒泡和默认行为
585
+ if (this.data.isEditing) {
586
+ if (e.oriEvent) {
587
+ // e.oriEvent.preventDefault();
588
+ // e.oriEvent.stopPropagation();
589
+ // e.oriEvent.stopImmediatePropagation();
590
+ }
591
+ // e.preventDefault && e.preventDefault();
592
+ // e.stopPropagation && e.stopPropagation();
593
+ // e.stopImmediatePropagation && e.stopImmediatePropagation();
594
+ }
595
+
608
596
  // 清除任何现有计时器
609
597
  this.cancelLongPress();
610
598
  // 记录起始触摸位置和索引
611
599
  const touch = e.changedTouches[0];
612
600
  this.touchStartX = touch.pageX;
613
601
  this.touchStartY = touch.pageY;
602
+ console.log('开始长按ddddddddd', touch, touch.pageY, touch.pageX);
614
603
  this.longPressStartIndex = index;
615
604
  this.isScrolling = false; // 重置滚动状态
616
605
 
617
- // 注意:不在这里阻止默认行为,允许滚动
618
- document.removeEventListener('touchmove', this.onTouchMove, {
619
- passive: true, // 设置为passive:true允许浏览器进行滚动优化
620
- });
621
- document.removeEventListener('touchend', this.onTouchEnd, {
622
- passive: true,
606
+ // 添加临时事件监听器,在长按期间阻止滚动
607
+ document.addEventListener('touchmove', this.onTouchMove, {
608
+ passive: false // 设置为false以允许阻止默认行为
623
609
  });
624
610
 
625
- if (this.isTouchDragging) {
626
- this.$emit('drag-end', {
627
- items: [...this.itemsList],
628
- });
629
- }
630
-
631
-
632
611
  // 设置新的长按计时器
633
612
  this.longPressTimer = setTimeout(() => {
634
613
  // 只有在没有滚动的情况下才激活拖拽模式
@@ -636,7 +615,6 @@ export default {
636
615
  this.activateDragMode(index);
637
616
  }
638
617
  }, this.longPressDuration);
639
- // 不阻止默认行为 - 允许滚动
640
618
  },
641
619
 
642
620
  // 检查长按过程中的移动
@@ -644,14 +622,28 @@ export default {
644
622
  if (!this.data.isEditable) {
645
623
  return;
646
624
  }
625
+
647
626
  const touch = e.changedTouches[0];
627
+ const moveX = Math.abs(touch.pageX - this.touchStartX);
628
+ const moveY = Math.abs(touch.pageY - this.touchStartY);
629
+
630
+ // 如果水平移动大于垂直移动,则阻止事件传播
631
+ if (moveX > moveY &&!this.isTouchDragging && this.data.isEditing) {
632
+ if (e.oriEvent) {
633
+ e.oriEvent.preventDefault();
634
+ e.oriEvent.stopPropagation();
635
+ e.oriEvent.stopImmediatePropagation();
636
+ e.preventDefault && e.preventDefault();
637
+ e.stopPropagation && e.stopPropagation();
638
+ e.stopImmediatePropagation && e.stopImmediatePropagation();
639
+ }
640
+ }
641
+
648
642
  // 如果已经在拖拽模式,交给onTouchMove处理
649
643
  if (this.isTouchDragging) {
650
644
  this.onTouchMove(e);
651
645
  return;
652
646
  }
653
- const moveX = Math.abs(touch.pageX - this.touchStartX);
654
- const moveY = Math.abs(touch.pageY - this.touchStartY);
655
647
 
656
648
  // 检测是否在滚动
657
649
  if (moveY > this.scrollThreshold * 3) {
@@ -665,14 +657,20 @@ export default {
665
657
  if (moveX > this.scrollThreshold || moveY > this.scrollThreshold) {
666
658
  this.cancelLongPress();
667
659
  }
668
- this.data.isEditing && e.oriEvent.stopPropagation()
669
- this.data.isEditing && e.oriEvent.preventDefault()
670
660
 
661
+ return false;
671
662
  },
672
663
 
673
664
  // 激活拖拽模式
674
665
  activateDragMode(index) {
675
666
  console.log('长按触发,进入编辑模式');
667
+ // 进入编辑模式
668
+
669
+ if(this.data.isEditing){
670
+ // 设置当前拖拽索引
671
+ this.draggingIndex = index;
672
+ this.isTouchDragging = true;
673
+
676
674
  // 此时添加阻止默认行为的事件监听,但只影响拖拽状态下的行为
677
675
  document.addEventListener('touchmove', this.onTouchMove, {
678
676
  passive: false, // 只有在拖拽模式下才阻止默认行为
@@ -680,50 +678,40 @@ export default {
680
678
  document.addEventListener('touchend', this.onTouchEnd, {
681
679
  passive: true,
682
680
  });
683
- if (this.data.isEditing) {
684
- // 设置当前拖拽索引
685
- this.draggingIndex = index;
686
- this.isTouchDragging = true;
687
-
688
- // 使用存储的固定宽高
689
- this.draggedItemRect = {
690
- width: this.fixedItemWidth,
691
- height: this.fixedItemHeight,
692
- };
693
-
694
- // 获取当前元素位置用于计算偏移
695
- const element = document.querySelectorAll('.grid-item')[index];
696
- if (element) {
697
- const rect = element.getBoundingClientRect();
698
- // 计算触摸点相对于元素左上角的偏移
699
- this.touchOffsetX = this.touchStartX - rect.left;
700
- this.touchOffsetY = this.touchStartY - rect.top;
701
-
702
- // 设置克隆元素的初始位置
703
- this.dragCloneX = rect.left;
704
- this.dragCloneY = rect.top;
705
-
706
- // 显示拖拽克隆
707
- this.isDragClone = true;
708
-
709
- // 立即执行一次定位以确保初始位置准确
710
- requestAnimationFrame(() => {
711
- this.dragCloneX = this.touchStartX - this.touchOffsetX;
712
- this.dragCloneY = this.touchStartY - this.touchOffsetY;
713
- });
714
681
 
715
- console.log('拖拽克隆已创建');
716
- }
682
+ // 使用存储的固定宽高
683
+ this.draggedItemRect = {
684
+ width: this.fixedItemWidth,
685
+ height: this.fixedItemHeight,
686
+ };
717
687
 
718
- this.longPressTimer = null;
688
+ // 获取当前元素位置用于计算偏移
689
+ const element = document.querySelectorAll('.grid-item')[index];
690
+ if (element) {
691
+ const rect = element.getBoundingClientRect();
692
+ // 计算触摸点相对于元素左上角的偏移
693
+ this.touchOffsetX = this.touchStartX - rect.left;
694
+ this.touchOffsetY = this.touchStartY - rect.top;
695
+
696
+ // 设置克隆元素的初始位置
697
+ this.dragCloneX = rect.left;
698
+ this.dragCloneY = rect.top;
699
+
700
+ // 显示拖拽克隆
701
+ this.isDragClone = true;
702
+
703
+ // 立即执行一次定位以确保初始位置准确
704
+ requestAnimationFrame(() => {
705
+ this.dragCloneX = this.touchStartX - this.touchOffsetX;
706
+ this.dragCloneY = this.touchStartY - this.touchOffsetY;
707
+ });
708
+
709
+ console.log('拖拽克隆已创建');
719
710
  }
720
- // 进入编辑模式
721
- if (!this.data.isEditing) {
722
- // 设置编辑状态并隐藏weex-refresh
723
- this.data.isEditing = true;
724
- this.$emit('onEditStateChanged', true);
725
- this.applyDragModeStyles(); // 应用编辑模式样式(隐藏refresh)
726
711
  }
712
+ this.data.isEditing = true;
713
+ this.$emit('onEditStateChanged', true);
714
+ this.longPressTimer = null;
727
715
  },
728
716
 
729
717
  // 取消长按计时器
@@ -739,6 +727,18 @@ export default {
739
727
  onTouchMove(e) {
740
728
  if (!this.isTouchDragging) return;
741
729
 
730
+ // 确保在拖拽模式下阻止所有事件传播
731
+ if (this.isTouchDragging && this.data.isEditing) {
732
+ if (e.oriEvent) {
733
+ e.oriEvent.preventDefault();
734
+ e.oriEvent.stopPropagation();
735
+ e.oriEvent.stopImmediatePropagation(); // 添加这行以确保事件不会继续传播
736
+ }
737
+ e.preventDefault && e.preventDefault();
738
+ e.stopPropagation && e.stopPropagation();
739
+ e.stopImmediatePropagation && e.stopImmediatePropagation();
740
+ }
741
+
742
742
  const touch = e.changedTouches[0];
743
743
 
744
744
  // 更新目标位置而非直接设置
@@ -853,8 +853,6 @@ export default {
853
853
  this.draggingIndex = bestTarget;
854
854
  this.lastSwapTime = now;
855
855
  }
856
- this.data.isEditing && e.oriEvent.stopPropagation()
857
- this.data.isEditing && e.oriEvent.preventDefault()
858
856
  },
859
857
 
860
858
  // 新增:平滑更新拖拽位置的方法
@@ -910,12 +908,13 @@ export default {
910
908
  this.isDragClone = false;
911
909
  this.hoverIndex = null;
912
910
  this.draggingIndex = null;
913
-
914
- // 如果不再拖拽,恢复touch-action(但保持refresh隐藏,因为仍在编辑状态)
915
- const elements = this.findParentElements();
916
- if (elements.listInner) {
917
- elements.listInner.style.touchAction = this.originListInnerStyle;
918
- }
911
+ this.lastBestTarget = null;
912
+ this.targetChangeTime = null;
913
+ this.pendingTarget = null;
914
+ this.touchStartX = 0;
915
+ this.touchStartY = 0;
916
+ this.targetTouchX = 0;
917
+ this.targetTouchY = 0;
919
918
  }
920
919
  },
921
920
 
@@ -923,9 +922,6 @@ export default {
923
922
  onTouchEnd(e) {
924
923
  console.log('全局触摸结束');
925
924
 
926
- // 恢复拖拽模式前的样式
927
- this.restoreDragModeStyles();
928
-
929
925
  // 移除全局事件监听
930
926
  document.removeEventListener('touchmove', this.onTouchMove, {
931
927
  passive: false,
@@ -976,10 +972,6 @@ export default {
976
972
  console.log(`销毁旧动画实例: ${key}`);
977
973
  try {
978
974
  anim.removeEventListener('complete');
979
- anim.removeEventListener('DOMLoaded');
980
- anim.removeEventListener('data_ready');
981
- anim.removeEventListener('loaded_images');
982
- anim.removeEventListener('loopComplete');
983
975
  } catch (e) {
984
976
  console.warn(`移除事件监听器失败: ${e.message}`);
985
977
  }
@@ -1000,7 +992,12 @@ export default {
1000
992
  setTimeout(() => {
1001
993
  // 为每个列表项初始化动画
1002
994
  this.processedList.forEach((item) => {
1003
- const itemId = item.itemView.id;
995
+ const itemId = String(item.itemView.id);
996
+ console.log('处理项目ID:', itemId);
997
+ console.log('loadingAnimView:', item.loadingAnimView);
998
+ console.log('bgAnimView:', item.bgAnimView);
999
+ console.log('frontAnimView:', item.frontAnimView);
1000
+
1004
1001
  // 加载背景动画
1005
1002
  this.loadLottieAnimation(
1006
1003
  item.bgAnimView,
@@ -1032,149 +1029,121 @@ export default {
1032
1029
  // 抽取公共的loadLottieAnimation方法
1033
1030
  loadLottieAnimation(animView, refName, animKey, item) {
1034
1031
  if (!animView || !animView.animUrl) {
1032
+ console.log(`[${animKey}] 跳过加载:animUrl不存在`);
1035
1033
  return;
1036
1034
  }
1037
1035
 
1036
+ console.log(
1037
+ `[${animKey}] 尝试初始化${refName}, animUrl:`,
1038
+ animView.animUrl
1039
+ );
1040
+
1038
1041
  const animEl = this.$refs[refName];
1039
1042
  if (!animEl || !animEl[0]) {
1043
+ console.warn(`[${animKey}] 未找到${refName}的DOM引用`);
1040
1044
  return;
1041
1045
  }
1042
1046
 
1043
1047
  try {
1044
- // 如果已经有实例,先销毁它
1048
+ // 如果已经有实例,先暂停它
1045
1049
  if (this.lottieAnimations[animKey]) {
1046
- this.lottieAnimations[animKey].destroy();
1047
- delete this.lottieAnimations[animKey];
1050
+ this.lottieAnimations[animKey].pause();
1048
1051
  }
1049
1052
 
1050
- // 确保animView.visibility不为0才初始化动画
1053
+ // 确保容器可见且透明度重置
1054
+ animEl[0].style.display = '';
1055
+ animEl[0].style.opacity = '1';
1056
+ animEl[0].style.transition = 'opacity 0.2s';
1057
+
1051
1058
  if (
1052
1059
  typeof animView.visibility !== 'number' ||
1053
1060
  animView.visibility !== 0
1054
1061
  ) {
1055
- // 使用fetch方式获取动画数据
1056
- fetch(animView.animUrl)
1057
- .then((response) => {
1058
- if (!response.ok) {
1059
- throw new Error('Network response was not ok');
1060
- }
1061
- return response.json();
1062
- })
1063
- .then((animationData) => {
1064
- // 再次检查是否已有实例(可能在fetch期间创建了)
1065
- if (this.lottieAnimations[animKey]) {
1066
- this.lottieAnimations[animKey].destroy();
1067
- delete this.lottieAnimations[animKey];
1068
- }
1062
+ // 延迟一帧再销毁旧实例
1063
+ requestAnimationFrame(() => {
1064
+ if (this.lottieAnimations[animKey]) {
1065
+ this.lottieAnimations[animKey].destroy();
1066
+ delete this.lottieAnimations[animKey];
1067
+ }
1069
1068
 
1070
- // 创建新的动画实例
1071
- const anim = lottie.loadAnimation({
1072
- container: animEl[0],
1073
- renderer: 'svg',
1074
- loop: Boolean(item.animRepeatCount) || false,
1075
- autoplay: true,
1076
- animationData: animationData,
1077
- rendererSettings: {
1078
- preserveAspectRatio: 'xMidYMid slice',
1079
- },
1080
- });
1081
-
1082
- // 保存动画实例
1083
- this.lottieAnimations[animKey] = anim;
1084
-
1085
- // 添加动画事件监听
1086
-
1087
- anim.addEventListener('complete', () => {
1088
- // 检查是否需要销毁动画(非循环动画完成后销毁)
1089
- if (!item.animRepeatCount) {
1090
- // 销毁前再次检查实例是否存在
1091
- if (this.lottieAnimations[animKey] === anim) {
1092
- anim.removeEventListener('complete');
1093
- anim.removeEventListener('DOMLoaded');
1094
- anim.removeEventListener('data_ready');
1095
- anim.removeEventListener('loaded_images');
1096
- anim.removeEventListener('loopComplete');
1097
- anim.destroy();
1098
- delete this.lottieAnimations[animKey];
1099
-
1100
- // 查找并隐藏对应的动画容器
1101
- this.$nextTick(() => {
1102
- const animContainer =
1103
- this.$refs[refName] && this.$refs[refName][0];
1104
- if (animContainer) {
1105
- animContainer.style.display = 'none';
1106
- }
1069
+ // 创建新的动画实例
1070
+ console.log(`[${animKey}] 创建新的动画实例`);
1071
+ const anim = lottie.loadAnimation({
1072
+ container: animEl[0],
1073
+ renderer: 'svg',
1074
+ loop: Boolean(item.animRepeatCount) || false,
1075
+ autoplay: true,
1076
+ path: animView.animUrl,
1077
+ rendererSettings: {
1078
+ preserveAspectRatio: 'xMidYMid slice',
1079
+ progressiveLoad: true, // 启用渐进式加载
1080
+ hideOnTransparent: true, // 优化透明度处理
1081
+ },
1082
+ });
1107
1083
 
1108
- // 将对应数据中的animUrl清空
1109
- const itemId = item.itemView.id;
1110
- const index = this.processedList.findIndex(
1111
- (i) => i.itemView.id === itemId
1084
+ this.lottieAnimations[animKey] = anim;
1085
+ anim.addEventListener('complete', () => {
1086
+ // 检查是否需要销毁动画(非循环动画完成后销毁)
1087
+ if (!item.animRepeatCount) {
1088
+ // 销毁前再次检查实例是否存在
1089
+ if (this.lottieAnimations[animKey] === anim) {
1090
+ anim.removeEventListener('complete');
1091
+ anim.destroy();
1092
+ delete this.lottieAnimations[animKey];
1093
+ // 将对应数据中的animUrl清空
1094
+ const itemId = String(item.itemView.id);
1095
+ const index = this.processedList.findIndex(
1096
+ (i) => i.itemView.id == itemId
1097
+ );
1098
+ if (index !== -1) {
1099
+ // 根据动画类型设置对应的animUrl为空
1100
+ if (animKey.startsWith('bg-')) {
1101
+ this.$set(
1102
+ this.processedList[index].bgAnimView,
1103
+ 'animUrl',
1104
+ ''
1112
1105
  );
1113
- if (index !== -1) {
1114
- // 根据动画类型设置对应的animUrl为空
1115
- if (animKey.startsWith('bg-')) {
1116
- this.$set(
1117
- this.processedList[index].bgAnimView,
1118
- 'animUrl',
1119
- ''
1120
- );
1121
- // 同步更新原始数据
1122
- const dataIndex = this.data.list.findIndex(
1123
- (i) => i.itemView.id === itemId
1124
- );
1125
- if (dataIndex !== -1) {
1126
- this.$set(
1127
- this.data.list[dataIndex].bgAnimView,
1128
- 'animUrl',
1129
- ''
1130
- );
1131
- }
1132
- } else if (animKey.startsWith('loading-')) {
1133
- this.$set(
1134
- this.processedList[index].loadingAnimView,
1135
- 'animUrl',
1136
- ''
1137
- );
1138
- // 同步更新原始数据
1139
- const dataIndex = this.data.list.findIndex(
1140
- (i) => i.itemView.id === itemId
1141
- );
1142
- if (dataIndex !== -1) {
1143
- this.$set(
1144
- this.data.list[dataIndex].loadingAnimView,
1145
- 'animUrl',
1146
- ''
1147
- );
1148
- }
1149
- } else if (animKey.startsWith('front-')) {
1150
- this.$set(
1151
- this.processedList[index].frontAnimView,
1152
- 'animUrl',
1153
- ''
1154
- );
1155
- // 同步更新原始数据
1156
- const dataIndex = this.data.list.findIndex(
1157
- (i) => i.itemView.id === itemId
1158
- );
1159
- if (dataIndex !== -1) {
1160
- this.$set(
1161
- this.data.list[dataIndex].frontAnimView,
1162
- 'animUrl',
1163
- ''
1164
- );
1165
- }
1166
- }
1167
- }
1168
- });
1106
+ this.$set(
1107
+ this.data.list[index].bgAnimView,
1108
+ 'animUrl',
1109
+ ''
1110
+ );
1111
+ } else if (animKey.startsWith('loading-')) {
1112
+ this.$set(
1113
+ this.processedList[index].loadingAnimView,
1114
+ 'animUrl',
1115
+ ''
1116
+ );
1117
+ this.$set(
1118
+ this.data.list[index].loadingAnimView,
1119
+ 'animUrl',
1120
+ ''
1121
+ );
1122
+ } else if (animKey.startsWith('front-')) {
1123
+ this.$set(
1124
+ this.processedList[index].frontAnimView,
1125
+ 'animUrl',
1126
+ ''
1127
+ );
1128
+ this.$set(
1129
+ this.data.list[index].frontAnimView,
1130
+ 'animUrl',
1131
+ ''
1132
+ );
1133
+ }
1134
+ console.log(`[${animKey}] 已清空动画URL数据`);
1135
+ item.addEventListener('touchstart', (e) => this.startLongPress(e, index), { passive: false });
1136
+ item.addEventListener('touchmove', this.checkLongPressMove, { passive: false });
1137
+ item.addEventListener('touchend', this.endTouch, { passive: false });
1138
+ item.addEventListener('touchcancel', this.endTouch, { passive: false });
1169
1139
  }
1170
1140
  }
1171
- });
1172
-
1173
- })
1174
- .catch((error) => {
1141
+ }
1175
1142
  });
1176
- }
1143
+ });
1144
+ }
1177
1145
  } catch (error) {
1146
+ console.error(`[${animKey}] 初始化失败:`, error);
1178
1147
  }
1179
1148
  },
1180
1149
 
@@ -1197,40 +1166,6 @@ export default {
1197
1166
  // 这里可以添加将来的处理逻辑
1198
1167
  return false;
1199
1168
  },
1200
-
1201
- // 查找父级元素和refresh元素
1202
- findParentElements() {
1203
- // 返回存储的元素引用
1204
- return {
1205
- listInner: this.weexListInnerEl,
1206
- refresh: this.weexRefreshEl
1207
- };
1208
- },
1209
-
1210
- // 进入拖拽模式时应用样式
1211
- applyDragModeStyles() {
1212
- const elements = this.findParentElements();
1213
-
1214
- // 设置weex-list-inner的touch-action: none(只在拖拽时)
1215
- if (elements.listInner && this.isTouchDragging) {
1216
- elements.listInner.style.touchAction = 'none';
1217
- }
1218
- },
1219
-
1220
- // 退出拖拽模式时恢复样式
1221
- restoreDragModeStyles() {
1222
- const elements = this.findParentElements();
1223
-
1224
- // 恢复weex-list-inner的touch-action(只在拖拽时修改)
1225
- if (elements.listInner && this.isTouchDragging) {
1226
- elements.listInner.style.touchAction = this.originListInnerStyle;
1227
- }
1228
-
1229
- // 如果不在编辑状态,恢复weex-refresh的display
1230
- if (elements.refresh && !this.data.isEditing) {
1231
- elements.refresh.style.display = 'flex';
1232
- }
1233
- },
1234
1169
  },
1235
1170
  watch: {
1236
1171
  // 监听初始数据变化
@@ -1247,9 +1182,20 @@ export default {
1247
1182
  handler(newList, oldList) {
1248
1183
  this.processedList = this.generateDataList();
1249
1184
  this.$nextTick(() => {
1250
- this.updateGridBoxWidth();
1251
- this.updateFixedItemSize();
1252
- this.initLottieAnimations();
1185
+ // 再次使用 nextTick 确保 DOM 完全更新
1186
+ this.$nextTick(() => {
1187
+ const gridItems = document.querySelectorAll('.grid-item');
1188
+ gridItems.forEach((item, index) => {
1189
+ const hasEvents = item._vei;
1190
+ if (!hasEvents) {
1191
+ item.addEventListener('touchstart', (e) => this.startLongPress(e, index), { passive: false });
1192
+ item.addEventListener('touchmove', this.checkLongPressMove, { passive: false });
1193
+ item.addEventListener('touchend', this.endTouch, { passive: false });
1194
+ item.addEventListener('touchcancel', this.endTouch, { passive: false });
1195
+ }
1196
+ });
1197
+ this.initLottieAnimations();
1198
+ });
1253
1199
  });
1254
1200
  },
1255
1201
  deep: true,
@@ -1258,119 +1204,12 @@ export default {
1258
1204
  processedList: {
1259
1205
  handler(newList, oldList) {
1260
1206
  if (!newList || !newList.length || this.isTouchDragging) return;
1261
-
1262
1207
  // 避免在拖拽过程中重新初始化动画
1263
1208
  if (this.draggingIndex !== null) return;
1264
-
1265
1209
  // 检查每个项目的动画URL是否有变化
1266
- newList.forEach((item, index) => {
1267
- // 如果是新增的项目,直接更新
1268
- if (!oldList || !oldList[index]) {
1269
- this.$nextTick(() => {
1270
- const itemId = item.itemView.id;
1271
- this.loadLottieAnimation(
1272
- item.bgAnimView,
1273
- `bgAnim-${itemId}`,
1274
- `bg-${itemId}`,
1275
- item
1276
- );
1277
- this.loadLottieAnimation(
1278
- item.loadingAnimView,
1279
- `loadingAnim-${itemId}`,
1280
- `loading-${itemId}`,
1281
- item
1282
- );
1283
- this.loadLottieAnimation(
1284
- item.frontAnimView,
1285
- `frontAnim-${itemId}`,
1286
- `front-${itemId}`,
1287
- item
1288
- );
1289
- });
1290
- return;
1291
- }
1292
-
1293
- // 检查bgAnimView.animUrl是否变化
1294
- if (
1295
- item.bgAnimView &&
1296
- oldList[index].bgAnimView &&
1297
- item.bgAnimView.animUrl !== oldList[index].bgAnimView.animUrl
1298
- ) {
1299
- this.$nextTick(() => {
1300
- const itemId = item.itemView.id;
1301
- if (this.lottieAnimations[`bg-${itemId}`]) {
1302
- this.lottieAnimations[`bg-${itemId}`].destroy();
1303
- delete this.lottieAnimations[`bg-${itemId}`];
1304
- }
1305
- this.loadLottieAnimation(
1306
- item.bgAnimView,
1307
- `bgAnim-${itemId}`,
1308
- `bg-${itemId}`,
1309
- item
1310
- );
1311
- });
1312
- }
1313
-
1314
- // 检查loadingAnimView.animUrl是否变化
1315
- if (
1316
- item.loadingAnimView &&
1317
- oldList[index].loadingAnimView &&
1318
- item.loadingAnimView.animUrl !==
1319
- oldList[index].loadingAnimView.animUrl
1320
- ) {
1321
- this.$nextTick(() => {
1322
- const itemId = item.itemView.id;
1323
- if (this.lottieAnimations[`loading-${itemId}`]) {
1324
- this.lottieAnimations[`loading-${itemId}`].destroy();
1325
- delete this.lottieAnimations[`loading-${itemId}`];
1326
- }
1327
- this.loadLottieAnimation(
1328
- item.loadingAnimView,
1329
- `loadingAnim-${itemId}`,
1330
- `loading-${itemId}`,
1331
- item
1332
- );
1333
- });
1334
- }
1335
-
1336
- // 检查frontAnimView.animUrl是否变化
1337
- if (
1338
- item.frontAnimView &&
1339
- oldList[index].frontAnimView &&
1340
- item.frontAnimView.animUrl !== oldList[index].frontAnimView.animUrl
1341
- ) {
1342
- this.$nextTick(() => {
1343
- const itemId = item.itemView.id;
1344
- if (this.lottieAnimations[`front-${itemId}`]) {
1345
- this.lottieAnimations[`front-${itemId}`].destroy();
1346
- delete this.lottieAnimations[`front-${itemId}`];
1347
- }
1348
- this.loadLottieAnimation(
1349
- item.frontAnimView,
1350
- `frontAnim-${itemId}`,
1351
- `front-${itemId}`,
1352
- item
1353
- );
1354
- });
1355
- }
1356
- });
1357
1210
  },
1358
1211
  deep: true,
1359
1212
  },
1360
- // 添加对编辑状态的监听
1361
- 'data.isEditing': {
1362
- handler(newValue) {
1363
- const elements = this.findParentElements();
1364
- if (elements.refresh) {
1365
- if (newValue) {
1366
- elements.refresh.style.maxHeight = '0px';
1367
- } else {
1368
- elements.refresh.style.maxHeight = '999px'
1369
- }
1370
- }
1371
- },
1372
- immediate: true
1373
- },
1374
1213
  },
1375
1214
  mounted() {
1376
1215
  console.log(this.data, 'djdjdjdjdjdjdj');
@@ -1379,8 +1218,6 @@ export default {
1379
1218
  // 获取并存储固定宽高
1380
1219
  this.updateFixedItemSize();
1381
1220
 
1382
- this.searchDom()
1383
-
1384
1221
  // 监听窗口大小变化,更新grid-box宽度
1385
1222
  window.addEventListener('resize', () => {
1386
1223
  this.updateGridBoxWidth();
@@ -1414,6 +1251,7 @@ export default {
1414
1251
  Object.keys(this.lottieAnimations).forEach((key) => {
1415
1252
  const anim = this.lottieAnimations[key];
1416
1253
  if (anim && typeof anim.destroy === 'function') {
1254
+ console.log(`组件销毁时清理动画: ${key}`);
1417
1255
  try {
1418
1256
  anim.removeEventListener('complete');
1419
1257
  anim.removeEventListener('DOMLoaded');
@@ -1421,6 +1259,7 @@ export default {
1421
1259
  anim.removeEventListener('loaded_images');
1422
1260
  anim.removeEventListener('loopComplete');
1423
1261
  } catch (e) {
1262
+ console.warn(`移除事件监听器失败: ${e.message}`);
1424
1263
  }
1425
1264
  anim.destroy();
1426
1265
  }
@@ -1433,11 +1272,6 @@ export default {
1433
1272
  created() {
1434
1273
  // 初始化处理后的数据列表
1435
1274
  this.processedList = this.generateDataList();
1436
-
1437
- // 添加测试拖拽模式的方法
1438
- window.testDragMode = (index = 0) => {
1439
- this.testDragMode(index);
1440
- };
1441
1275
  },
1442
1276
  };
1443
1277
  </script>
@@ -1455,6 +1289,10 @@ button {
1455
1289
  position: relative;
1456
1290
  }
1457
1291
 
1292
+ .items-container {
1293
+ width: 100%;
1294
+ }
1295
+
1458
1296
  .grid-items-wrapper {
1459
1297
  width: 100%;
1460
1298
  position: relative;
@@ -1464,7 +1302,7 @@ button {
1464
1302
  display: grid;
1465
1303
  grid-template-columns: repeat(var(--grid-cols), 1fr);
1466
1304
  grid-gap: var(--grid-gap);
1467
- width: calc(100% - var(--grid-margin));
1305
+ width: calc(100% - 74px);
1468
1306
  }
1469
1307
 
1470
1308
  /* 优化排序过渡效果 */