javascript - 以编程方式填充 ReactJS 输入的正确方法

标签 javascript jquery reactjs

我正在构建一个运行 JavaFX Webkit 的 headless 爬虫,它肯定没有 chrome 的 v8 强大。

但是我最近遇到了一些问题,我试图输入一个值来对呈现的输入字段使用react。

这是我到目前为止所做的但失败了。[ 注意:我无法控制源代码/React 代码。因为我正在尝试抓取目标网站 ]

  1. jQuery - $('input.r_input').val("2");
  2. Vanila JS - document.querySelector("input.r_input").value = "2";
  3. 通过 jquery 触发器触发更改事件 - change、blur、keyup、keydown 等。
  4. 创建一个手动事件,例如:

    event = new Event( event, {target: obj, bubbles: true} ); 事件.simulated = true; 返回对象? obj.dispatchEvent(事件) : false;

并触发一个input事件。

以上均无效。

我正在从网站上的 JS 文件中添加部分 React 代码,如果它可能有助于添加更多上下文的话。

创建:

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,但其中包含一些验证代码。

我们将不胜感激。

最佳答案

在您的情况下,看起来您可以在更改值后在元素上触发 keyup 事件。您可能还需要等待元素出现在 DOM 中,基于 React 状态变化。试试这个

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 中使用 onChange 处理程序并按照链接线程中的规定分派(dispatch) input 事件。

另请注意:我未能将其与 jQuery 的 trigger 一起使用方法,也许你能弄清楚我在那里遗漏了什么,但在我下面的代码片段中使用 native Javascript 进行事件调度是可行的。

继续阅读了解详情!


您的问题没有单一的答案,因为给定的 React 组件从 input 字段中读取值的方式可能会有所不同,因此您需要查看您尝试操作的每个 React 实现.我猜测 onChange 是 React 捕获文本字段中输入的最常见方式。 The React onChange handler listens for input events .

也有可能 React 的状态正在更新,导致您要查找的元素在 jQuery's .ready() callback 之后添加到 DOM 中。火灾。这意味着你的选择器没有找到任何东西,因为他们正在寻找的元素在他们寻找时不存在于 DOM 中。 (这就是我在建议的解决方案中添加 setTimeout 的原因)。

在这里,我说明了在 React 状态更改后元素出现在 DOM 中的问题,以及一个工作示例,其中 jQuery 用于设置由 React 管理的 input 元素的值。 (确保在运行它时查看控制台输出以了解发生了什么),当它全部完成时,您应该在 HTML 中看到它

React thinks the value is 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 是否存在。 .

关于javascript - 以编程方式填充 ReactJS 输入的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47412188/

相关文章:

javascript - 如何在php中使用js对象

javascript - 如何使用 HTML/Javascript/CSS 将文本动态添加到图像上?

javascript - 如何从多个元素复制属性值并将每个元素复制到不同的元素?

reactjs - 如何使类对象在 MobX 中可观察?

javascript - 如何访问组件的自定义属性? ( Angular 5)

javascript - 在 Heroku 上部署 NodeJS 应用程序时遇到错误

javascript - 在 D3 中向分层条形图添加图例

javascript - 加载图像、javascript 文件后预加载 div?

javascript - UseState、UseEffect 不更新 reactjs 中的状态。我正在尝试将随机数添加到状态

javascript - React - 模块解析失败 : Unexpected token