State JS 0.1
Sets the data-state attr of elements on the page as they are clicked
by moob
HTML
<div id="main">
<div id="key">
<div data-state="clicked">clicked</div> (every element clicked is recorded as such)
<br/>
<div data-state="on">on</div> (on click toggles the 'on' state)
<br/>
<div data-state="active">active</div> (only 1 child can be active in each family)
<br/>
<div data-state="previous">previous</div> (the last previously active child)
<br/>
<div data-state="current">current </div> (the very last element that been clicked)
<br/>
<div data-state="inview">inview </div> (currently in viewport)
<br/>
<div data-state="seen">seen </div> (was previously or is currently in viewport)
</div>
<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>using 'on'
<div>All children can be opened independently</div>
</div>
<div>to control
<div>All children can be opened independently</div>
</div>
<div>an accordion
<div>All children can be opened independently</div>
</div>
</section>
<section id="eg2">
<div data-state="active">using 'active'
<div>Only one child</div>
</div>
<div>to control
<div>may be open</div>
</div>
<div>an accordion
<div>at a time</div>
</div>
</section>
<section id="eg3">
<a id="slide0trigger" data-state="active">1</a><a id="slide1trigger">2</a><a id="slide2trigger">3</a>
<ul>
<li id="slide0"...
CSS
#key {
pointer-events: none;
border: 3px solid rgba(123, 23, 123, .1);
font-family: monospace;
}
#key * {
display: inline-block;
}
body * {
background: white;
border: 1px solid #eee;
margin: 5px;
position: relative;
}
body *[data-state~="clicked"] {
border: 1px solid #666;
}
body *[data-state~="on"] {
outline: 3px dotted rgba(255, 155, 155, .5);
}
body *[data-state~="active"] {
background: rgba(0, 255, 50, 0.15);
}
body *[data-state~="previous"] {
background: rgba(255, 255, 0, 0.1);
}
body *[data-state~="current"] {
color: red;
padding-right: 20px;
}
body *[data-state~="current"]:after {
content: "*";
position: absolute;
top: 0%;
right: 0%;
color: red;
font-size: 40px;
height: 20px;
width: 20px;
line-height: 32px;
background: rgba(255, 0, 0, 0.1);
text-align: center;
}
*[data-state] {
transition: all 0.3s;
}
*[data-state~="seen"] {
background: rgba(100, 0, 100, 0.05);
}
*[data-state~="inview"] {
background: rgba(0, 0, 0, 0.05);
}
/* eg1 */
section#eg1 > div > div {
transition: all 0.5s;
margin:0;
height:0px; overflow:hidden;
}
section#eg1 > div[data-state~="on"] > div {
height:100px;
}
/* eg2 */
section#eg2 > div > div {
transition: all 0.5s;
margin:0;
height:0px; overflow:hidden;
}
section#eg2 > div[data-state~="active"] > div {
height:100px;
}
/* eg3 */
section#eg3 > ul {
box-sizing: border-box;
display: black;
position: relative;
width: 100%;
height: 200px;
margin: 0 0 20px 0;
padding: 0;
list-style: none;
overflow: hidden;
}
section#eg3 > ul > li {
box-sizing: border-box;
margin: 0;
padding: 0;
list-style: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 100%;
border: 1px solid red;
z-index: 1;
background-color: #eee;
animation: slide-out 0.8s forwards;
-webkit-animation: slide-out 0.8s forwards;
...
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)
inview (currently in viewport)
seen (was previously or is currently in viewport)
*/
;
(function() {
"use strict";
var state = {
add: function(el, str) {
if (!!el.dataset.state) {
var states = el.dataset.state.split(' ');
var index = states.indexOf(str); //IE >=9
if (index < 0) {
states.push(str);
}
el.dataset.state = states.join(' ');
} else {
el.dataset.state = str;
}
},
remove: function(el, str) {
if (!!el.dataset && !!el.dataset.state) {
var states = el.dataset.state.split(' ');
var index = states.indexOf(str); //IE >=9
if (index > -1) {
states.splice(index, 1);
}
el.dataset.state = states.join(' ');
}
},
toggle: function(el, str) {
if (state.is(el, str)) {
state.remove(el, str);
} else {
state.add(el, str);
}
},
replace: function(el, oldstr, newstr) {
if (state.is(el, oldstr)) {
state.remove(el, oldstr);
state.add(el, newstr);
}
},
is: function(el, str) {
if (!!el && !!el.dataset && !!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);
var start = performance.now();
//mark...