简体   繁体   English

单击包含span的div,不会触发onclick事件 - React

[英]Clicking on a div that contains span, doesn't trigger onclick event - React

I have a div, and inside I am rendering spans based on some conditions. 我有一个div,在里面我根据某些条件渲染范围。 If the component has some children, I'd like this div to expand. 如果该组件有一些孩子,我希望这个div扩展。 It works fine if I click on this div on an area outside of the inner span. 如果我在内跨区域外的区域上单击此div,它可以正常工作。

An example, is the following Image . 一个例子,是下面的图像 When clicking on the row, it expands the area to show items like this . 单击该行时,它会展开区域以显示此类项目。 However, when I click on the header text, it's not working, the on click event doesn't fire. 但是,当我单击标题文本时,它不起作用,on click事件不会触发。

Here's my code: 这是我的代码:

 <div className={headerStyles.header} onClick={(e) => this.selectHeader(e, this.props.items.length)}>
    {this.props.items.length > 0 && 
          <span className={headerStyles.expand} style={{ color: this.props.headerNameColor }}></span>
                    }
          <span style={{ color: this.props.headerNameColor }}  >{this.props.headerName}</span>
                    {this.props.headerUrl &&
                        <a
                            style={{ color: this.props.headerNameColor }}
                            href={this.props.headerUrl}
                            data-interception="off"
                            target="_blank"
                            title="Open link in a new tab">
                            <i className={['ms-Icon', 'ms-Icon--OpenInNewWindow', headerStyles.openNewTab].join(' ')}></i>
                        </a>
                    }
                </div>

Here's the function that gets called when clicking the header: 这是单击标题时调用的函数:

 selectHeader(e, numOfItems) {
        if (e.target.children.length > 0 && numOfItems > 0) {
            e.target.children[0].classList.toggle(headerStyles.expand)
            e.target.children[0].classList.toggle(headerStyles.collapse)
            e.target.parentElement.querySelector(`.${headerStyles.items}`).classList.toggle(headerStyles.hidden)
        }
        else if(this.props.headerUrl){

        }
    }

Any guidance is appreciated. 任何指导表示赞赏。

Thanks 谢谢

As I suspected, you're trying to do something with the event.target value inside of selectHeader . 我怀疑你正在尝试使用selectHeaderevent.target值。 That won't work very well because event.target will change depending on which element you clicked on inside of your div. 这将无法正常工作,因为event.target将根据您在div中单击的元素而改变。 It won't always be the outer "parent" element. 它并不总是外部的“父”元素。

You're also trying to read data imperatively from the DOM, which is not a very "React" way of doing things. 您还试图从DOM中强制读取数据,这不是一种非常“反应”的做事方式。 In fact, within your function you're doing a classList.toggle(headerStyles.hidden) which is in direct conflict with React managing the state and rendering of your app. 实际上,在你的函数中你正在做一个classList.toggle(headerStyles.hidden) ,这与React管理应用程序的状态和呈现有直接冲突。 All the data you need should live within the state of your React application - you shouldn't need to query the DOM at all. 您需要的所有数据都应该在React应用程序的状态内 - 您根本不需要查询DOM。

Ditch event.target and classList.toggle and find a way to do it using React state. Ditch event.targetclassList.toggle并找到一种使用React状态的方法。 For example, when you click the div you could simply toggle the "expanded" state of your component, and use that state to determine which CSS class to render: 例如,当您单击div时,您只需切换组件的“展开”状态,并使用该状态来确定要呈现的CSS类:

<div onClick={() => {this.setState({isExpanded: !this.state.isExpanded})}} >
  <span className={this.state.isExpanded ? headerStyles.expand : headerStyles.collapse} ></span>
</div>

Avoid using arrow functions inside the JSX here. 避免在JSX中使用箭头函数。 e object is always passed since this is an event handler, and your props are accessible from your handler: e对象总是被传递,因为这是一个事件处理程序,你的props可以从你的处理程序访问:

selectHeader = (e) => {
     const numOfItems = this.props.items.length;
     // rest of the code...

 }

inside render method: 内部渲染方法:

<div onClick={this.selectHeader}>

Try to add pointerEvents: 'none' style to the span tags so it won't get any mouse event. 尝试将pointerEvents: 'none'样式添加到span标记中,这样就不会获得任何鼠标事件。 This will make the event.target to always be the div 这将使event.target始终为div

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

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