V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
snimstice
V2EX  ›  前端开发

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

  •  
  •   snimstice · 81 天前 · 1042 次点击
    这是一个创建于 81 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    兼容性最好的方法就是模拟键盘输入
    sharida
        10
    sharida  
       81 天前
    /**
    * 触发 dom 的 input 事件
    * @param {Element} ele dom 元素
    */
    function dispatchInputEvent(ele) {
    const inputEvent = new InputEvent('input');
    ele.dispatchEvent(inputEvent);
    }

    试试
    krapnik
        11
    krapnik  
       81 天前
    @snimstice 发下地址?
    18601294989
        12
    18601294989  
       81 天前
    如果是 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
        13
    snimstice  
    OP
       80 天前
    @krapnik 是一个内网的页面,得挂着 vpn 才能访问
    snimstice
        14
    snimstice  
    OP
       80 天前
    @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
        15
    snimstice  
    OP
       80 天前
    @sharida 感谢,试了一下(楼上有代码),但是似乎还是不行
    snimstice
        16
    snimstice  
    OP
       80 天前
    @krapnik
    @cydysm
    @eason1874
    @sharida
    @18601294989
    感谢所有人,问题解决了。确实需要自定义事件。监听 change 事件就好了,应该是页面监听的是 change 事件,不是 input 事件
    最终代码如下:
    el.setAttribute('value', value)
    el.value = value
    el.dispatchEvent(new Event('change'));
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   3761 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 06:03 · PVG 14:03 · LAX 22:03 · JFK 01:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.