更改通过chrome扩展做出反应的输入值

时间:2019-01-10 22:31:21

标签: reactjs google-chrome-extension

我正在使用Chrome扩展程序,我需要从CSV读取的数字中更新用React生成的html页面的许多输入。我无法更新该网站。

- 从呈现的网站复制输入的示例:

  <td><input class="input input_small fpInput" value="29,4"></td>

- 它是如何制作的(不确定100%是否必须阅读uglified js源代码)

{
    key: "render",
    value: function () {
        return s.a.createElement("input", {
            className: "input input_small fpInput",
            value: this.state.value,
            onChange: this.handleChange,
            onBlur: this.handleSubmit,
            onFocus: this.handleFocus
        })
    }
}

- 每次更改输入值时,都会调用一个函数,并进行POST进行保存。

在更改输入值以触发POST之后,我想从扩展程序中触发onBlur()onChange()

我尝试过:

var el = document. ... .querySelector('input'); // the selector is simplied of course
el.value = 321;
el.onChange();  // ERROR onChange is not a function
el.onchange();  // ERROR onchange is not a function
el.handleChange(); // ERROR handleChange is not a function

请问有什么想法吗?

3 个答案:

答案 0 :(得分:2)

要详细说明@varoons的答案,尽管略有解释,但实际上是正确的。

您可以通过将事件注入(以浏览器的方式调度)到dom中来做到这一点:

// Needs setAttribute to work well with React and everything, just `.value` doesn't cut it
// Also changed it to a string, as all attributes are strings (even for <input type="number" />)
el.setAttribute("value", "321"); 

// As @wOxxOm pointed out, we need to pass `{ bubbles: true }` to the options,
// as React listens on the document element and not the individual input elements
el.dispatchEvent(new Event("change", { bubbles: true }));
el.dispatchEvent(new Event("blur", { bubbles: true }));

这实际上将调用所有侦听器,甚至包括那些由React构成的侦听器(就像去掉代码的代码一样;)或由简单的element.onChange = () => {...}侦听器构成的侦听器。

示例:https://codesandbox.io/s/kml7m2nn4r

答案 1 :(得分:1)

您不能直接从它呈现的DOM元素中调用React组件的方法。您需要触发一个冒泡的事件,以便React可以在document级别捕获它并正常处理它,就像处理真实事件一样。

✨Document.execCommand():

@woxxom在评论中指出,最简单的方法可能是集中输入,然后使用Document.execCommand()

const input1 = document.getElementById('input1');
const input2 = document.getElementById('input2');

input1.focus();
document.execCommand('insertText', false, 'input1');

input2.focus();
document.execCommand('insertText', false, 'input2');
<input id="input1" />
<input id="input2" />

⚒️手动调度事件:

否则,您可以在更改它们的值后使用dispatching a change, input and/or blur event在这些字段中手动尝试Event() constructor

另外,请注意Event()的第二个可选参数包含一个字段bubbles,默认情况下为false您需要一个true 。否则,这将不起作用,因为React正在监听document上的事件。

此外,您可能还需要使用Element.setAttribute(),因为这将更新DOM上的value属性(字段的初始值),而element.value将更新当前属性。值(以及显示值)。通常,虽然不需要。有关更多信息,请参见What is the difference between properties and attributes in HTML?

在更新多个输入时,这种方法可能会遇到一些时序问题,您可能需要使用setTimeout来解决,因此,如果第一个输入可行,我会改用那个输入。

const input1 = document.getElementById('input1');

// This updates the value displayed on the input, but not the DOM (you can do that with setAttribute,
// but it's not needed here):
input1.value = 'input1';

// Dispatch an "input" event. In some cases, "change" would also work:
input1.dispatchEvent(new Event('input', { bubbles: true }));

// It looks like only one field will be updated if both events are dispatched
// straight away, so you could use a setTimeout here:

setTimeout(() => {
  const input2 = document.getElementById('input2');
  input2.value = 'input2';
  input2.dispatchEvent(new Event('input', { bubbles: true }));    
});
<input id="input1" />
<input id="input2" />

答案 2 :(得分:0)

el.dispatchEvent(new CustomEvent("change"))