JSFiddle - React, Tailwind, and code Playground
sets the data-state attr of elements on the page as they are clicked
by moob
HTML
<div>
<p>paragraph</p>
<p>paragraph <strong>strong</strong> <span>span</span></p>
<a href='#'>link</a><a href='#'>link</a><a href='#'>link</a><a href='#'>link</a><a href='#'>link</a><a href='#'>link</a>
</div>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
<section id="eg1">
<div>divone<div>divonechild</div></div>
<div>divtwo<div>divtwochild</div></div>
<div>divthree<div>divthreechild</div></div>
<div>divfour<div>divfourchild</div></div>
</section>
<section id="eg2">
<div>divone<div>divonechild</div></div>
<div>divtwo<div>divtwochild</div></div>
<div>divthree<div>divthreechild</div></div>
<div>divfour<div>divfourchild</div></div>
</section>
CSS
body * {
background: white;
border: 1px solid #eee;
margin: 10px;
}
body *[data-state~="clicked"] {
border: 1px solid #666;
}
body *[data-state~="on"] {
outline: 3px solid rgba(255, 155, 155, .5);
}
body *[data-state~="active"] {
background: rgba(0, 255, 0, 0.2);
}
body *[data-state~="current"] {
color: red;
text-decoration:underline;
}
/* eg1 */
section#eg1 > div > div {display:none;}
section#eg1 > div[data-state~="on"] > div {
display:block;
}
/* eg2 */
section#eg2 > div > div {display:none;}
section#eg2 > div[data-state~="active"] > div {
display:block;
}
JavaScript
/*
clicked (every element clicked is recorded as such)
on (every element clicked is marked as on)
active (only 1 child can be active)
current (the very last element that been clicked)
*/
var state = {
add: function (el, str) {
if (!!el.dataset.state) {
state.remove(el, str);
el.dataset.state = el.dataset.state+" "+str;
} else {
el.dataset.state = str;
}
},
remove: function (el, str) {
if (!!el.dataset && !!el.dataset.state) {
var re = new RegExp(str,"g");
el.dataset.state = el.dataset.state.replace(re,"");
}
},
toggle: function (el, str) {
if (state.is(el, str)) {
state.remove(el, str);
} else {
state.add(el, str);
}
},
is: function (el, str) {
if (!!el.dataset.state) {
var states = el.dataset.state.split(' ');
var index = states.indexOf(str); //IE >=9
if (index > -1) {
return true
}
}
return false;
},
onclick: function (e) {
//console.log(e.target,e.currentTarget);
//clicked (every element clicked is recorded as such)
state.add(e.target, "clicked");
//on (every element clicked is marked as on)
state.toggle(e.target, "on");
//active (only 1 child can be active);
var children = e.target.parentNode.childNodes;
var n = children.length - 1;
while (n--) {
console.log(children[n]);
state.remove(children[n], "active");
}
state.add(e.target, "active");
//current (the very last element that been clicked)
var current = document.querySelectorAll('*[data-state~="current"]'),
i;
for (i = 0; i < current.length; ++i) {
state.remove(current[i], "current");
}
state.add(e.target, "current");
//
}
}
document.addEventListener("click", state.onclick, false);
/* perf test */
if(0>1){
var start = performance.now();
for(i=0; i<1000; i++){
var str = 'omega iota kappa';
/*
var items = str.split(' ');
var index =...