我正在构建一个运行JavaFX Webkit的无头爬虫,它肯定不如chrome的v8强大。
但是我最近遇到了问题,我正在尝试输入一个值来对渲染的输入字段做出反应。
这是我到目前为止所做的并且失败了。[注意:我无法控制源/ React代码。由于我正在尝试抓取目标网站]
$('input.r_input').val("2");
document.querySelector("input.r_input").value = "2";
创建手动事件,如:
event = new Event( event, {target: obj, bubbles: true} );
event.simulated = true;
return obj ? obj.dispatchEvent(event) : false;
并触发input
事件。
以上都不起作用。
如果可能有助于添加更多上下文,我会在网站上的JS文件中添加部分反应代码。
创建:
t.prototype.createInputProps = function(e) {
return {
disabled: this.props.submitting || e > this.focusIndex,
className: "r_input",
type: "tel",
name: "tan-" + e,
maxLength: 1,
pattern: "[\\d]*",
tabIndex: 0,
placeholder: "·",
autoComplete: "off"
}
}
渲染:
t.prototype.render = function() {
var e = this.props,
t = e.meta,
n = t.touched,
r = t.error,
o = (e.input.value, sa()("r_input", {
"has-error": r && n
}));
return us("article", {
className: o
}, void 0, us("div", {
className: "r_inputs"
}, void 0, ro.a.createElement("input", as({
onPaste: this.handleOnPaste,
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(0)
}, this.createInputProps(0))), ro.a.createElement("input", as({
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(1)
}, this.createInputProps(1))), ro.a.createElement("input", as({
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(2)
}, this.createInputProps(2))), ro.a.createElement("input", as({
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(3)
}, this.createInputProps(3))), ro.a.createElement("input", as({
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(4)
}, this.createInputProps(4))), ro.a.createElement("input", as({
ref: this.addInputToList,
onKeyUp: this.handleKeyUp,
value: this.getValue(5)
}, this.createInputProps(5)))), n && r && us(is.a, {}, void 0, r))
}
不确定我是否需要添加handleKeyUp
,但其中包含一些验证码。
任何帮助将不胜感激。
答案 0 :(得分:1)
在您的情况下,看起来您可以在更改值后在元素上触发keyup
事件。您可能还必须根据React状态更改等待元素出现在DOM中。试试这个
setTimeout(function() {
var event = new Event('keyup', { bubbles: true });
$('input.r_input').val("2")[0].dispatchEvent(event);
}, 3000);
如果无法访问相关网页,当然很难提供明确的内容。
注意:我想出伏都教通过this thread发送keyup
事件,该事件表示React onChange
处理程序侦听input
事件并查看代码您提供了哪些电话onKeyUp
。我的示例代码在React& amp;中使用了onChange
处理程序。调度链接线程中规定的input
事件。
另请注意:我无法使用jQuery的trigger
方法,也许您可以弄清楚我在那里缺少的内容,但使用本机Javascript的事件调度正在下面的代码段中工作。
继续阅读以获取详细信息!
您的问题没有单一的答案,因为给定的React组件从input
字段读取值的方式可能会有所不同,因此您需要查看您尝试操作的每个React实现。我猜测onChange
是React在文本字段中捕获输入的最常用方法。 The React onChange
handler listens for input
events
在jQuery's .ready()
callback触发后,React的状态也可能会更新,导致您要查找的元素被添加到DOM中。这意味着你的选择器没有找到任何东西,因为他们正在寻找的元素在他们看的时候不存在于DOM中。 (这就是我在建议的解决方案中添加setTimeout
)的原因。
这里我说明了在React状态更改后出现在DOM中的元素的问题,以及一个工作示例,其中jQuery用于设置由React管理的input
元素的值。 (确保在运行它时查看控制台输出以了解正在发生的事情),当HTML全部完成时,您应该在HTML中看到它
React认为该值为50
jQuery(function() {
console.log('jquery loaded');
function searchForNodeOfInterest() {
console.log('jQuery searching for nodes of interest');
if(jQuery('#interesting-node').length === 0) {
console.log('jQuery did not find the selector of interest');
} else {
console.log('jQuery found the selector of interest, setting input value...');
var event = new Event('input', { bubbles: true });
jQuery('#interesting-node').val(50)[0].dispatchEvent(event);
}
}
searchForNodeOfInterest();
setTimeout(searchForNodeOfInterest, 4000);
console.log('jQuery - taking a nap, I will search again soon...');
});
var App = React.createClass({
getInitialState: function() {
return {
hidden: true
};
},
componentDidMount: function() {
console.log('react mounted');
},
// Imagine something happens inside react (AJAX response comes in for example),
// causing the nodes of interest to be rendered in DOM
componentWillMount: function() {
var that = this;
setTimeout(function() {
console.log('react updating the state...');
that.setState({
hidden: false,
value: null
})
}, 2000);
},
handleInput: function(e) {
console.log('react handling input...', e.target.value);
this.setState({
value: e.target.value
})
},
render: function() {
return this.state.hidden ? null : <form>React Powered Input: <input type="text" id="interesting-node" onChange={this.handleInput}/><p>React thinks the value is {this.state.value}</p></form>
}
});
ReactDOM.render(<App />, document.getElementById('react'));
<body>
<div id="react"></div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
在一段随机时间内,比setTimeout
更可靠的技术是一个包装器,它定期检查是否存在选择器like this。
答案 1 :(得分:0)
我可以想象你根本无法做到。 这取决于它是如何实现的以及它正在监听的事件。
如果控制React组件并注册&#39; onChange&#39;事件,那么它可能是可能的。
如果它是不受控制的组件,那么我猜它可能不起作用。 即使你以某种方式填写输入。在表单提交时,它可能仍在使用其内部状态的值。
答案 2 :(得分:0)
首先验证该元素是否存在香草if。如果它存在,那么以编程方式填充它。请注意,某些UI库可能需要在动态添加值时进行初始化或升级。
if(document.getElementById("my-input")){
document.getElementById("my-input").value = "foo";
}
如果您使用脚本添加元素,则可能需要在创建元素后附加事件侦听器。