[前端] 通过 JS 直接改变 input 的 value,在提交表单的时候无法通过校验:提示 input 的值不能为空,有解决办法吗

2022-11-14 11:32:57 +08:00
 snimstice

请问这个问题出现的原因是什么呢?
通过 JS 直接改变 value 与用户手动输入有什么区别呢?能否通过 JS 来模拟用户真实的输入呢?
拜托大家了🙏🙏

1834 次点击
所在节点    前端开发
16 条回复
wunonglin
2022-11-14 11:35:41 +08:00
用 stackBlitz 之类的工具,附上代码
shuxhan
2022-11-14 11:59:18 +08:00
不太可能出现你这种情况,除非校验的方式是判断失去焦点时获取 value
krapnik
2022-11-14 12:05:02 +08:00
https://note.ms/uzvf vue2 的时候整过
cydysm
2022-11-14 12:06:07 +08:00
不知道你是用了框架还是用了原生 js 开发
之前在 vue 中业务也有这个需求,在改变值后 emit change input 事件
snimstice
2022-11-14 12:12:54 +08:00
@cydysm 页面是其他人的,我是给这个页面开发一个 chrome 的插件,帮助填写工单的。不太清楚这个页面的代码是怎么写的,但是确认没用 vue
snimstice
2022-11-14 12:13:53 +08:00
@krapnik 感谢~我试了一下,还是没有通过校验
snimstice
2022-11-14 12:15:14 +08:00
@shuxhan 亲眼所见~已经被折腾一天了
snimstice
2022-11-14 12:17:01 +08:00
@wunonglin 感谢,但是我没有代码。我开发的是 chrome 插件,辅助用户填写表单的。通过 js 改变 input 的 value ,改了之后死活通不过那个页面上表单项的校验
eason1874
2022-11-14 12:25:49 +08:00
几年前遇到过,基本就是两种情况

一是赋值和取值方式不兼容,记不清了,反正就是 attr 之类的,取不到

二是输入表单并非提交表单,输入框监听键入事件,键入时把值同步到真正提交的表单,如果你直接修改输入框的值那就没发生键入事件,那就不会同步,所以真正提交的还是空

兼容性最好的方法就是模拟键盘输入
sharida
2022-11-14 12:33:34 +08:00
/**
* 触发 dom 的 input 事件
* @param {Element} ele dom 元素
*/
function dispatchInputEvent(ele) {
const inputEvent = new InputEvent('input');
ele.dispatchEvent(inputEvent);
}

试试
krapnik
2022-11-14 12:34:28 +08:00
@snimstice 发下地址?
18601294989
2022-11-14 13:09:19 +08:00
如果是 React 写的可以试试 这段代码

function changeReactInputValue(inputDom,newText){
let lastValue = inputDom.value;
inputDom.value = newText;
let event = new Event('input', { bubbles: true });
event.simulated = true;
let tracker = inputDom._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
inputDom.dispatchEvent(event);
}
snimstice
2022-11-14 14:24:17 +08:00
@krapnik 是一个内网的页面,得挂着 vpn 才能访问
snimstice
2022-11-14 14:26:11 +08:00
@eason1874
el.addEventListener('input', e => {
console.log('input trigger: ', e)
})
el.setAttribute('value', value)
el.value = value
const inputEvent = new InputEvent('input');
el.dispatchEvent(inputEvent);

请问我这样写算是模拟键盘输入吗?我监听的事件可以触发,但是最终表单校验还是没有通过
snimstice
2022-11-14 14:26:38 +08:00
@sharida 感谢,试了一下(楼上有代码),但是似乎还是不行
snimstice
2022-11-14 14:36:18 +08:00
@krapnik
@cydysm
@eason1874
@sharida
@18601294989
感谢所有人,问题解决了。确实需要自定义事件。监听 change 事件就好了,应该是页面监听的是 change 事件,不是 input 事件
最终代码如下:
el.setAttribute('value', value)
el.value = value
el.dispatchEvent(new Event('change'));

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/895063

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX