表单「点了没反应」的排查顺序:三次真事故换来的五步法
写自动化脚本最难的不是写代码,是判断「到底成没成」。尤其是那种点下去什么都不发生的按钮:没有 JS 报错,Network 面板一条新请求都没有,URL 不动,按钮的 class 也不变。你盯着屏幕看半分钟,只能得出一个结论——「好像没点上」。
我在一个后台系统上连着踩了三次,三次的原因完全不同,但排查顺序是同一套。
这类故障为什么特别坑
正常的失败会给你信号:接口返回 400,控制台飘红,页面弹出提示。而表单静默失败什么信号都不给,于是人本能地往两个方向猜——内容违规,或者账号被限流。
这两个猜测都很贵。为了验证内容违规,你会改文案、换配图、拆段落;为了验证限流,你会换浏览器、换网络、等一小时再试。我第一次为这件事折腾了将近一小时,最后发现真实原因和这两件事毫无关系。
所以第一条经验是:不要先怀疑账号,先怀疑页面。账号问题通常有痕迹(其他页面也失效、接口返回 403),页面问题才是「只有这一个按钮不灵」。
事故一:一个没有边框的复选框
页面最底部有一行声明文字,旁边有个 16×16 的 span。它没有边框、没有对勾图标、没有 hover 高亮,看起来就是一段普通文本。实际上它是必勾的同意框。
不勾选时点「发表」的表现是:完全没反应。没有 JS 报错,没有网络请求,URL 不变,按钮的 class 也不变。
最误导人的是按钮的 class 里带 -no。我一度以为那是禁用标志,后来发现新建一个空白页也是 -no,它只是常态样式。
正确的做法是直接改状态再验证:
const el = document.querySelector('#agreementBox');
el.click(); // DOM click,不是坐标点击
const cls = el.className; // 必须含 checked,否则按钮的 disabled 不会移除
这里还有一个细节:坐标点击不管用。滚动到可见后取中心点去点,elementFromPoint 命中的是底部一个浮层,点了四次都勾不上,DOM 的 click() 一次成功。原因很可能是这个组件绑在 click 事件上,而浮层挡住了真实鼠标事件。
事故二:提交按钮把自己变灰了
第二个表单的提交按钮有 disabled 属性。填完所有可见字段后按钮是亮的,点下去的一瞬间,按钮变灰、底部勾好的同意框自己取消了、没有任何请求发出去。
看起来像是「提交后重置了表单」,实际是校验没通过,页面回滚了状态。
根因在关联产品那个多选组件上:它的值由两个地方保存,一个是给用户看的 chip,一个是隐藏字段。隐藏字段只在输入框触发 blur 时由组件内部同步一次。脚本点下拉项只加了 chip,没走 blur,隐藏字段还是空字符串。提交时校验读到空值,直接静默 return false,顺手把同意框取消、把按钮禁用。
修法是选完标签主动失焦,然后直接读隐藏字段确认:
input.focus();
input.blur();
const v = document.querySelector('#labelTxt').textContent; // 不要看按钮是否可点
这条经验的通用形式是:按钮能不能点,不代表表单状态对不对。真正要看的是校验函数读的那个值。
事故三:坐标算对了,点到别处去了
第三个不是逻辑问题,是点击本身打偏了。页面开了平滑滚动,scrollIntoView 之后立刻取 getBoundingClientRect(),此时滚动动画还在跑,算出来的坐标属于上一个位置。结果点提交按钮,实际点到了底部的同意框——于是出现了「点一次提交,勾选反而没了」的诡异现象。
判断方法很简单,点击前先自检命中项:
const r = btn.getBoundingClientRect();
const cx = r.left + r.width / 2, cy = r.top + r.height / 2;
const hit = document.elementFromPoint(cx, cy);
if (!btn.contains(hit) && hit !== btn) {
console.log('打偏了,实际命中:', hit.tagName, hit.className);
}
如果命中项不对,等滚动停稳再算一次,或者干脆改用 DOM click()——多数表单按钮对 .click() 是有反应的,只有少数依赖可信事件的地方才必须用真实鼠标。
固定下来的五步
三次踩完,我把顺序固定成下面这样,从上往下走,基本不会绕远路:
1. 滚到页面最底部,把所有看起来像文字的东西点一遍。 复选框可以完全没有视觉特征,这一条能解决一半问题。
2. 用 elementFromPoint 看坐标命中的是谁。 有浮层遮挡时,先关浮层再点。
3. 读隐藏字段,确认表单真实状态。 不要用「按钮是否置灰」反推。
4. 看事件绑定类型。 有些按钮只绑 mousedown,click() 无效;有些反过来。用 DOMDebugger.getEventListeners 一眼能看出来。
5. 最后才去读压缩后的源码。 这一步成本最高,收益最低,前四步能解决绝大多数情况。
一句总结
「点了没反应」不是没有原因,是原因不在你能看见的地方。先把页面上所有可疑的、像文字的元素都点一遍,再去看坐标和隐藏字段,最后才怀疑账号——顺序对了,一小时能压到五分钟。
- 点赞
- 收藏
- 关注作者
评论(0)