我正在尝试为PayPal捐赠基金donation page上的文本框设置一个值,并且彻底难倒。
这是我尝试过的:
设置input.value
从Chrome devtools,如果我运行以下JavaScript:
document.getElementById('nemo_inputAmount').value = '1'
值“1”出现在文本框中,但是当我单击“立即捐赠”按钮时,该值将被清除,表单不会提交。
发送活动
我使用Chrome devtools监控所有事件,当我选中文本框,输入值'1',然后选项卡。
然后我使用下面的代码重新创建了每个事件。使用此方法,值“1”甚至不会出现在文本框中。我已经尝试过各种我能想到的调度事件的组合和风格。
function textEvent(text) {
let textEvent = document.createEvent('TextEvent');
textEvent.initTextEvent('textInput', true, true, null, text);
return textEvent;
}
function setDonationAmount(amount) {
let amountInput = document.querySelector('input#nemo_inputAmount');
if (amountInput) {
console.log('Setting amount to', amount)
const events = [
new FocusEvent('focus', {
composed: true
}),
new Event('select', {
bubbles: true
}),
new KeyboardEvent('keydown', {
bubbles: true,
cancelable: true,
composed: true,
code: 'Digit1',
key: '1',
keyCode: 49,
which: 49
}),
new KeyboardEvent('keypress', {
bubbles: true,
cancelable: true,
composed: true,
code: 'Digit1',
key: '1',
keyCode: 49,
which: 49
}),
textEvent('1'),
new Event('input', {
bubbles: true
}),
new KeyboardEvent('keyup', {
bubbles: true,
cancelable: true,
composed: true,
code: 'Digit1',
key: '1',
keyCode: 49,
which: 49
}),
new Event('change', {
bubbles: true
}),
new FocusEvent('blur', {
composed: true
})
]
events.forEach(function(event) {
amountInput.dispatchEvent(event);
})
}
}
setDonationAmount('1');
正如您所看到的,我正在尝试在纯JavaScript中执行此操作。我完全不知道为什么上面的解决方案都不起作用。
有人有任何建议吗?
答案 0 :(得分:2)
输入是React组件的一部分。我能够通过在源头搜索输入的ID(nemo_inputAmount
)来找到它。这次搜索将我带到组件的渲染功能。这是相关部分:
_react2.default.createElement('input', {
type: 'text',
id: 'nemo_inputAmount',
className: inputBoxStyling,
onChange: this.handleInputChange,
onFocus: this.handleInputFocus,
value: this.state.inputAmount,
autoComplete: 'off',
placeholder: 'Other Amount',
required: true
}),
您可以在其上看到事件处理程序:onChange
和onFocus
。处理程序在之前定义。以下是片段:
handleInputChange: function handleInputChange(event) {
var value = event.target.value;
var input = (0, _parseAmount2.default)(value);
if (input === undefined) {
return this.invalid();
}
this.setState({
inputAmount: input
});
},
handleInputFocus: function handleInputFocus() {
this.setState({
selectedAmount: '',
radioBtnClicked: false,
clickedIndex: -1
});
},
您可以看到,当输入更改时,它会将商店中的inputAmount
更改为新金额。如果您回顾createElement
函数,可以看到商店中的inputAmount
绑定到value
的{{1}}属性。
input
这意味着仅在触发相关事件时才运行事件处理程序时设置输入的值。
以编程方式设置 value: this.state.inputAmount,
属性不会触发事件,这就是为什么您的输入会保持清除,因为商店未更新,因此它仍为空。
为了使它成功,你将需要这个:
value
此部分会创建一个新的const input = document.getElementById('nemo_inputAmount');
const event = new Event('input', { bubbles: true });
input.value = '1';
input.dispatchEvent(event);
事件,这是input
实际响应的事件 - 我没有查看React来源以确认,此声明基于观察和这Stack Overflow answer。
handleInputChange
然后该部分调度该事件。
const event = new Event('input', { bubbles: true });
答案 1 :(得分:0)
这是唯一对我有用的东西,适用于 Edge:
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(textarea, 'some text');
textarea.dispatchEvent(new Event('input', { bubbles: true }));
从此处获取:https://github.com/facebook/react/issues/10135#issuecomment-314441175