模拟react元素上的click事件

时间:2016-10-17 16:07:09

标签: javascript reactjs

我正在尝试在React元素上模拟.click() event,但我无法弄清楚它为什么不起作用(当我解雇时,它没有反应event)。

我想仅使用JavaScript发布Facebook评论,但我坚持第一步(在.click()元素上执行div[class="UFIInputContainer"])。

我的代码是:

document.querySelector('div[class="UFIInputContainer"]').click();

这是我尝试执行此操作的网址:https://www.facebook.com/plugins/feedback.php...

P.S。我对React没有经验,我不知道这在技术上是否可行。有可能吗?

编辑:我正在尝试从Chrome DevTools Console执行此操作。

8 个答案:

答案 0 :(得分:4)

使用refs获取回调函数中的元素,并使用click()函数触发点击。



class Example extends React.Component{
  simulateClick(e) {
    e.click()
  }
  render(){
    return <div className="UFIInputContainer"
    ref={this.simulateClick} onClick={()=> console.log('clicked')}>
      hello
      </div>
  }
}

ReactDOM.render(<Example/>, document.getElementById('app'))
&#13;
<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>
<div id="app"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

React跟踪mousedownmouseup事件以检测鼠标单击,而不是像其他大多数事件一样跟踪click事件。因此,必须直接调度down和up事件,而不是直接调用click方法或调度click事件。出于良好的考虑,我还发送了click事件,但我认为这对于React来说是不必要的:

const mouseClickEvents = ['mousedown', 'click', 'mouseup'];
function simulateMouseClick(element){
  mouseClickEvents.forEach(mouseEventType =>
    element.dispatchEvent(
      new MouseEvent(mouseEventType, {
          view: window,
          bubbles: true,
          cancelable: true,
          buttons: 1
      })
    )
  );
}

var element = document.querySelector('div[class="UFIInputContainer"]');
simulateMouseClick(element);

此答案的灵感来自Selenium Webdriver code

答案 2 :(得分:2)

如果您没有在组件中定义类,而是只声明:

function App() { ... }

在这种情况下,您只需要设置 useRef 钩子并使用它指向/引用任何html元素,然后使用该引用触发常规的dom事件。

import React, { useRef } from 'react';

function App() {
  const inputNameRef = useRef()
  const buttonNameRef = useRef()
  
  function handleKeyDown(event) {
    // This function runs when typing within the input text,
    // but will advance as desired only when Enter is pressed
    if (event.key === 'Enter') {
      // Here's exactly how you reference the button and trigger click() event,
      // using ref "buttonNameRef", even manipulate innerHTML attribute
      // (see the use of "current" property)
      buttonNameRef.current.click()
      buttonNameRef.current.innerHTML = ">>> I was forced to click!!"
    }
  }
  
  function handleButtonClick() {
    console.log('button click event triggered')
  }
  
  return (
    <div>
      <input ref={inputNameRef} type="text" onKeyDown={handleKeyDown}  autoFocus />
      <button ref={buttonNameRef} onClick={handleButtonClick}>
      Click me</button>
    </div>
  )
}

export default App;

答案 3 :(得分:0)

受以前的解决方案的启发并使用一些javascript代码注入,它也可能首先注入 React 到页面中,然后在该页面元素上触发click事件

&#13;
&#13;
let injc=(src,cbk) => { let script = document.createElement('script');script.src = src;document.getElementsByTagName('head')[0].appendChild(script);script.onload=()=>cbk() }
injc("https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js",() => injc("https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js",() => {

class ReactInjected extends React.Component{
  simulateClick(e) {
    e.click()
  }
  render(){
    return <div className="UFIInputContainer"
    ref={this.simulateClick} onClick={()=> console.log('click injection')}>
      hello
      </div>
  }
}
ReactDOM.render(<ReactInjected/>, document.getElementById('app'))

} ))
&#13;
<div id="app"></div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

使用react 16.8,我会这样:

const Example = () => {
          const inputRef = React.useRef(null)

          return (
            <div ref={inputRef} onClick={()=> console.log('clicked')}>
              hello
            </div>
          )
    }

只需致电

inputRef.current.click()

答案 5 :(得分:0)

使用React useRef Hooks,您可以在任何这样的按钮上触发点击事件:

export default const () => {

    // Defining the ref constent
    const inputRef = React.useRef(null);

    // example use
    const keyboardEvent = () => {
      inputRef.current.handleClick(); //Trigger click
    }

    // registering the ref
    return (
       <div ref={inputRef} onClick={()=> console.log('clicked')}>
          hello
       </div>
    )
}

答案 6 :(得分:0)

对@ carlin.scott的好答案进行了少许调整,该答案模拟了mousedownmouseupclick,就像在真正的鼠标单击期间一样(否则React不会检测到它) )。

此答案在mousedownmouseup事件之间添加了些许停顿,以增加真实感,并将事件按正确的顺序放置(click最后触发)。暂停使其变为异步状态,这可能是不可取的(因此,为什么我不只是建议对@ carlin.scott的答案进行编辑)。

async function simulateMouseClick(el) {
  let opts = {view: window, bubbles: true, cancelable: true, buttons: 1};
  el.dispatchEvent(new MouseEvent("mousedown", opts));
  await new Promise(r => setTimeout(r, 50));
  el.dispatchEvent(new MouseEvent("mouseup", opts));
  el.dispatchEvent(new MouseEvent("click", opts));
}

用法示例:

let btn = document.querySelector("div[aria-label=start]");
await simulateMouseClick(btn);
console.log("The button has been clicked.");

答案 7 :(得分:0)

有种肮脏的骇客之作,但这对我来说很好用,而这篇文章之前的建议却失败了。您必须在源代码中找到在其上定义了onClick的元素(为此,我必须在移动模式下运行网站)。该元素将具有一个__reactEventHandlerXXXXXXX属性,允许您访问react事件。

let elem = document.querySelector('YOUR SELECTOR');
//Grab mouseEvent by firing "click" which wouldn't work, but will give the event
let event;
likeBtn.onclick = e => {
  event = Object.assign({}, e);
  event.isTrusted = true; //This is key - React will terminate the event if !isTrusted
};
elem.click();
setTimeout(() => {
  for (key in elem) {
    if (key.startsWith("__reactEventHandlers")) {
      elem[key].onClick(event);
    }
  }
}, 1000);