javascript - 打开/关闭弹出窗口的多种方式出现意外显示

标签 javascript html css dom-events

我试图用变量打开/关闭弹出窗口, 它显示输入字段何时获得焦点,反之亦然。 但会有一个图标允许用户点击它, 该图标可以切换弹出窗口的显示。

这是代码片段:

// Get references to the input field and the popup
const inputField = document.getElementById("inputField");
const popup = document.getElementById("popup");
const toggleIcon = document.getElementById("toggleIcon");

// Variable to track the visibility state of the popup
let isPopupVisible = false;

// Function to show the popup
function showPopup() {
  console.log("showing");
  popup.style.display = "block";
  isPopupVisible = true;
}

// Function to hide the popup
function hidePopup() {
  console.log("hiding");
  popup.style.display = "none";
  isPopupVisible = false;
}

// Function to toggle the visibility of the popup
function togglePopup() {
  console.log("toggle", isPopupVisible ? "true" : "false");
  if (isPopupVisible) {
    hidePopup();
  } else {
    showPopup();
  }
}

// Event handler for when the input field is focused
inputField.addEventListener("focus", function () {
  if (!isPopupVisible) {
    showPopup();
  }
});

// Event handler for when the input field is blurred
inputField.addEventListener("blur", function () {
  hidePopup();
});

// Event handler for when the toggle icon is clicked
toggleIcon.addEventListener("click", function () {
  togglePopup();
});
<html>

<head>
  <title>Popup Example</title>
  <style>
    .popup {
      display: none;
      position: absolute;
      background-color: #f9f9f9;
      border: 1px solid #ccc;
      padding: 10px;
    }
  </style>
</head>

<body>
  <input type="text" id="inputField" placeholder="Enter text">
  <span id="toggleIcon">&#x1F441;</span>
  <div id="popup" class="popup">
    This is the popup content.
  </div>

  <script>
    // JavaScript code goes here
  </script>
</body>

</html>

但是通过特定的程序,发现了意外的显示弹出窗口:

1. click the icon to show the popup
2. click the input field to focus on it, the popup still showing
3. click the icon
Expected: the popup should be hidden
Result: the popup hides and shows back

通过控制台日志,我发现输入的 onblur 事件是在调用图标切换函数之前触发的。

"toggle: isPopupVisible=false"
"showing"
"hiding"
"toggle: isPopupVisible=false"
"showing"

对于这种情况,我该如何更新我的代码才能达到效果?

我不能只用 display: none; 隐藏弹出窗口,因为对于我的真实情况, 除了显示弹出窗口之外,我需要 isPopupVisible 来做其他事情。

最佳答案

问题的原因是,当您单击带有从输入的焦点可见的弹出窗口的图标时,会触发两个事件。首先,输入的模糊会隐藏弹出窗口,然后单击图标会切换弹出窗口并再次显示它。

要解决此问题,您可以监听input外部的点击,而不是blur事件,但点击时除外输入图标

另请注意,用于存储弹出窗口可见状态的变量是多余的,会导致不必要的复杂性。 DOM 已经保存了状态,因此可以将其用作唯一的事实来源。事实上,您可以通过使用带有 display: block 的类并根据需要更新该类来简化显示/隐藏/切换。

话虽如此,这是一个进行了上述更改的工作版本:

const inputField = document.getElementById("inputField");
const popup = document.getElementById("popup");
const toggleIcon = document.getElementById("toggleIcon");

const showPopup = () => popup.classList.add('show');
const hidePopup = () => popup.classList.remove('show');
const togglePopup = () => popup.classList.toggle('show');

// Event handler for when the input field is focused
inputField.addEventListener("focus", function() {
  showPopup();
});

// Event handler for when a click occurs outside of an element which affects the popup
document.addEventListener("click", function(e) {
  if (e.target != inputField && e.target != toggleIcon) {
    hidePopup();
  }
});

// Event handler for when the toggle icon is clicked
toggleIcon.addEventListener("click", function(e) {
  togglePopup();
});
.popup {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  border: 1px solid #ccc;
  padding: 10px;
}

.popup.show {
  display: block;
}
<input type="text" id="inputField" placeholder="Enter text">
<span id="toggleIcon">&#x1F441;</span>
<div id="popup" class="popup">
  This is the popup content.
</div>

关于javascript - 打开/关闭弹出窗口的多种方式出现意外显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77236469/

相关文章:

html - 内容在悬停时被遮盖

java - Docx4j 在将 html 文档转换为 docx 时出现某些样式问题

css - 使用 :after 将元素定位在其父项下

javascript - 带有按钮和渐变的水平滚动区域

javascript - Ext Js Combo 按不同项目过滤

javascript - 如何在jqGrid单元格编辑中只允许数字?

javascript - 确保纯 Ajax/Javascript 客户端的安全

html - 如何根据屏幕自动调整高度和宽度?

html - Internet Explorer 图像叠加链接

html - 响应式设计站点标题和 slider