378.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. window.zknumber = prompt("将当页折扣统一设置为:", "");
  2. if (window.zknumber !== null) {
  3. runJob ()
  4. }
  5. function forceReactUpdate(element, value) {
  6. console.log('🎯 强制React更新,新值:', value);
  7. // 方法1:尝试直接修改React内部状态
  8. const reactKeys = Object.keys(element).filter(key =>
  9. key.startsWith('__react') ||
  10. key.includes('Props') ||
  11. key.includes('Handler')
  12. );
  13. console.log('找到的React属性:', reactKeys);
  14. // 如果有React内部属性,尝试直接修改
  15. if (reactKeys.length > 0) {
  16. for (const key of reactKeys) {
  17. try {
  18. const obj = element[key];
  19. if (obj && typeof obj === 'object') {
  20. // 尝试找到onChange或onBlur
  21. if (obj.onChange) {
  22. console.log('找到 onChange,尝试调用');
  23. const event = {
  24. target: element,
  25. currentTarget: element,
  26. type: 'change'
  27. };
  28. element.value = String(value);
  29. obj.onChange(event);
  30. }
  31. if (obj.onBlur) {
  32. console.log('找到 onBlur,尝试调用');
  33. const event = {
  34. target: element,
  35. currentTarget: element,
  36. type: 'blur'
  37. };
  38. obj.onBlur(event);
  39. }
  40. }
  41. } catch (e) {
  42. console.warn('访问React属性失败:', key, e.message);
  43. }
  44. }
  45. }
  46. // 方法2:同时触发所有可能的事件
  47. console.log('🔨 触发所有相关事件');
  48. // 设置值
  49. element.value = String(value);
  50. // 创建事件数组,按正确顺序触发
  51. const eventSequence = [
  52. { type: 'focus', isFocus: true },
  53. { type: 'focusin', isFocus: true },
  54. { type: 'click' },
  55. { type: 'mousedown' },
  56. { type: 'mouseup' },
  57. { type: 'keydown', isKey: true, key: ' ' },
  58. { type: 'keypress', isKey: true, key: ' ' },
  59. {
  60. type: 'input',
  61. isInput: true,
  62. data: String(value),
  63. inputType: 'insertText'
  64. },
  65. { type: 'keyup', isKey: true, key: ' ' },
  66. { type: 'change' },
  67. { type: 'blur', isFocus: true },
  68. { type: 'focusout', isFocus: true }
  69. ];
  70. eventSequence.forEach((eventConfig, index) => {
  71. setTimeout(() => {
  72. let event;
  73. if (eventConfig.isFocus) {
  74. event = new FocusEvent(eventConfig.type, {
  75. bubbles: true,
  76. cancelable: true,
  77. view: window
  78. });
  79. } else if (eventConfig.isKey) {
  80. event = new KeyboardEvent(eventConfig.type, {
  81. bubbles: true,
  82. cancelable: true,
  83. key: eventConfig.key || ' ',
  84. code: eventConfig.key === ' ' ? 'Space' : 'Key' + eventConfig.key?.toUpperCase(),
  85. view: window
  86. });
  87. } else if (eventConfig.isInput) {
  88. event = new InputEvent(eventConfig.type, {
  89. bubbles: true,
  90. cancelable: true,
  91. data: eventConfig.data,
  92. inputType: eventConfig.inputType,
  93. view: window
  94. });
  95. } else {
  96. event = new Event(eventConfig.type, {
  97. bubbles: true,
  98. cancelable: true,
  99. view: window
  100. });
  101. }
  102. // 设置目标
  103. Object.defineProperty(event, 'target', { value: element });
  104. Object.defineProperty(event, 'currentTarget', { value: element });
  105. console.log(`触发 ${eventConfig.type} 事件`);
  106. element.dispatchEvent(event);
  107. }, index * 20); // 每个事件间隔20ms
  108. });
  109. // 最后触发blur
  110. setTimeout(() => {
  111. element.blur();
  112. console.log('✅ 所有事件已触发');
  113. }, eventSequence.length * 20 + 50);
  114. }
  115. // 或者使用 React Test Utilities 风格
  116. function simulateReactChange(element, value) {
  117. element.value = value;
  118. // React 16+ 使用这些事件
  119. element.dispatchEvent(new Event('input', { bubbles: true }));
  120. element.dispatchEvent(new Event('change', { bubbles: true }));
  121. // 对于 React 17+
  122. element.dispatchEvent(new Event('change', {
  123. bubbles: true,
  124. composed: true
  125. }));
  126. }
  127. function runJob () {
  128. document.querySelectorAll('[aria-label="percentageInput"]').forEach(element => {
  129. forceReactUpdate(element, window.zknumber)
  130. });
  131. setTimeout(() => {
  132. if (!document.querySelector('.andes-pagination__button--next').classList.contains('andes-pagination__button--disabled')) {
  133. document.querySelector('[title="Next"]').click()
  134. setTimeout(() => {
  135. runJob ()
  136. }, 2000);
  137. } else {
  138. alert('执行完毕!')
  139. }
  140. }, 1000);
  141. }