Как предотвратить действие событий во вложенных элементах div при использовании React Hooks - PullRequest
1 голос
/ 19 февраля 2020

У меня есть вложенные элементы div. Снаружи должны быть события для перемещения и нажатия. Я хочу, чтобы вложенный элемент действовал как кнопка и предотвращал действие события извне. В примере, когда мы нажимаем на красную часть, происходят оба события. Как я могу остановить событие из зеленой части, когда мы нажимаем на красную часть? stopPropagation () не выполняет эту работу. Я использую React, и моя структура более сложная, чем в примере. Но я хотел уменьшить из соображений ясности.

Я был бы рад, если кто-то может помочь.

#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>

Я думаю, что это связано с React Hooks. Здесь вы видите пример с не работающим stopPropagation:

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;

Я был бы рад, если бы кто-то знал, как это исправить.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Вы имеете дело с различными событиями, поэтому, чтобы дочерний элемент не вызывал родительский элемент, вам нужно добавить одно и то же событие и вместо него stopPropagation():

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

Вот полностью рабочий пример:

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>
1 голос
/ 19 февраля 2020

Используйте event.stopPropagation() для предотвращения родительского триггера.

#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>
...