I'm attempting to build an accordion menu using querySelectorAll()
but unsure what the best method would be to check if the clicked list item's children (.toggleContent
and .toggleIcon
) belong to it's clicked parent toggle_li[i]
.
Correct me if I am wrong, but I assume that controlling this within the onclick
function will be more flexible than impacting the toggleDataAttr
function?
I'm still new to querySelector so any guidance is appreciated.
codepen: http://codepen.io/seejaeger/pen/qdqxGy
// data attribute toggle
var toggleDataAttr = function (toggleElem, opt1, opt2, dataAttr) {
//
// ? belongs to clicked element (parent toggle_li[i])?
//
var toggleElem = document.querySelector(toggleElem);
toggleElem.setAttribute(dataAttr,
toggleElem.getAttribute(dataAttr) === opt1 ? opt2 : opt1);
};
// declare toggle onclick element
var toggle_li = document.querySelectorAll('li');
// iterate query and listen for clicks
for (var i = 0; i < toggle_li.length; i++) {
toggle_li[i].onclick = function() {
//
// ? belongs to clicked element (parent toggle_li[i])?
//
toggleDataAttr('.toggleContent', 'closed', 'open', 'data-state');
toggleDataAttr('.toggleIcon', 'plus', 'minus', 'data-icon');
};
}
Here is what I think you should do:
toggleDataAttr
function to receive one more parameter parentElem
.parentElem
for querySelector
instead of document
inside toggleDataAttr
.this
as parameter to be used as parentElem
.Snippet:
var toggleDataAttr = function(parentElem, toggleElem, opt1, opt2, dataAttr) {
var toggleElem = parentElem.querySelector(toggleElem);
toggleElem.setAttribute(dataAttr, toggleElem.getAttribute(dataAttr) === opt1 ? opt2 : opt1);
};
var toggle_li = document.querySelectorAll('li');
for (var i = 0; i < toggle_li.length; i++) {
toggle_li[i].onclick = function() {
toggleDataAttr(this, '.toggleContent', 'closed', 'open', 'data-state');
toggleDataAttr(this, '.toggleIcon', 'plus', 'minus', 'data-icon');
};
}
body {
background: #034;
opacity: 0.9;
font-family: sans-serif;
font-size: 24px;
font-weight: 300;
letter-spacing: 2px;
}
ul {
list-style: none;
padding: 0 24px;
width: 30%;
overflow: hidden;
color: #333;
}
li {
background: #eee;
padding: 0px;
border-bottom: 2px solid #aaa;
}
i {
font-style: normal;
}
.li-label {
padding: 18px;
}
.toggleContent {
padding: 18px 14px;
border-top: 2px solid #bac;
background: #334;
color: #eee;
}
.toggleContent[data-state=closed] {
display: none;
}
.toggleContent[data-state=open] {
display: block;
}
.toggleIcon[data-icon=plus]:after {
content: '+';
float: right;
}
.toggleIcon[data-icon=minus]:after {
content: '-';
float: right;
}
<ul>
<li>
<div class="li-label">
list item one <i class="toggleIcon" data-icon="plus"></i>
</div>
<div class="toggleContent" data-state="closed">toggle content one</div>
</li>
<li>
<div class="li-label">
list item two <i class="toggleIcon" data-icon="plus"></i>
</div>
<div class="toggleContent" data-state="closed">toggle content two</div>
</li>
<li>
<div class="li-label">
list item three <i class="toggleIcon" data-icon="plus"></i>
</div>
<div class="toggleContent" data-state="closed">toggle content three</div>
</li>
</ul>
Hope it helps.