简体   繁体   English

元素上的外部点击处理事件

[英]Outside Click handle event on element

can you tell me how can i handle a click on outside of element .For example i have that 你能告诉我如何处理元素外部的点击吗?例如,我有那个

<td><input type="number" className="hour" onKeyDown={this.editInlineHour(this)} /></td>

and i want only when i click outside of that element to execute some function and that is it in react ! 而且我只希望当我在该元素之外单击以执行某些功能时,它才是反应!

I try it with that 我尝试一下

  window.addEventListener('mousedown', this.pageClick, false);

but even when i click on input field the function is executed.Thanks This is my full code ..basically it is inline edit on field on table.. when i click on that field it show input field.. and i want when i click outside that field do go away 但是,即使我单击输入字段,函数也会执行。谢谢,这是我的完整代码..基本上,这是对表上字段的内联编辑..当我单击该字段时,它显示输入字段..而我想当我单击那个领域以外的地方会消失

editInlineHour:function () {

    },
    showInlineEditHour:function (i) {
        this.setState({
            index:i,
            showInlineHour:true
        })
    },
    showInlineEditStart:function (i) {
        this.setState({
            index:i,
            showInlineStart:true
        })
    },
    showInlineEditEnd:function (i) {
        this.setState({
            index:i,
            showInlineEnd:true
        })
    },
    pageClick:function () {
      this.setState({
          showInlineStart:false,
          showInlineEnd:false,
          showInlineHour:false
      });
    },
    render: function () {

        var itemMap = this.state.items.map(function (item, i) {
            var fieldDp1;
            if(this.state.showInlineStart){
                fieldDp1 = <input id="inlineDp1"  className="flatpickr" data-date-format="m/d/Y"/>
            }else{
                fieldDp1 = <td onDoubleClick={this.showInlineEditStart.bind(this,i)} ><FormattedDate value={item.startDate}/></td>
            }
            var fieldDp2;
            if(this.state.showInlineEnd){
                fieldDp2 = <input id="inlineDp2"  className="flatpickr" data-date-format="m/d/Y" />
            }else{
                fieldDp2 = <td onDoubleClick={this.showInlineEditEnd.bind(this,i)}><FormattedDate value={item.endDate}/></td>
            }
            var fieldHours;
            if(this.state.showInlineHour){
                fieldHours = <td><input type="number" className="hour" onKeyDown={this.editInlineHour(this)} /></td>
            }else{
                fieldHours =  <td  onDoubleClick={this.showInlineEditHour.bind(this,i)} >{item.workInHours}</td>

            }
            return (
                <tr key={i}>
                    <td><input type="checkbox" checked={item.selected} onClick={this.handleChange.bind(this,i)} /></td>
                    {fieldDp1}
                    {fieldDp2}
                    {fieldHours}
                    <td><label type="button" onClick={this.handleShowModal.bind(this,i)}><img height="30px" src="moliv.jpg"/></label>
                    </td>
                </tr>
            );

        }.bind(this));
        return (
            <div>
                <button className="btn btn-primary center-block" onClick={this.addElem}>Add</button>
                {this.state.list.theList.length > 0 ?  <button className="btn btn-primary" onClick={this.putResult}>Put result</button> :null}
                <table className="table scroll2">
                    <thead>
                    <tr className="danger">
                        <th><input  type="checkbox" checked={this.state.allChecked} onClick={this.toggleAll}/></th>
                        <th>Start Date</th>
                        <th>End Date</th>
                        <th>Hours</th>
                        <th></th>
                    </tr>
                    </thead>
                    <tbody>
                    {itemMap}

                    </tbody>

                </table>
                {this.state.items.length > 0 ? <button  type="button" className="btn btn-danger" onClick={this.deleteItems}>Remove</button> : null}
                <Modal parentState={this.state} modalPropsId={this.props.theProps.id} handleHideModal={this.handleHideModal}/>
            </div>
        );

Using that approach you will need to assign a onClick handler to your input element and stop propagation so that it doesn't propagate to the windows onClick event. 使用该方法,您需要为输入元素分配一个onClick处理函数,并停止传播,以使其不会传播到Windows onClick事件。

const handleInsideClick = (e) => {
   e.stopPropagation();
} 

React handles events in a smart way, an event is triggered from the deeper node in the DOM to the top, so when you click in the input you can either stop propagation to the onClick handler in the parent node or do whatever you want in the click event and let it propagate. React以一种聪明的方式处理事件,从DOM的较深节点到顶部触发一个事件,因此,当您单击输入时,可以停止传播到父节点中的onClick处理程序,也可以在点击事件,并使其传播。

You can add ref to your element and check if click event comes outside of it. 您可以将ref添加到元素中,并检查click事件是否在其外部。

function handleClickOutside(evt) {
  if (this.refs.yourInput !== evt.target) {
    callSomeFunction();
  }
  return true;
}

componentDidMount() {
  this.clickHandler = handleClickOutside.bind(this);
  document.addEventListener('click', this.clickHandler, true);
} 

componentWillUnmount() {
  document.removeEventListener('click', this.clickHandler, true);
}

In case if you want to check outside click for some component with children, you can use contains 如果要检查外部单击是否有子组件,可以使用contains

if (!this.refs.yourComponent.contains(evt.target)) {
  callSomeFunction();
}

The event.preventDefault() method stops the default action of an element from happening if that what you're after. 如果您要执行的操作,event.preventDefault()方法将阻止发生元素的默认操作。

 <td><input type="number" id="inputField" className="hour" onKeyDown={this.editInlineHour(this)} /></td>

JavaScript: JavaScript:

$("#inputField").on("submit", function(event){
      event.preventDefault(); // Stop event 
      event.stopPropagation(); // Stop event (react)
});

http://jsbin.com/nejetoxeve/edit?html,js,console,output http://jsbin.com/nejetoxeve/edit?html,js,控制台,输出

You can wrap Component with a component with a position: fixed like so: 您可以使用position: fixed的组件包装Component,如下所示:

import React, { Component } from 'react';
import ReactDom from 'react-dom';

const styles = (onClick) => ({
  position: 'fixed',
  pointerEvents: onClick ? 'auto' : 'none',
  top: 0,
  bottom: 0,
  right: 0,
  left: 0,
  height: '100%',
});

export default class FixedLayer extends Component {

  static defaultProps = {
    zIndex: 2000,
    onClick: null,
  };

  render () {
    const divProps = { ...this.props };
    delete divProps.zIndex;
    return (
      <div { ...divProps }
        onClick={ (e) => this.props.onClick && (e.target === ReactDom.findDOMNode(this)) && this.props.onClick() }
        style={{...this.props.style, ...styles(this.props.onClick), ...{zIndex: this.props.zIndex}}}>
          {this.props.children}
      </div>
    )
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM