jQuery动态设置input值后触发blur/focusout时数值丢失问题求助
问题根因
你遇到的回退问题本质是多框架混合开发下的DOM值与框架内部状态不同步导致的,你用jQuery直接修改DOM节点的value属性,没有同步到管控该input的React/Dijit框架的内部状态,当blur触发框架的状态同步/重渲染逻辑时,框架会用自身存储的初始空值覆盖你修改的DOM值。
对应的现象也能验证这个判断:你手动修改input值时,会触发框架内置的输入事件回调,自动同步更新内部状态,所以值可以正常保留。
你之前做的事件监听移除、阻止冒泡等操作无效,是因为React的合成事件、Dijit的组件状态同步逻辑都是框架内部实现的,没有绑定在DOM节点的普通事件上,操作DOM层面的事件无法阻止框架的状态回写逻辑。
具体触发场景&对应解决方案
场景1:input是React受控组件
如果该input是React管控的受控组件,它的显示值完全与React组件内部的state绑定,你用jQuery修改DOM值绕开了React的状态更新流程,React内部存储的state还是初始空值,blur触发组件重渲染时就会还原。
解决方案
优先走React的标准更新逻辑:找到该input绑定的state对应的更新方法,直接修改state,React会自动同步到DOM:
// 假设是函数组件绑定了testValue状态 setTestValue('test')
如果必须用jQuery修改DOM,修改完成后手动触发input事件通知React同步状态:
const inputDom = $('#test')[0] inputDom.value = 'test' // 手动触发输入事件,触发React状态同步 inputDom.dispatchEvent(new Event('input', { bubbles: true })) inputDom.dispatchEvent(new Event('change', { bubbles: true }))
场景2:input是Dijit表单组件
如果该input是Dojo/Dijit的表单组件(比如dijit/form/TextBox这类),Dijit会把组件的实际值存在组件实例的内部属性中,不会直接读取DOM的value属性,你用jQuery修改DOM值后没有同步组件实例的状态,blur时Dijit会执行状态与DOM的同步逻辑,用实例存储的空值覆盖DOM值。
解决方案
使用Dijit官方API修改值,会自动同步实例状态和DOM:
// 先获取Dijit组件实例,再调用set方法更新值 dijit.byId('test').set('value', 'test')
内容的提问来源于stack exchange,提问作者Mech
相关产品推荐
相关产品推荐

