在元素可点击的同时在元素内部创建一个按钮

时间:2018-02-02 20:38:21

标签: javascript html reactjs dom dom-events

我有一个简单的侧边栏,里面有一堆列表项,旁边有一个按钮,就像这样:

enter image description here

我将点击处理程序附加到<li>元素,如下面的代码所示:

<li className="note" onClick={()=> props.selectNote(props.note)} role="button">
    <button className="delete-note" onClick={() => console.log('Fired')}>Delete dis</button>
    <span className="updated-at">2hr</span>
    <div className="note-content">
        <h4 className="note-title">
            {title}
        </h4>
        <p className="note-preview">
            {notePreview.substr(0, 80)}...
        </p>
    </div>
</li>

但正如预期的那样,当我点击它旁边的按钮时,实际li被点击而不是其中的按钮。我认为这是事件如何起泡的一个问题,以及将onClick处理程序附加到非交互元素的错误做法(My ESLint说)。

我想要的是

  1. 点击列表项后,附加的onClick事件会触发。
  2. 点击该按钮后,触发按钮上的onClick事件,而不是<li>

5 个答案:

答案 0 :(得分:1)

<li data-is-parent className="note" onClick={(e)=> e.target.getAttribute('data-is-parent') && props.selectNote(props.note)} role="button">
    <button className="delete-note" onClick={() => console.log('Foreground Fired')}>Delete dis</button>
    <span className="updated-at">2hr</span>
    <div className="note-content">
        <h4 className="note-title">
            {title}
        </h4>
        <p className="note-preview">
            {notePreview.substr(0, 80)}...
        </p>
    </div>
</li>

答案 1 :(得分:1)

哈哈传入!

我通过在我不想触发主点击事件的元素中添加name属性来解决这个问题:

handleClick = (e) => {
    if(e.target.name === 'deleteButton') {
        e.preventDefault();
        e.stopPropagation();
    }else {
        this.props.selectNote(this.props.note)
    }
}


<li className="note" onClick={this.handleClick} role="button">
    <button className="delete-note" name="deleteButton" onClick={() => console.log('Fired')}>Delete dis</button>
    <span className="updated-at">2hr</span>
    <div className="note-content">
        <h4 className="note-title">
            {title}
        </h4>
        <p className="note-preview">
            {notePreview.substr(0, 80)}...
        </p>
    </div>
</li>

您需要检查触发事件的元素,如果是按钮则阻止它。

答案 2 :(得分:0)

对于Button onClick,默认点击参数event args作为&#39; event&#39;传递。使用event.stopPropagation()来停止将click事件传播回li。

<li className="note" onClick={()=> props.selectNote(props.note)} role="button">
<button className="delete-note" onClick={(event) => event.stopPropagation(); console.log('Fired')}>Delete dis</button>
<span className="updated-at">2hr</span>
<div className="note-content">
    <h4 className="note-title">
        {title}
    </h4>
    <p className="note-preview">
        {notePreview.substr(0, 80)}...
    </p>
</div>

答案 3 :(得分:0)

您需要的是防止在the capturing and bubbling phases中进一步传播当前事件(点击)。

请参阅有关事件传播的示例:https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation

答案 4 :(得分:0)

你应该将你的李包裹在一个div中 如下所示

<div>
    <li className="note" onClick={()=> props.selectNote(props.note)} role="button">
        <span className="updated-at">2hr</span>
        <div className="note-content">
            <h4 className="note-title">
                {title}
            </h4>
            <p className="note-preview">
                {notePreview.substr(0, 80)}...
            </p>
        </div>
    </li>
    <button className="delete-note" onClick={() => console.log('Fired')}>Delete dis </button>
</div>