简体   繁体   English

嵌套按钮时如何仅激活顶级按钮的onclick事件? React.js

[英]How to only activate the onclick event of the top level button when having nested buttons? React.js

I'll try to explain this further.我将尝试进一步解释这一点。 I have a material-UI List component, with ListItem component that is set to button=true thus makes the whole item a button.我有一个 material-UI List 组件,ListItem 组件设置为 button=true 从而使整个项目成为一个按钮。

inside I added that inside him I have a FontAwesomeIcon.在里面我补充说在他里面我有一个 FontAwesomeIcon。 To hide the button I put it's style to visibility: "hidden" and the Icon to visibility: "visible" so it would be available to see.为了隐藏按钮,我将它的样式设置为可见性:“隐藏”并将图标设置为可见性:“可见”,以便可以看到。 (little bad practice maybe, but did not though of another way). (也许有点不好的做法,但没有想到另一种方式)。

Now, when someone presses the ListItem anywhere without the Icon, it activates the onClick of that ListItem - as it should, and it's good!现在,当有人在没有 Icon 的任何地方按下 ListItem 时,它会激活该 ListItem 的 onClick - 正如它应该的那样,这很好! but, when pressing the area where the Icon is, both OnClick events of the "Icon button" and the ListItem is called - as it should, but I don't want it to be that way.但是,当按下图标所在的区域时,“图标按钮”和 ListItem 的 OnClick 事件都会被调用 - 应该如此,但我不希望它是那样。

Now, is there a way to make the small "nested" button to be "on top" of the parent button so only it's event would be called?现在,有没有办法让小的“嵌套”按钮位于父按钮的“顶部”,以便只调用它的事件?

If not, is there a way to know from the parent onClick that it's pressed on the area without the Icon so I would call different functions based on the click area?如果没有,有没有办法从父 onClick 知道它在没有 Icon 的区域上被按下,所以我会根据点击区域调用不同的功能?

Also, any other idea will be gladly received as I am new to react and web in general and I'd want to have the best practices solutions.此外,我很高兴收到任何其他想法,因为我是 React 和网络的新手,我希望拥有最佳实践解决方案。

Many thanks :)非常感谢 :)

This is unrelated to React.这与 React 无关。 In JavaScript you can use event.stopPropagation() method to stop the propogation of event at any level.在 JavaScript 中,您可以使用event.stopPropagation()方法在任何级别停止事件的传播。 https://www.w3schools.com/JSREF/event_stoppropagation.asp#:~:text=Definition%20and%20Usage,capturing%20down%20to%20child%20elements . https://www.w3schools.com/JSREF/event_stoppropagation.asp#:~:text=Definition%20and%20Usage,capturing%20down%20to%20child%20elements

Here is the example of how you would do it in React这是您如何在 React 中执行此操作的示例

import React from "react";
import "./styles.css";

export default function App() {
  const parentButtonHandler = () => {
    console.log("parent");
  };
  const childButtonHandler = (e) => {
    console.log("child");
    e.stopPropagation();
  };

  return (
    <div className="App">
      <button onClick={parentButtonHandler}>
        Hello CodeSandbox
        <button onClick={childButtonHandler}>
          Start editing to see some magic happen!
        </button>
      </button>
    </div>
  );
}

If I understand your question correctly, you got that issue because the event is bubbled.如果我正确理解您的问题,那么您会遇到该问题,因为该事件是冒泡的。 You can read this for more information: https://javascript.info/bubbling-and-capturing To solve it, you can use event.stopPropagation() in the event handler for click event on "Icon button", so the event wont be bubbled to the parent element which is the ListItem您可以阅读本文以获取更多信息: https : //javascript.info/bubbling-and-capturing要解决它,您可以在事件处理程序中使用 event.stopPropagation() 来处理“图标按钮”上的点击事件,因此该事件不会冒泡到作为 ListItem 的父元素

I think it's bad idea to make nested buttons.我认为制作嵌套按钮是个坏主意。 it's harder to support and it makes your layout messy.它更难支持,它使您的布局变得混乱。

In your case you can do it based on few ideas:在您的情况下,您可以根据一些想法来做到这一点:

  1. You have two separate buttons in your ListItem您的 ListItem 中有两个单独的按钮
export const Comp = () => {
  return (
   <ListItem>
    <button onClick={handleOnMainClick}>mainButton</button>
    <button onClick={handleOnSecondClick}>secondButton</button>
   </ListItem>
  )
}

But it works if your buttons on left side or right side only.但如果您的按钮仅位于左侧或右侧,则它有效。

  1. If you want to place your functional button whatether you want you can place it by position如果你想放置你想要的功能按钮,你可以按位置放置
export const Comp = () => {
  return (
   <ListItem styles={{position: 'relative'}}>
    <button onClick={handleOnMainClick}>mainButton</button>
    <button 
      styles={{position: 'absolute', top: '50%', left: '50%'}} 
      onClick={handleOnSecondClick}>
         secondButton
     </button>
   </ListItem>
  )
}

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

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