我想在单击某个元素的关联按钮时切换其可见性。另外,我希望可见元素在单击外部任何地方时都关闭。可见元素内的任何链接也应该能够被点击。这是针对Shopify主题的,不确定是否有区别。
我也尝试过在元素上使用焦点事件侦听器,但是存在相同的问题。
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:无法读取null的属性'querySelector'”
但是当我使用console.log时,正确的变量会记录到控制台。
我已经为这个问题研究了几天。我对javascript还是很陌生,而且我不太确定这是怎么回事。预先感谢您的帮助。
答案 0 :(得分:0)
document.getElementById('#spotifyBtn')
使用“ document.getElementById”代替“ document.querySelector”
答案 1 :(得分:0)
我创建了一个类似的场景。 div本身和其中的项目也是可点击的。 #include <climits>
// : :
// Start with a table initialized to all zeroes.
char is_op[1 << CHAR_BIT] = {0};
// Build the table any way you please. This way using a string is handy.
const char* ops = "+-*/";
for (const char* op = ops; *op; op++) is_op[*op] = 1;
// Then tests require no searching
while(is_op[temp->left->oper] || is_op[temp->right->oper])
{
// do something
}
https://codepen.io/anon/pen/OKMNEy