模拟react元素上的click事件

Alf*_*rga 9 javascript reactjs

我试图模拟.click() event一个上作出反应元素,但我想不出为什么它不工作(当我烧了它不反应event).

我想仅使用JavaScript发布Facebook评论,但我坚持第一步(做一个.click()on div[class="UFIInputContainer"]元素).

我的代码是:

document.querySelector('div[class="UFIInputContainer"]').click();
Run Code Online (Sandbox Code Playgroud)

这是我尝试这样做的URL:https://www.facebook.com/plugins/feedback.php ...

PS我对React没有经验,我不知道这在技术上是否可行.这是可能的?

编辑:我正试图这样做Chrome DevTools Console.

Elf*_*fen 18

使用 react 16.8 我会这样做:

const Example = () => {
  const inputRef = React.useRef(null)
        
  return (
    <div ref={inputRef} onClick={()=> console.log('clicked')}>
      hello
    </div>
  )
}
    
Run Code Online (Sandbox Code Playgroud)

只需调用

inputRef.current.click()
Run Code Online (Sandbox Code Playgroud)

  • 当我使用这个时,我在单击一次后无法读取 null 的属性单击 (4认同)

car*_*ott 9

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);
Run Code Online (Sandbox Code Playgroud)

这个答案是受Selenium Webdriver代码启发的。


Pra*_*avi 8

用于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'))
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • `e.click不是函数` (4认同)

joe*_*joe 8

对 @carlin.scott 的伟大答案进行了轻微调整,它模拟了mousedown,mouseupclick,就像真正的鼠标单击期间发生的情况一样(否则 React 不会检测到它)。

mousedown此答案在和事件之间添加了轻微的暂停mouseup,以实现额外的真实感,并将事件按正确的顺序排列(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));
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

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

请注意,它可能需要页面焦点才能工作,因此在控制台中执行可能无法工作,除非您打开 Chrome DevTools 的“渲染”选项卡并选中“在 DevTools 打开时模拟页面焦点”框。

  • 这似乎对我不起作用,也许反应现在检测到它有所不同? (2认同)

小智 5

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

function App() { ... }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您只需要设置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;
Run Code Online (Sandbox Code Playgroud)