【问题标题】:How to toggle element on button click and close on outside click?如何在按钮单击时切换元素并在外部单击时关闭?
【发布时间】:2019-07-23 04:19:39
【问题描述】:

我想在单击某个元素的关联按钮时切换其可见性。此外,我希望在可见元素之外的任何地方发生单击时关闭可见元素。可见元素内的任何链接也应该能够被点击。这是针对 Shopify 主题的,不确定这是否会有所不同。

我也尝试在元素上使用 focusout 事件侦听器,但也有同样的问题。

Javascript

const selectors = {
  mobileDownBtns: document.querySelectorAll('.mobile-nav__down-btn'),
  mainDownBtns: document.querySelectorAll('.main-nav-list__down-btn'),
  mainParent: document.querySelectorAll('.main-nav-parent-item'),
  spotifyBtn: document.querySelector('#spotifyBtn')
}

selectors.spotifyBtn.addEventListener('click', toggleElement);

selectors.mainDownBtns.forEach(function(btn) {
  btn.addEventListener('click', toggleElement);
});

function toggleElement(event) {
  const btn = event.currentTarget;
  const elem = btn.nextElementSibling;
  const container = btn.parentElement;

  if (elem.classList.contains('show')) {
    btn.setAttribute('aria-expanded', 'false');
    elem.classList.remove('show');
    container.classList.remove('isActive');
  } else {
    btn.setAttribute('aria-expanded', 'true');
    elem.classList.add('show');
    container.classList.add('isActive');
  }
}

window.addEventListener('mousedown', function(e) {
  const container = document.querySelector('.isActive');
  const btn = container.querySelector('button');
  const child = container.querySelector('.show');

  if (e.target != container && e.target.parentNode !== container) {
    container.classList.remove('isActive');
    btn.setAttribute('aria-expanded', 'false');
    child.classList.remove('show');
  }
});

HTML

<ul class="site-header__icon-list small--hide">
        <li class="site-header__icon-list--item">
          <button aria-label="Check out my spotify playlist" aria-expanded="false" id="spotifyBtn">
            {% include 'alt-icon-music' %}
          </button>

          <div class="site-header__spotify">
            {% include 'spotify' %}
          </div>
        </li>
      </ul>

      <nav role="navigation" class="site-header__main-nav--wrapper small--hide">
        <ul class="main-nav-list">
          {% for link in linklists[section.settings.menu].links %}
            {% if link.links != blank %}
              <li class="main-nav-list__item">
                <div class="main-nav-parent-item">  
                  <button class="main-nav-list__down-btn site-header__icon" aria-controls="navigation" aria-label="See sub navigation" aria-expanded="false">
                    <span>
                      {{ link.title }}
                    </span>

                    {% include 'alt-icon-chevron-down' %}
                  </button>

                  <div class="main-nav-list__dropdown">
                    <ul class="main-nav-list__child-list{% if link.links.size > 7 %} long{% endif %}">
                      {% for childlink in link.links %}
                        <li class="main-nav-list__item child-item">
                          <a href="{{ childlink.url }}">
                            {{ childlink.title }}
                          </a>
                        </li>
                      {% endfor %}
                    </ul>
                  </div>
                </div>
              </li>
            {% else %}
              <li class="main-nav-list__item">
                <a href="{{ link.url }}">
                  {{ link.title }}
                </a>
              </li>
            {% endif %}
          {% endfor %}
        </ul>
      </nav>

我的切换功能自己运行良好,但是当我添加窗口事件侦听器时,切换不再像我想要的那样工作。第一次单击按钮有效(显示元素)并且窗口侦听器有效(隐藏可见元素),但对按钮的任何其他单击都无济于事。此外,尽管窗口侦听器可以关闭可见元素,但它不允许在可见元素关闭之前点击它。

我在控制台中也遇到了错误

“未捕获的 TypeError:无法读取属性 'querySelector' of null”

但是当我使用 console.log 时,正确的变量会记录到控制台。

我已经解决这个问题几天了。我对javascript还是很陌生,我不确定这里出了什么问题。提前感谢您的帮助。

【问题讨论】:

    标签: javascript html css shopify


    【解决方案1】:
    document.getElementById('#spotifyBtn')
    

    使用“document.getElementById”而不是“document.querySelector”

    【讨论】:

      【解决方案2】:

      我创建了一个类似的场景。 div 本身和其中的项目也是可点击的。 check this code pen linkhttps://codepen.io/anon/pen/OKMNEy

      【讨论】:

      • 感谢您的评论,但我无法在我的项目中复制您的解决方案。即使有您的建议,它的行为仍然与以前相同。我很快将我的项目复制到code pen。不太确定我还能尝试什么。
      猜你喜欢
      • 2019-11-29
      • 2012-08-29
      • 2015-09-22
      • 2014-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多