Link 嵌入图标未触发 JavaScript

Link with Embedded Icon Not Firing with JavaScript

我有一个菜单列表,其中图标放在菜单标签旁边。一个菜单项有一个用 JavaScript 展开的子菜单。如果我单击菜单项中的任意位置,子菜单就会展开。但是,如果我单击嵌入在菜单项或标签中的图标,则子菜单不会展开。单击图标或菜单项的其他部分时,不使用 JavaScript 展开子菜单的所有其他菜单项会正确触发。

// Show an element
var show = function (elem) {

  // Get the natural height of the element
  var getHeight = function () {
    elem.style.display = 'block'; // Make it visible
    var height = elem.scrollHeight + 'px'; // Get it's height
    elem.style.display = ''; //  Hide it again
    return height;
  };

  var height = getHeight(); // Get the natural height
  elem.classList.add('is-visible'); // Make the element visible
  elem.style.height = height; // Update the max-height

  // Once the transition is complete, remove the inline max-height so the content can scale responsively
  window.setTimeout(function () {
    elem.style.height = '';
  }, 350);

};

// Hide an element
var hide = function (elem) {

  // Give the element a height to change from
  elem.style.height = elem.scrollHeight + 'px';

  // Set the height back to 0
  window.setTimeout(function () {
    elem.style.height = '0';
  }, 1);

  // When the transition is complete, hide it
  window.setTimeout(function () {
    elem.classList.remove('is-visible');
  }, 300);

};

// Toggle element visibility
var toggle = function (elem, timing) {

  // If the element is visible, hide it
  if (elem.classList.contains('is-visible')) {
    hide(elem);
    return;
  }

  // Otherwise, show it
  show(elem);

};

// Listen for click events
document.addEventListener('click', function (event) {

  // Make sure clicked element is our toggle
  if (!event.target.classList.contains('toggle')) return;

  // Prevent default link behavior
  event.preventDefault();

  // Get the content
  var content = document.querySelector(event.target.hash);
  if (!content) return;

  // Toggle the content
  toggle(content);

}, false);
ul {
  font-family: sans-serif;
  list-style-type: none;
  width: 230px;
}

li {
  color: #404040;
  font-size: 0.75rem;
  letter-spacing: -0.4px;
  line-height: 1.025rem;
  text-transform: uppercase;
}

li ul {
  padding: 0;
  margin: 0;
}

li img {
  margin-right: 1rem;
}

li a {
  color: inherit;
  display: block;
  padding: 0.875rem 1.5rem 1.025rem;
  text-decoration: none;
}

li a:hover {
  background-color: #f2f6f9;
}

li span {
  position: relative;
  top: -.25rem;
}

li li {
  background-color: transparent;
}

.toggle {
  border-left: 5px solid #015295;
  padding-left: calc(1.5rem - 5px);
}

.toggle-content {
  display: none;
  height: 0;
  overflow: hidden;
  transition: height .3s ease-in-out;
}

.toggle-content.is-visible {
  display: block;
  height: auto;
}
<ul>
  <li><a href="http://isitchristmas.com">
    <img src="https://image.flaticon.com/icons/svg/263/263115.svg" width="20" height="20" alt=""><span>Home</span></a></li>
  <li style="background-color: #f2f6f9;"><a class="toggle" href="#example"><img src="https://image.flaticon.com/icons/svg/263/263078.svg" width="20" height="20" alt=""><span>Billing</span>
    </a>
    <div class="toggle-content" id="example">
      <ul>
        <li><a href="http://isitchristmas.com">Premium Statement</a></li>
        <li><a href="http://isitchristmas.com">Payment Summary</a></li>
      </ul>
    </div>
  </li>
  <li><a href="http://isitchristmas.com">
    <img src="https://image.flaticon.com/icons/svg/263/263058.svg" width="20" height="20" alt=""><span>Employees</span></a></li>
  <li><a href="http://isitchristmas.com"><img src="https://image.flaticon.com/icons/svg/263/263146.svg" width="20" height="20" alt=""><span>Claims</span></a></li>
  <li><a href="http://isitchristmas.com"><img src="https://image.flaticon.com/icons/svg/263/263122.svg" width="20" height="20" alt=""><span>My Plans</span></a></li>
</ul>

我不知道为什么单击 link 中嵌入的图标会阻止 JavaScript 触发。感谢任何帮助。

这是因为 "event.target" return 是确切的 DOM 元素,所以在您的代码中,当您单击 "img" 或 "span","event.target" 将 return

<img src="https://image.flaticon.com/icons/svg/263/263078.svg" width="20" height="20" alt="">

<span>Billing</span>

为了防止这种情况,您应该使用:.closest('a') 它将转到最接近描述的元素。

  // Make sure clicked element is our toggle
  if (!event.target.closest('a').classList.contains('toggle')) {
    return;
  }

  // Prevent default link behavior
  event.preventDefault();

  // Get the content
  console.log(event.target.closest('a').hash);
  var content = document.querySelector(event.target.closest('a').hash);
  if (!content) return;

这是我对您的代码所做的小修改,现在应该可以使用了。

要了解有关 .closest() 的更多信息,请阅读此处:https://developer.mozilla.org/en-US/docs/Web/API/Element/closest