Javascript 如何以编程方式填充使用React生成的输入元素?
我的任务是用React创建爬行网站。我正在尝试填写输入字段,并使用javascript注入将表单提交到页面(selenium或mobile中的webview)。这在其他所有网站+技术上都很有魅力,但React似乎真的很痛苦 下面是一个示例代码Javascript 如何以编程方式填充使用React生成的输入元素?,javascript,reactjs,automation,web-crawler,Javascript,Reactjs,Automation,Web Crawler,我的任务是用React创建爬行网站。我正在尝试填写输入字段,并使用javascript注入将表单提交到页面(selenium或mobile中的webview)。这在其他所有网站+技术上都很有魅力,但React似乎真的很痛苦 下面是一个示例代码 var email = document.getElementById( 'email' ); email.value = 'example@mail.com'; I DOM输入元素上的值发生更改,但React不会触发更改事件 我一直在尝试过很多不同的方
var email = document.getElementById( 'email' );
email.value = 'example@mail.com';
I DOM输入元素上的值发生更改,但React不会触发更改事件
我一直在尝试过很多不同的方法来获得更新状态的响应
var event = new Event('change', { bubbles: true });
email.dispatchEvent( event );
无济于事
var event = new Event('input', { bubbles: true });
email.dispatchEvent( event );
不起作用
email.onChange( event );
不起作用
email.onChange( event );
我不敢相信与React的互动会变得如此困难。我将非常感谢任何帮助
谢谢React正在侦听文本字段的
输入事件
您可以更改该值并手动触发输入事件,react的onChange
处理程序将触发:
类表单扩展了React.Component{
建造师(道具){
超级(道具)
this.state={value:''}
}
手变(e){
this.setState({value:e.target.value})
console.log('State update to',e.target.value);
}
render(){
返回(
{this.state.value}
)
}
}
ReactDOM.render(
,
document.getElementById('app')
)
document.getElementById('textfield')。值='foo'
const event=new事件('input',{bubbles:true})
document.getElementById('textfield').dispatchEvent(事件)
由于重复数据消除输入和更改事件的更改,此公认的解决方案在React>15.6(包括React 16)中似乎不起作用
您可以在此处看到React讨论:
建议的解决方法如下:
为方便起见,此处复制:
而不是
input.value = 'foo';
input.dispatchEvent(new Event('input', {bubbles: true}));
你会用
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
然后
setNativeValue(input, 'foo');
input.dispatchEvent(new Event('input', { bubbles: true }));
DOM输入元素上的值发生更改,但React不会触发更改事件。
您希望发生什么更改事件?如果您能够成功填写输入字段,那么为什么不document.forms[0].submit()
?是的,这就是我试图做的-但是React验证器抱怨您必须填写值,即值没有传播到React组件啊,这很有趣-我理解。下面的答案帮助我解决了同样的问题,但我想知道你是否对你的问题的下半部分有什么指导,也就是提交表格?我无法通过在表单的提交按钮上触发.click()
,或在表单元素本身上触发.submit()
,或使用下面建议的dispatchEvent()
方法执行上述任一操作,成功提交react表单。但是,手动单击“提交”按钮不会正确提交表单。我错过了什么?谢谢,超时似乎起到了作用-我不太明白为什么会这样-但是如果我在没有超时的情况下做同样的事情(来自selenium),React永远不会得到事件。我确实在使用超时时遇到了一些问题,所以我必须找到一种解决方法。超时不是必需的,我添加它只是为了让示例更清楚。请参阅不带超时的更新。您需要确保的唯一一件事是,更改输入值的代码在react组件完全呈现后执行。确保我完全理解了它-问题是从Selenium进程调用事件不会触发,除非超时-您的示例现在与我在初始问题中的示例基本相同,因此我很确定selenium桥中有什么东西会弄乱js engineJust FYIconst event=new event('input',{bubbles:true})文档。getElementById('textfield')。dispatchEvent(event)
解决了我的大量调试问题。谢谢。请注意,如果您有一个选择
字段,则需要发送一个更改
事件,而不是输入
事件。这在greasemonkey中对我不起作用-可能与安全有关。。。它甚至尝试调用Object.getOwnPropertyDescriptor(..)
都失败了。对我来说,使用greasemonkey中的setNativeValue(..)
函数。如何将其更改为只需单击即可工作?另外,React似乎已更改,因此您需要立即发送一个“更改”事件,而不是直接在控制台中运行,而不是从加载项(Object.getOwnPropertyDescriptor(element,'value').set;
失败)。这对我来说似乎是可行的,但Typescript编译器对此并不满意:)多谢了。成功了:)