【问题标题】:How to manually trigger click event in ReactJS?如何在 ReactJS 中手动触发点击事件?
【发布时间】:2017-02-16 06:05:09
【问题描述】:

如何在 ReactJS 中手动触发点击事件? 当用户点击element1时,我想自动触发点击input标签。

<div className="div-margins logoContainer">
  <div id="element1" className="content" onClick={this.uploadLogoIcon}>
    <div className="logoBlank" />
  </div>
  <input accept="image/*" type="file" className="hide"/>
</div>

【问题讨论】:

  • 查看一些外部库,以编程方式制作输入元素似乎是个好主意:github.com/okonet/react-dropzone/blob/master/src/index.js#L7
  • 我不明白你为什么要在 React 中这样做。你想做什么?
  • @tobiasandersen 以编程方式聚焦input 元素是一个非常有效的用例,这很可能是提问者希望通过以编程方式触发的点击来完成的。
  • 是的,焦点和模糊都是完全有效的。但是点击?我问的原因是,如果例如聚焦是用例,那么最好展示一下。但如果点击确实是用例,那么最好只调用处理程序。
  • @JohnWhite 好吧,它可以正确绑定:) 但你可能是对的,我的意思不是刻薄。只是想看看这背后的真正意图是什么。

标签: html reactjs


【解决方案1】:

您可以使用 ref 属性通过回调获取对底层 HTMLInputElement 对象的引用,将引用存储为类属性,然后使用该引用稍后使用 @ 触发来自事件处理程序的点击987654323@方法。

在您的render 方法中:

<input ref={input => this.inputElement = input} ... />

在您的事件处理程序中:

this.inputElement.click();

完整示例:

class MyComponent extends React.Component {
  render() {
    return (
      <div onClick={this.handleClick}>
        <input ref={input => this.inputElement = input} />
      </div>
    );
  }

  handleClick = (e) => {
    this.inputElement.click();
  }
}

注意 ES6 arrow function 在回调中为 this 提供正确的词法范围。另请注意,您以这种方式获取的对象类似于您使用 document.getElementById 获取的对象,即实际的 DOM 节点。

【讨论】:

  • 这对我不起作用。不确定它是否过时,但我成功分配了元素,但是当我在其上调用click 时,click 未定义。我可以看到分配给该元素的所有其他属性和回调。有什么想法吗?
  • "Refs 不再返回文档 DOM 节点,它们返回对 React 虚拟 DOM 节点的引用" 这绝对是一个误解。 Refs 不返回“虚拟 DOM”节点。资料来源:我在 React 上工作。
  • @DanAbramov 那么推荐的方法是什么?
  • @JohnWeisz 非常感谢,它对我有用,我有必要处理表单之外的点击,因为我不得不在按钮和表单之间放置一些元素。
  • @TheJKFever 如果你在 TypeScript 中,点击可能是未定义的,因为输入是类型; HTMLInputElement | null;,因此使用:onClick={() =&gt; { if(inputElement) (inputElement).click(); } } 编译!
【解决方案2】:

在 2018 年 5 月使用 ES6 完成以下工作 React Docs 作为参考:https://reactjs.org/docs/refs-and-the-dom.html

import React, { Component } from "react";
class AddImage extends Component {
  constructor(props) {
    super(props);
    this.fileUpload = React.createRef();
    this.showFileUpload = this.showFileUpload.bind(this);
  }
  showFileUpload() {
    this.fileUpload.current.click();
  }
  render() {
    return (
      <div className="AddImage">
        <input
          type="file"
          id="my_file"
          style={{ display: "none" }}
          ref={this.fileUpload}
        />
        <input
          type="image"
          src="http://www.graphicssimplified.com/wp-content/uploads/2015/04/upload-cloud.png"
          width="30px"
          onClick={this.showFileUpload}
        />
      </div>
    );
  }
}
export default AddImage;

【讨论】:

  • 这看起来更像是 React Oriented 答案。
【解决方案3】:

这里是 Hooks 解决方案

    import React, {useRef} from 'react';

    const MyComponent = () =>{

    const myRefname= useRef(null);

    const handleClick = () => {
        myRefname.current.focus();
     }

    return (
      <div onClick={handleClick}>
        <input ref={myRefname}/>
      </div>
     );
    }

【讨论】:

  • "myRefname.current.focus 不是函数"
【解决方案4】:

您可以使用ref 回调,它将返回node。在该节点上调用 click() 以进行编程点击。

获取div 节点

clickDiv(el) {
  el.click()
}

ref 设置为div 节点

<div 
  id="element1"
  className="content"
  ref={this.clickDiv}
  onClick={this.uploadLogoIcon}
>

检查小提琴

https://jsfiddle.net/pranesh_ravi/5skk51ap/1/

希望对你有帮助!

【讨论】:

  • 当您链接到 jsfiddle 时,最好将相关代码至少放在这里(顺便说一句:sn-p 编辑器也支持 reactjs)
  • 值得注意的是,虽然字符串引用方法没有被弃用,但它被认为是被基于回调的语法所取代的遗留功能:ref={elem =&gt; this.elem = elem} -- 这在Refs to Components 中有详细说明。
  • @JohnWhite 有效的建议。更新了答案!
  • 另外,您需要先检查并确保 el 不是 null/undefined,然后再执行此操作。
【解决方案5】:

在函数式组件中,这一原则也适用,只是语法和思维方式略有不同。

const UploadsWindow = () => {
  // will hold a reference for our real input file
  let inputFile = '';

  // function to trigger our input file click
  const uploadClick = e => {
    e.preventDefault();
    inputFile.click();
    return false;
  };

  return (
    <>
      <input
        type="file"
        name="fileUpload"
        ref={input => {
          // assigns a reference so we can trigger it later
          inputFile = input;
        }}
        multiple
      />

      <a href="#" className="btn" onClick={uploadClick}>
        Add or Drag Attachments Here
      </a>
    </>
  )

}

【讨论】:

    【解决方案6】:

    受此答案 https://stackoverflow.com/a/54316368/3893510 的启发,使用 useRef 对 Aaron Hakala 的答案进行复习。

    const myRef = useRef(null);
    
      const clickElement = (ref) => {
        ref.current.dispatchEvent(
          new MouseEvent('click', {
            view: window,
            bubbles: true,
            cancelable: true,
            buttons: 1,
          }),
        );
      };
    

    还有你的 JSX:

    <button onClick={() => clickElement(myRef)}>Click<button/>
    <input ref={myRef}>
    

    【讨论】:

      【解决方案7】:

      试试这个,如果它对你不起作用,请告诉我:

      <input type="checkbox" name='agree' ref={input => this.inputElement = input}/>
      <div onClick={() => this.inputElement.click()}>Click</div>
      

      点击div 应该模拟点击input 元素

      【讨论】:

        【解决方案8】:

        使用 React Hooks 和 useRef hook

        import React, { useRef } from 'react';
        
        const MyComponent = () => {
            const myInput = useRef(null);
        
            const clickElement = () => {
                // To simulate a user focusing an input you should use the
                // built in .focus() method.
                myInput.current?.focus();
        
                // To simulate a click on a button you can use the .click()
                // method.
                // myInput.current?.click();
            }
        
            return (
                <div>
                    <button onClick={clickElement}>
                        Trigger click inside input
                    </button>
                    <input ref={myInput} />
                </div>
            );
        }
        

        【讨论】:

        • 对我来说这不起作用,因为点击和焦点不可用。但是这个答案起作用的是stackoverflow.com/a/54316368/3893510 if 而不是尝试做 myInput.current?.click();你这样做: myInput.current.dispatchEvent( new MouseEvent('click', { view: window, bubbles: true, cancelable: true, buttons: 1, }), );它应该工作
        • 是什么意思?在 myInput.current?.focus();
        • @JuliodeLeon 它是“可选链接” - 最近在 JavaScript 中引入 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 当您想要访问或调用可能未定义的对象上的函数时使用它。
        【解决方案9】:

        如果在最新版本的reactjs中不起作用,请尝试使用innerRef

        class MyComponent extends React.Component {
        
        
          render() {
            return (
              <div onClick={this.handleClick}>
                <input innerRef={input => this.inputElement = input} />
              </div>
            );
          }
        
          handleClick = (e) => {
            this.inputElement.click();
          }
        }
        

        【讨论】:

          【解决方案10】:

            imagePicker(){
                  this.refs.fileUploader.click();
                  this.setState({
                      imagePicker: true
                  })
              }
            <div onClick={this.imagePicker.bind(this)} >
            <input type='file'  style={{display: 'none'}}  ref="fileUploader" onChange={this.imageOnChange} /> 
            </div>

          这对我有用

          【讨论】:

            【解决方案11】:
              let timer;
              let isDoubleClick = false;
            
              const handleClick = () => {
                if(!isDoubleClick) {
                  isDoubleClick = true;
                  timer = setTimeout(() => {
                    isDoubleClick = false;
                    props.onClick();
                  }, 200);
                } else {
                  clearTimeout(timer);
                  props.onDoubleClick();
                }
              }
            
            return <div onClick={handleClick}></div>
            

            【讨论】:

              【解决方案12】:
              this.buttonRef.current.click();
              

              【讨论】:

                【解决方案13】:

                简单的旧 js 怎么样? 示例:

                autoClick = () => {
                 if (something === something) {
                    var link = document.getElementById('dashboard-link');
                    link.click();
                  }
                };
                  ......      
                var clickIt = this.autoClick();            
                return (
                  <div>
                     <Link id="dashboard-link" to={'/dashboard'}>Dashboard</Link>
                  </div>
                );
                

                【讨论】:

                • 期望在 React 中
                • 在 react 中不鼓励直接操作 dom,并且出于正确的原因。使用 useRef 挂钩存储引用是更好的实现方式。
                • 是的,我没有说上面的最佳实践是 hackey 方式,但它有效
                猜你喜欢
                • 2020-10-03
                • 1970-01-01
                • 1970-01-01
                • 2016-04-19
                • 1970-01-01
                • 1970-01-01
                • 2012-01-23
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多