javascript中可以嵌套多个事件吗?

问题描述 投票:0回答:1

作为 JavaScript 的新手,我发现这个函数很有趣,尽管我不完全确定为什么它是这样设计的。有时,它似乎达到了其预期目的,即在单击另一个 div 时保持 div 可见并处于相同位置,直到单击回原始 div。然而,我对间歇性的行为感到困惑,其中消息“第二次点击已进行=”和“第一次点击已进行=”似乎打印得好像 if 条件没有得到尊重,即使只单击一次被制成。尽管存在这种混乱,但我很欣赏该功能设计精良,并且能够在某些条件下实现其目标。

let clickFuera = true;

function inOutHover(idDivCard, isHover, idPoligono) {
  const divCard = document.getElementById(idDivCard);
  const poligono = document.getElementById(idPoligono);

  const manejadorEventoMovMouse = function(e) {
    divCard.style.left = e.pageX + 40 + "px";
    divCard.style.top = e.pageY + 5 + "px";
  };

  const manejadorEventoClick = function() {
    if (clickFuera) {
      document.removeEventListener("mousemove", manejadorEventoMovMouse);
      divCard.manejadorEventoMovMouse = null;
      divCard.style.display = "block";
      clickFuera = false;
      console.log("The first click has been made  = " + clickFuera);
    } else {
      poligono.removeEventListener("click", manejadorEventoClick);
      divCard.style.display = "none";
      clickFuera = true;
      console.log("The second click has been made = " + clickFuera);
    }
  };

  if (isHover) {
    divCard.manejadorEventoMovMouse = manejadorEventoMovMouse;
    document.addEventListener("mousemove", divCard.manejadorEventoMovMouse);
    poligono.addEventListener("click", manejadorEventoClick);
    divCard.style.display = "block";
  } else {
    if (divCard.manejadorEventoMovMouse) {
      document.removeEventListener("mousemove", divCard.manejadorEventoMovMouse);
      divCard.manejadorEventoMovMouse = null;
    }
    divCard.style.display = "none";
    poligono.removeEventListener("click", manejadorEventoClick);
  }
}
body {
  font-family: Arial, sans-serif;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f0f0f0;
  margin: 0;
}

.poligono {
  width: 100px;
  height: 100px;
  background-color: #3498db;
  cursor: pointer;
}

.divCard {
  display: none;
  position: absolute;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
<body>
  <div id="poligono" class="poligono" onmouseover="inOutHover('divCard', true, 'poligono')" onmouseout="inOutHover('divCard', false, 'poligono')"></div>
  <div id="divCard" class="divCard">This is a card</div>

  <script src="script.js"></script>
</body>

我尝试检查代码并确保事件正确执行,但我仍然对不一致的行为感到困惑。有时它似乎按预期工作,而有时则不然。查明这种变化背后的确切原因是一个挑战。尽管我努力理解和调试代码,但我还是想知道为什么它在某些情况下可以正确运行,但在其他情况下却无法正常运行。

javascript function events nested
1个回答
0
投票

每次执行时都会为事件处理程序创建新函数

inOutHover
,因此您不会删除事件侦听器,因为您传递了一个不同的(新)事件侦听器来删除。

因此,每个事件处理程序应该只有 1 个实例,您可以这样做:

let clickFuera = true, manejadorEventoClick, manejadorEventoMovMouse;

function inOutHover(idDivCard, isHover, idPoligono) {
  const divCard = document.getElementById(idDivCard);
  const poligono = document.getElementById(idPoligono);

  manejadorEventoMovMouse ??= function(e) {
    divCard.style.left = e.pageX + 40 + "px";
    divCard.style.top = e.pageY + 5 + "px";
  };

  manejadorEventoClick ??= function() {
    if (clickFuera) {
      document.removeEventListener("mousemove", manejadorEventoMovMouse);
      divCard.manejadorEventoMovMouse = null;
      divCard.style.display = "block";
      clickFuera = false;
      console.log("The first click has been made  = " + clickFuera);
    } else {
      poligono.removeEventListener("click", manejadorEventoClick);
      divCard.style.display = "none";
      clickFuera = true;
      console.log("The second click has been made = " + clickFuera);
    }
  };

  if (isHover) {
    divCard.manejadorEventoMovMouse = manejadorEventoMovMouse;
    document.addEventListener("mousemove", divCard.manejadorEventoMovMouse);
    poligono.addEventListener("click", manejadorEventoClick);
    divCard.style.display = "block";
  } else {
    if (divCard.manejadorEventoMovMouse) {
      document.removeEventListener("mousemove", divCard.manejadorEventoMovMouse);
      divCard.manejadorEventoMovMouse = null;
    }
    divCard.style.display = "none";
    poligono.removeEventListener("click", manejadorEventoClick);
  }
}
body {
  font-family: Arial, sans-serif;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f0f0f0;
  margin: 0;
}

.poligono {
  width: 100px;
  height: 100px;
  background-color: #3498db;
  cursor: pointer;
}

.divCard {
  display: none;
  position: absolute;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
<body>
  <div id="poligono" class="poligono" onmouseover="inOutHover('divCard', true, 'poligono')" onmouseout="inOutHover('divCard', false, 'poligono')"></div>
  <div id="divCard" class="divCard">This is a card</div>

  <script src="script.js"></script>
</body>

© www.soinside.com 2019 - 2024. All rights reserved.