当.value和事件似乎不起作用时,使用JavaScript设置文本框的值

时间:2017-02-28 14:33:50

标签: javascript google-chrome-devtools

我正在尝试为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中执行此操作。我完全不知道为什么上面的解决方案都不起作用。

有人有任何建议吗?

2 个答案:

答案 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
}),

您可以在其上看到事件处理程序:onChangeonFocus。处理程序在之前定义。以下是片段:

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