javascript - 为什么在 javascript 中点击外部时不关闭下拉菜单

标签 javascript html css

我的设计中有一个下拉列表,当单击 .categories.menu 以外的任何位置时,应将其删除。 也就是说,丢失其显示类并关闭 .categories.menu。 在我编写的代码末尾,如果运行此部分 (categoriesMenu.classList.remove ("show")),它将完全阻止 show 类的下拉。 所以我想每当用户点击菜单外部时关闭菜单。

预先感谢您的合作。

function toggleClass(elem, className) {
  if (elem.className.indexOf(className) !== -1) {
    elem.className = elem.className.replace(className, '');
  } else {
    elem.className = elem.className.replace(/\s+/g, ' ') + ' ' + className;
  }

  return elem;
}

function toggleDisplay(elem) {
  const curDisplayStyle = elem.style.display;

  if (curDisplayStyle === 'none' || curDisplayStyle === '') {
    elem.style.display = 'block';
  } else {
    elem.style.display = 'none';
  }
}

function toggleMenuDisplay(e) {
  const dropdown = e.currentTarget.parentNode;
  const menu = dropdown.querySelector('.menu');
  toggleClass(menu, 'show');
}

function handleOptionSelected(e) {
  toggleClass(e.target.parentNode, 'show');
  const id = e.target.id;
  const newValue = e.target.textContent + ' ';
  const titleElem = document.querySelector('.dropdown .dropdown--title');
  titleElem.textContent = newValue;
}


const dropdownTitle = document.querySelector('.dropdown .dropdown--title');
const dropdownOptions = document.querySelectorAll('.dropdown .menu.categories a');
dropdownTitle.addEventListener('click', toggleMenuDisplay);
dropdownOptions.forEach(item => item.addEventListener('click', handleOptionSelected));

var categoriesMenu = document.querySelector('.categories.menu');
window.addEventListener('click', function(event) {
var categoriesMenuShow = categoriesMenu.classList.contains("show");
var isClickInsideElement = categoriesMenu.contains(event.target);
  if (isClickInsideElement == categoriesMenuShow ) {
      // categoriesMenu.classList.remove("show")
    }
  });
.dropdown {
  position: relative;
}

.dropdown::before {
  content: "+";
  position: absolute;
  width: 1.5rem;
  height: 1.5rem;
  top: 15px;
  right: 0;
  color: var(--cbl);
}

.dropdown .dropdown--title {
  padding: 0.75rem;
  width: 100%;
  cursor: pointer;
}

.dropdown .menu {
  cursor: pointer;
  max-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: absolute;
  z-index: 12;
  width: 100%;
  top: 45px;
  right: 0;
  background-color: var(--cwh);
  transition: max-height 0.3s;
  -webkit-transition: max-height 0.3s;
  -moz-transition: max-height 0.3s;
  -ms-transition: max-height 0.3s;
  -o-transition: max-height 0.3s;
  box-shadow: 0 3px 20px #ccc;
  -webkit-box-shadow: 0 3px 20px #ccc;
  -moz-box-shadow: 0 3px 20px #ccc;
}

.dropdown .menu.show {
  max-height: 20em !important;
}

.dropdown .menu.show a {
  color: var(--cbl);
  opacity: 1;
  transition: all 0.3s;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -ms-transition: all 0.3s;
  -o-transition: all 0.3s;
  transform: translateX(0);
  -webkit-transform: translateX(0);
  -moz-transform: translateX(0);
  -ms-transform: translateX(0);
  -o-transform: translateX(0);
}

.dropdown .menu a {
  padding: 1rem;
  opacity: 0;
  color: var(--cbl);
  transform: translateX(100%);
  -webkit-transform: translateX(100%);
  -moz-transform: translateX(100%);
  -ms-transform: translateX(100%);
  -o-transform: translateX(100%);
}

.dropdown .menu a:nth-child(1) {
  transition-delay: 0.2s;
}

.dropdown .menu a:nth-child(2) {
  transition-delay: 0.15s;
}

.dropdown .menu a:nth-child(3) {
  transition-delay: 0.1s;
}

.dropdown .menu a:nth-child(4) {
  transition-delay: 0.05s;
}

.dropdown .menu a:nth-child(5) {
  transition-delay: 0s;
}

.dropdown .menu a:not(:last-child) {
  border-bottom: 1px solid var(--cblo40);
}

.dropdown .menu a:hover {
  background: rgba(0, 0, 0, 0.2);
}
<div class="dropdown">
  <div class="dropdown--title">Choose category</div>
  <div class="categories menu">
    <a href="#" data-category="[15,16,26,27]" class="clicked">All</a>
    <a href="http://localhost/discount/product-category/other/" data-category="15">Other</a>
    <a href="http://localhost/discount/product-category/electronics/" data-category="16">Electronics</a>
    <a href="http://localhost/discount/product-category/sports/" data-category="26">Sports</a>
    <a href="http://localhost/discount/product-category/toys/" data-category="27">Toys &amp; Games</a>
  </div>
</div>

最佳答案

试试这个!

function toggleClass(elem, className) {
  if (elem.className.indexOf(className) !== -1) {
    elem.className = elem.className.replace(className, '');
  } else {
    elem.className = elem.className.replace(/\s+/g, ' ') + ' ' + className;
  }

  return elem;
}

function toggleDisplay(elem) {
  const curDisplayStyle = elem.style.display;

  if (curDisplayStyle === 'none' || curDisplayStyle === '') {
    elem.style.display = 'block';
  } else {
    elem.style.display = 'none';
  }
}

function toggleMenuDisplay(e) {
  const dropdown = e.currentTarget.parentNode;
  const menu = dropdown.querySelector('.menu');
  toggleClass(menu, 'show');
}

function handleOptionSelected(e) {
  toggleClass(e.target.parentNode, 'show');
  const id = e.target.id;
  const newValue = e.target.textContent + ' ';
  const titleElem = document.querySelector('.dropdown .dropdown--title');
  titleElem.textContent = newValue;
}


const dropdownTitle = document.querySelector('.dropdown .dropdown--title');
const dropdownOptions = document.querySelectorAll('.dropdown .menu.categories a');
dropdownTitle.addEventListener('click', toggleMenuDisplay);
dropdownOptions.forEach(item => item.addEventListener('click', handleOptionSelected));

var categoriesMenu = document.querySelector('.categories.menu');
window.addEventListener('click', function(event) {
  var categoriesMenuShow = categoriesMenu.classList.contains("show");
  var isClickInsideElement = categoriesMenu.contains(event.target);
  if (isClickInsideElement == categoriesMenuShow ) {
    // categoriesMenu.classList.remove("show")
  }
});





//newly added code to determine outside clicks
var ignoreClickOnMeElement = document.getElementById('dropdown');

document.addEventListener('click', function(event) {
  var isClickInsideElement = ignoreClickOnMeElement.contains(event.target);
  if (!isClickInsideElement) {
      categoriesMenu.classList.remove("show");
  }
});
.dropdown {
  position: relative;
}

.dropdown::before {
  content: "+";
  position: absolute;
  width: 1.5rem;
  height: 1.5rem;
  top: 15px;
  right: 0;
  color: var(--cbl);
}

.dropdown .dropdown--title {
  padding: 0.75rem;
  width: 100%;
  cursor: pointer;
}

.dropdown .menu {
  cursor: pointer;
  max-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: absolute;
  z-index: 12;
  width: 100%;
  top: 45px;
  right: 0;
  background-color: var(--cwh);
  transition: max-height 0.3s;
  -webkit-transition: max-height 0.3s;
  -moz-transition: max-height 0.3s;
  -ms-transition: max-height 0.3s;
  -o-transition: max-height 0.3s;
  box-shadow: 0 3px 20px #ccc;
  -webkit-box-shadow: 0 3px 20px #ccc;
  -moz-box-shadow: 0 3px 20px #ccc;
}

.dropdown .menu.show {
  max-height: 20em !important;
}

.dropdown .menu.show a {
  color: var(--cbl);
  opacity: 1;
  transition: all 0.3s;
  -webkit-transition: all 0.3s;
  -moz-transition: all 0.3s;
  -ms-transition: all 0.3s;
  -o-transition: all 0.3s;
  transform: translateX(0);
  -webkit-transform: translateX(0);
  -moz-transform: translateX(0);
  -ms-transform: translateX(0);
  -o-transform: translateX(0);
}

.dropdown .menu a {
  padding: 1rem;
  opacity: 0;
  color: var(--cbl);
  transform: translateX(100%);
  -webkit-transform: translateX(100%);
  -moz-transform: translateX(100%);
  -ms-transform: translateX(100%);
  -o-transform: translateX(100%);
}

.dropdown .menu a:nth-child(1) {
  transition-delay: 0.2s;
}

.dropdown .menu a:nth-child(2) {
  transition-delay: 0.15s;
}

.dropdown .menu a:nth-child(3) {
  transition-delay: 0.1s;
}

.dropdown .menu a:nth-child(4) {
  transition-delay: 0.05s;
}

.dropdown .menu a:nth-child(5) {
  transition-delay: 0s;
}

.dropdown .menu a:not(:last-child) {
  border-bottom: 1px solid var(--cblo40);
}

.dropdown .menu a:hover {
  background: rgba(0, 0, 0, 0.2);
}
<div class="dropdown" id="dropdown">
  <div class="dropdown--title">Choose category</div>
  <div class="categories menu">
    <a href="#" data-category="[15,16,26,27]" class="clicked">All</a>
    <a href="http://localhost/discount/product-category/other/" data-category="15">Other</a>
    <a href="http://localhost/discount/product-category/electronics/" data-category="16">Electronics</a>
    <a href="http://localhost/discount/product-category/sports/" data-category="26">Sports</a>
    <a href="http://localhost/discount/product-category/toys/" data-category="27">Toys &amp; Games</a>
  </div>
</div>

谢谢并致以最诚挚的问候!

关于javascript - 为什么在 javascript 中点击外部时不关闭下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72547597/

相关文章:

javascript - 如何创建和显示一个div

jquery - 如何根据按下的按钮调出不同的对话框

javascript - 使用javascript更改div中的元素颜色

javascript - 取消之前调用的 Google Maps geocode 方法

javascript - 我的 javascript 有什么问题阻止了警报和/或表单验证?

javascript - CSS 'translate(0px, 0px)' 元素样式的正则表达式匹配值

javascript - 第二个下拉菜单运行不佳。

javascript - 当使用来自其他域的图像时,为什么我的导航器会污染 Canvas ?

css - 如果 div 比视口(viewport)短,则扩展它的高度

jquery - 将鼠标悬停在父菜单项上时在背景中显示叠加层