1

我有嵌套的 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;

如果有人知道如何解决这个问题,我会很高兴。

4

2 回答 2

1

用于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>

于 2020-02-19T10:28:33.760 回答
1

您正在处理不同的事件,因此为了防止子元素触发父元素,您需要添加相同的事件并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>

于 2020-02-19T12:30:21.767 回答