1

I have nested div elements. Outside there should be events to move and to click. I want to enable a nested element to act as a button and to prevent the event from outside to act. In the example when we click on the red part, both events are happening. How can I stop the event from the green part when we click on the red part? stopPropagation() did not do the job. I am using React and my structure is more complex than in the example. But I wanted to reduce for reasons of clarity.

I would be happy if someone can help.

#bigCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background-color: green;
}

#smallCircle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: red;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <div id="bigCircle">
    <div id="smallCircle"></div>
  </div>
  
  <script>
  document.getElementById("bigCircle").addEventListener("click",myBigCircle);
  
    document.getElementById("smallCircle").addEventListener("click",mySmallCircle);
  
  function myBigCircle(){
  console.log("Hello");}
  
    function mySmallCircle(){
  console.log("Bye");}
  </script>
</body>

</html>

I think it is related to React Hooks. Here you see the example with stopPropagation not working:

import React, { useState } from 'react';

function Test() {
    let [test, setTest] = useState(false);


    return (
        <div id="wrapper"
            style={styleBigCircle}
            onMouseUp={() => {
                setTest(false);
                console.log("Hello", test)
            }
            }>

            <div id="center"
                style={styleSmallCircle}
                onClick={(e) => {
                    e.stopPropagation();
                    setTest(!test);
                    console.log("Bye", test)
                }}
            >

            </div>

        </div>

    );
}

const styleBigCircle = {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    width: "180px",
    height: "180px",
    borderRadius: "50%",
    backgroundColor: "green"
}

const styleSmallCircle = {
    width: "40px",
    height: "40px",
    borderRadius: "50%",
    backgroundColor: "red"
}

export default Test;

I would be happy if someone knows how to fix this.

user
  • 117
  • 9

2 Answers2

1

Use event.stopPropagation() to prevent parent trigger.

#bigCircle {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background-color: green;
}

#smallCircle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: red;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <div id="bigCircle">
    <div id="smallCircle"></div>
  </div>
  
  <script>
  document.getElementById("bigCircle").addEventListener("click",myBigCircle);
  
    document.getElementById("smallCircle").addEventListener("click",mySmallCircle);
  
  function myBigCircle(){
  console.log("Hello");}
  
    function mySmallCircle(event){
     event.stopPropagation()
     console.log("Bye");
   }
  </script>
</body>

</html>
Raj Kumar
  • 839
  • 8
  • 13
1

You are dealing with different events, so to prevent the child element from trigger the parent you would need to add the same event and stopPropagation() on that one instead:

<div
    id="center"
    style={styleSmallCircle}
    onMouseUp={e => {
      e.stopPropagation();
    }}
    onClick={e => {
      setTest(!test);
      console.log("Bye");
    }}
/>

Here is a fully working example:

const Test = () => {
  let [test, setTest] = React.useState(false);

  return (
    <div
      id="wrapper"
      style={styleBigCircle}
      onMouseUp={() => {
        console.log("Hello");
      }}
    >
      <div
        id="center"
        style={styleSmallCircle}
        onMouseUp={e => {
          e.stopPropagation();
        }}
        onClick={e => {
          console.log("Bye");
        }}
      />
    </div>
  );
};

const styleBigCircle = {
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  width: "180px",
  height: "180px",
  borderRadius: "50%",
  backgroundColor: "green"
};

const styleSmallCircle = {
  width: "40px",
  height: "40px",
  borderRadius: "50%",
  backgroundColor: "red"
};

const rootElement = document.getElementById("root");
ReactDOM.render(<Test />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>


<div id="root"></div>
a--m
  • 4,716
  • 1
  • 39
  • 59