TIP게시판

제목 Javascript animated collapsible panels
글쓴이 darkninja 작성시각 2023/02/04 23:13:27
댓글 : 1 추천 : 0 스크랩 : 0 조회수 : 7522   RSS

https://www.media-division.com/javascript-animated-collapsible-panels-without-frameworks/

뭔가 필요할거 같았는데 만들고 나니 그다지 유용할거 같지 않은

멍때릴대 유용함.

 

<div class="left-sidebar-wrapper">
	<div class="ex-panel left">
		<h3>progress</h3>
		<div class="ex-panelcontent">
			<div id="current_datetime" style="height:17px"></div>
			<div id="progress_bar" style="height:19px">
				<div id="progress_forward" style="height:19px; width:50%; float:left;"></div>
				<div id="progress_backward" style="height:19px; width:50%; float:right"></div>
			</div>							
		</div>				
	</div>

	<div class="ex-panel collapsed left">
		<h3>text</h3>
		<div class="ex-panelcontent">
			<textarea id="disp_text_area" name="disp_text_area" rows="5" style="width: 99.9%" spellcheck="false" placeholder="disp_text"></textarea>
		</div>
	</div>
</div>
<html>

<head>
	<title>멍때림 금지구역</title>

<style>
.left-sidebar-wrapper {
	font-size: 10pt;
	margin: 1px;
	padding: 2px 2px 2px 2px; 
	border: 1px solid #aaa;
	background-color: #eee; 
}

#current_datetime {
    padding: 0px 5px;
}

#progress_bar {
    width: 99.45%;
    padding: 0;
    margin: 3px 0px 0px 3px;
    border: 1px solid #777;
}

#progress_forward,
#progress_backward {
    color: #fff;
    overflow: hidden;
    white-space: nowrap;
    padding: 0;
    margin: 0;
    text-align: center;
}

/* panel */
.ex-panel
{
	background: #eee;
	margin: 1px;
	padding: 0px 0px 3px 0px;
	border: 1px solid #999;
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
}

/* panel heading */
.ex-panel h3
{
	/* font-size: 15px; */
	font-weight: normal;
	margin: 0px;
	padding: 2px 2px 2px 5px;
	background: #CCC url(images/arrow-up.gif) no-repeat center right;
	border-bottom: 1px solid #999;
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
	border-top: 1px solid #FFF;
	border-right: 1px solid #FFF;
	border-left: 1px solid #FFF;
}

/* panel heading on rollover */
.ex-panel h3:hover { background-color: #A9BCEF; }

/* heading of a collapsed panel */
.ex-panel.collapsed h3
{
	background: #CCC url(images/arrow-dn.gif) no-repeat center right;
	border-color: #CCC;
}

/* collapsed panel content */
.ex-panel.collapsed .ex-panelcontent { display: none; }

/* panel content - do not set borders or paddings */
.ex-panelcontent 
{ 
	margin: 0px 0px 0px 0px;
	padding: 0px 0px 0px 2px;
	overflow: hidden;
	background: #EEE;
	list-style-type: none;
}
</style>

</head>

<body>

<?php
	//도움 받은 곳
	//https://stackoverflow.com/questions/13958303/curl-download-progress-in-php
	//https://www.media-division.com/javascript-animated-collapsible-panels-without-frameworks/
?>

<div class="left-sidebar-wrapper">
	<div class="ex-panel left">
		<h3>progress</h3>
		<div class="ex-panelcontent">
			<div id="current_datetime" style="height:17px"></div>
			<div id="progress_bar" style="height:19px">
				<div id="progress_forward" style="height:19px; width:50%; float:left;"></div>
				<div id="progress_backward" style="height:19px; width:50%; float:right"></div>
			</div>							
		</div>				
	</div>

	<div class="ex-panel collapsed left">
		<h3>text</h3>
		<div class="ex-panelcontent">
			<textarea id="disp_text_area" name="disp_text_area" rows="5" style="width: 99.9%" spellcheck="false" placeholder="disp_text"></textarea>
		</div>
	</div>
</div>

<script type="text/javascript">
	function numberPad(n, width) {
		n = n + '';
		return n.length >= width ? n : new Array(width - n.length + 1).join('0') + n;
	}

	var current_datetimeElement = document.getElementById('current_datetime')

	var progress_forwardElement = document.getElementById('progress_forward')
	var progress_backwardElement = document.getElementById('progress_backward')

	function updateProgress(percentage, progress, current_datetime, forward=ture) {
		if (forward) {
			progress_forwardElement.style.width = percentage + '%';
			progress_forwardElement.style.backgroundColor = "#999";
			progress_forwardElement.innerText = numberPad(progress, 2);

			progress_backwardElement.style.width = (100 - percentage) + '%';
			progress_backwardElement.style.backgroundColor = "#ccc";
			progress_backwardElement.innerText = numberPad((60 - progress), 2);
		}
		else {
			progress_forwardElement.style.width = percentage + '%';
			progress_forwardElement.style.backgroundColor = "#ccc";
			progress_forwardElement.innerText = numberPad((60 - progress), 2);

			progress_backwardElement.style.width = (100 - percentage) + '%';
			progress_backwardElement.style.backgroundColor = "#999";
			progress_backwardElement.innerText = numberPad(progress, 2);
		}	
		
		current_datetimeElement.innerText = current_datetime;
    }

	var clockF_set = false;
	var clockF_forward = true;
	function clockF() { 
		today = new Date(); 
		var weekday = new Array(7);
		weekday[0] = "일요일";
		weekday[1] = "월요일";
		weekday[2] = "화요일";
		weekday[3] = "수요일";
		weekday[4] = "목요일";
		weekday[5] = "금요일";
		weekday[6] = "토요일";
		var day = weekday[today.getDay()];			
		
		var symd = today.toISOString().split('T')[0]+" "+day;
		var shms = today.toTimeString().split(' ')[0];
		var ssec = today.getSeconds(); 
		var smilisec = today.getMilliseconds(); 
		var progress = (ssec + (smilisec / 1000))/60 * 100;

		if (ssec == 0 && clockF_set) {
			clockF_set = false;
			clockF_forward = ! clockF_forward;
		}	
		if (ssec >= 1)
			clockF_set = true;

		if (! clockF_forward)
			progress = 100 - progress;

	    updateProgress(progress, ssec, symd + " " + shms, clockF_forward);
	} 
	setInterval('clockF()' , 100) ; 
</script>

<!--script type="text/javascript" src="<?php echo JS_DIR; ?>/ex-pannel.js"></script-->
<script type="text/javascript">
var PANEL_CLASS           = "ex-panel";
var PANEL_EXPAND_CLASS    = "expand";
var PANEL_COLLAPSED_CLASS = "collapsed";
var PANEL_HEADING_TAG     = "h3";
var PANEL_CONTENT_CLASS   = "ex-panelcontent";
var PANEL_COOKIE_NAME     = "ex-panels";
var PANEL_ANIMATION_DELAY = 20; /*ms*/
var PANEL_ANIMATION_STEPS = 10;

var PANEL_CLASS_LEFT      = "left";
var PANEL_CLASS_RIGHT     = "right";

var panelsleft = new Array();;
var panelsright = new Array();;

var	panelsStatus = new Array();;

function getPanelsHeight()
{
	var lh = 0;
	for (var i=0; i<panelsleft.length; i++) {
		lh += panelsleft[i].offsetHeight;
	}	
	
	var rh = 0;
	for (var i=0; i<panelsright.length; i++) {
		rh += panelsright[i].offsetHeight;
	}	

	var lsw = document.getElementById('left-sidebar-wrapper');
	var lsw_h = window.getComputedStyle(lsw).height;
	lsw_h = Number(lsw_h.replace('px', ''));

	var rsw = document.getElementById('right-sidebar-wrapper');
	var rsw_h = window.getComputedStyle(rsw).height;
	rsw_h = Number(rsw_h.replace('px', ''));

	var big_lr = (lh>rh) ? lh : rh;
	var big_lswrsw = (lsw_h>rsw_h) ? lsw_h : rsw_h;
	var big = (big_lr>big_lswrsw) ? big_lr : big_lswrsw;

    var ret = [];
	ret['lh'] = lh;
	ret['rh'] = rh;
	ret['lsw_h'] = lsw_h;
	ret['rsw_h'] = rsw_h;
	ret['big_lr'] = big_lr;
	ret['big_lswrsw'] = big_lswrsw;
	ret['big'] = big;

	return ret;
}

function setUpPanels()
{
	loadSettings();
	
	// get all headings
	var headingTags = document.getElementsByTagName(PANEL_HEADING_TAG);
	
	// go through all tags
	for (var i=0; i<headingTags.length; i++)
	{
		var el = headingTags[i];
		var panel = headingTags[i].parentNode;
		
		// make sure it's the heading inside a panel
		if (! panel.classList.contains(PANEL_CLASS))
			continue;		

		if (panel.classList.contains(PANEL_CLASS_LEFT)) {
			panelsleft.push(panel);
		}	
		else if (panel.classList.contains(PANEL_CLASS_RIGHT)) {
			panelsright.push(panel);
		}	
	
		// get the text value of the tag
		var name = el.firstChild.nodeValue;
	
		// look for the name in loaded settings, apply the normal/collapsed class
		if (panelsStatus[name] == "collapsed") {
			panel.classList.remove(PANEL_EXPAND_CLASS);
			panel.classList.add(PANEL_COLLAPSED_CLASS);
		}	
		else if (panelsStatus[name] == "expand") {
			panel.classList.remove(PANEL_COLLAPSED_CLASS);
			panel.classList.add(PANEL_EXPAND_CLASS);
		}	
		else {
			// if no saved setting, see the initial setting
			panelsStatus[name] = (panel.classList.contains(PANEL_EXPAND_CLASS)) ? "expand" : "collapsed";
		}
		
		// add the click behavor to headings
		el.onclick = function() 
		{
			var target    = this.parentNode;
			var name      = this.firstChild.nodeValue;
			var collapsed = target.classList.contains(PANEL_COLLAPSED_CLASS);
			saveSettings(name, collapsed?"expand":"collapsed");
			animateTogglePanel(target, collapsed);
		};
	}
}

/**
 * Start the expand/collapse animation of the panel
 * @param panel reference to the panel div
 */
function animateTogglePanel(panel, expanding)
{
	// find the .panelcontent div
	var elements = panel.getElementsByTagName("div");
	var panelContent = null;
	for (var i=0; i<elements.length; i++)
	{
		if (elements[i].classList.contains(PANEL_CONTENT_CLASS))
		{
			panelContent = elements[i];
			break;
		}
	}
	
	// make sure the content is visible before getting its height
	panelContent.style.display = "block";
	
	// get the height of the content
	var contentHeight = panelContent.offsetHeight;
	var stepHeight = contentHeight / PANEL_ANIMATION_STEPS;
	
	// if panel is collapsed and expanding, we must start with 0 height
	var direction = -1;
	if (expanding) {
		direction = 1;
		panelContent.style.height = "0px";
	}	
	
	setTimeout(function(){animateStep(panelContent,1,stepHeight,direction)}, PANEL_ANIMATION_DELAY);
}

/**
 * Change the height of the target
 * @param panelContent	reference to the panel content to change height
 * @param iteration		current iteration; animation will be stopped when iteration reaches PANEL_ANIMATION_STEPS
 * @param stepHeight	height increment to be added/substracted in one step
 * @param direction		1 for expanding, -1 for collapsing
 */
function animateStep(panelContent, iteration, stepHeight, direction)
{
	if (iteration<PANEL_ANIMATION_STEPS)
	{
		panelContent.style.height = Math.round(((direction>0) ? iteration : 10 - iteration) * stepHeight) +"px";
		iteration++;
		setTimeout(function(){animateStep(panelContent,iteration,stepHeight,direction)}, PANEL_ANIMATION_DELAY);
	}
	else
	{
		// set class for the panel
		if (direction < 0) {
			panelContent.parentNode.classList.remove(PANEL_EXPAND_CLASS);
			panelContent.parentNode.classList.add(PANEL_COLLAPSED_CLASS);
		}
		else {
			panelContent.parentNode.classList.remove(PANEL_COLLAPSED_CLASS);
			panelContent.parentNode.classList.add(PANEL_EXPAND_CLASS);
		}	

		// clear inline styles
		panelContent.style.display = "";
		panelContent.style.height = "";
	}
}

// -----------------------------------------------------------------------------------------------
// Load-Save
// -----------------------------------------------------------------------------------------------
/**
 * Reads the "panels" cookie if exists, expects data formatted as key:value|key:value... puts in panelsStatus object
 */
function loadSettings()
{
	// prepare the object that will keep the panel statuses
	//panelsStatus = {};
	
	// find the cookie name
	var start = document.cookie.indexOf(PANEL_COOKIE_NAME + "=");
	if (start == -1) return;
	
	// starting point of the value
	start += PANEL_COOKIE_NAME.length+1;
	
	// find end point of the value
	var end = document.cookie.indexOf(";", start);
	if (end == -1) end = document.cookie.length;
	
	// get the value, split into key:value pairs
	var cookieValue = unescape(document.cookie.substring(start, end));
	var panelsData = cookieValue.split("|");
	
	// split each key:value pair and put in object
	for (var i=0; i< panelsData.length; i++)
	{
		var pair = panelsData[i].split(":");
		panelsStatus[pair[0]] = pair[1];
	}
}

function expandAll()
{
	for (var key in panelsStatus)
		saveSettings(key, "expand");
		
	setUpPanels();
}

function collapseAll()
{
	for (var key in panelsStatus)
		saveSettings(key, "collapsed");
		
	setUpPanels();
}

/**
 * Takes data from the panelsStatus object, formats as key:value|key:value... and puts in cookie valid for 365 days
 * @param key	key name to save
 * @paeam value	key value
 */
function saveSettings(key, value)
{
	// put the new value in the object
	panelsStatus[key] = value;
	
	// create an array that will keep the key:value pairs
	var panelsData = [];
	for (var key in panelsStatus)
		panelsData.push(key+":"+panelsStatus[key]);
		
	// set the cookie expiration date 1 year from now
	var today = new Date();
	var expirationDate = new Date(today.getTime() + 365 * 1000 * 60 * 60 * 24);
	// write the cookie
	document.cookie = PANEL_COOKIE_NAME + "=" + escape(panelsData.join("|")) + ";expires=" + expirationDate.toGMTString();
}

// -----------------------------------------------------------------------------------------------
// Register setUpPanels to be executed on load
// the "proper" way
//if (window.addEventListener)
//	window.addEventListener("load", setUpPanels, false);
// the IE way
//else if (window.attachEvent)
//	window.attachEvent("onload", setUpPanels);
</script>

<script type="text/javascript">
	setUpPanels();
</script>

</body>

</html>

 

 다음글 nested panel - sk-rt / handy-c... (2)
 이전글 개발자에게 유용한 북마크 툴 소개

댓글

darkninja / 2023/02/18 21:30:11 / 추천 0

handy-collapse: Examples

https://www.cssscript.com/demo/Nested-Accordion-Content-Toggle-handy-collapse/

 

늘 하던것처럼 분석은 뒤로 미루고

필요한 부분만 고쳐 사용하는 버릇이 ...

시간이 많으신 분들은 쿠키를 추가해 보세요!


<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>handy-collapse: Examples</title>

    <style>
		.left-sidebar-wrapper {
			font-size: 10pt;
			margin: 1px;
			padding: 2px 2px 2px 2px; 
			border: 1px solid #aaa;
			background-color: #eee; 
		}

		//handy-panel.css
		/* top, right, bottom, left */
	
		.handy-panel
		{
			background: #eee;
			margin: 1px;
			border: 1px solid #CCC;
			-moz-border-radius: 3px;
			-webkit-border-radius: 3px;
		}

		.handy-panel.collapsed
		{
			border: 1px solid #999;
			-moz-border-radius: 3px;
			-webkit-border-radius: 3px;
		}

		.handy-panel.expand
		{
			border-left: 1px solid #CCC;
			border-right: 1px solid #CCC;
			border-bottom: 1px solid #CCC;
			-moz-border-radius: 3px;
			-webkit-border-radius: 3px;
		}

		.handy-panel button
		{
			/* font-size: 15px; */
			font-weight: normal;
			margin: 0px;
			padding: 2px 2px 2px 5px;
			background: #CCC url(images/arrow-up.gif) no-repeat center right;
			border: 0px;
			-moz-border-radius: 3px;
			-webkit-border-radius: 3px;
		}

		.handy-panel button:hover { 
			background-color: #A9BCEF; 
			cursor:pointer;
		}

		.handy-panel.collapsed button
		{
			background: #CCC url(images/arrow-dn.gif) no-repeat center right;
			border-color: #CCC;
		}

		.handy-panel.collapsed button:hover
		{
			background: #A9BCEF url(images/arrow-dn.gif) no-repeat center right;
		}

		.handy-panelcontent
		{ 
			padding: 0px 10px 0px 10px; 
			margin: 0px 0px 3px 0px;
			overflow: hidden;
			list-style-type: none;
		}

		.handy-panelcontent.is-1 { background-color:#FFFFFF; }
		.handy-panelcontent.is-2 { background-color:#F7F7F7; }
		.handy-panelcontent.is-3 { background-color:#EEEEEE; }
		.handy-panelcontent.is-4 { background-color:#E7E7E7; }
		.handy-panelcontent.is-5 { background-color:#CACACA; }

		.handy-panelcontent p
		{ 
			margin: 0px; 
			padding: 0px 0px 2px 0px; 
		}

		/* collapsed panel content */
		.handy-panel.collapsed .handy-panelcontent { display: none; }

		.button.is-fullwidth{
			display:flex;
			width:100%
		}
    </style>

</head>
 
<body>

	<?php
		//source
		//https://github.com/sk-rt/handy-collapse
		//https://www.cssscript.com/nested-accordion-content-toggle-handy-collapse/
		//https://www.cssscript.com/demo/Nested-Accordion-Content-Toggle-handy-collapse/
	?>

	<div class="left-sidebar-wrapper">

		<div class="handy-panel left collapsed">
			<!--
			.handy-panel.collapsed button
			{
				background: #CCC url(images/arrow-dn.gif) no-repeat center right;
				border-color: #CCC;
			}
			-->
			<button type="button" class="button is-fullwidth" data-nested-control="content01">Content01</button>
			<div class="handy-panelcontent is-1" data-nested-content="content01">
				<p>
					Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>                       Utenim
					ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure<br>                        dolor
					in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecatcupidatat<br>                     non
					proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
				</p>
				<div class="handy-panel left collapsed">
					<button type="button" class="button is-fullwidth" data-nested-control="child01">Child01</button>
					<div class="handy-panelcontent is-2" data-nested-content="child01">
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>                               Utenim
							ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure<br>                                dolor
							in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecatcupidatat<br>                             non
							proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
						</p>
					</div>
				</div>
			</div>
		</div>
 
		<div class="handy-panel left collapsed">
			<button type="button" class="button is-fullwidth" data-nested-control="content02">Content02</button>
			<div class="handy-panelcontent is-1" data-nested-content="content02">
				<p>
					Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>                       Utenim
					ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure<br>                        dolor
					in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecatcupidatat<br>                     non
					proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
				</p>
				<div class="handy-panel left collapsed">
					<button type="button" class="button is-fullwidth" data-nested-control="child02">Child02</button>
					<div class="handy-panelcontent is-2" data-nested-content="child02">
						<p>
							Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>                               Utenim
							ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure<br>                                dolor
							in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecatcupidatat<br>                             non
							proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
						</p>
						<div class="handy-panel left collapsed">
							<button type="button" class="button is-fullwidth" data-nested-control="grandChild02">grandChild02</button>
							<div class="handy-panelcontent is-3" data-nested-content="grandChild02">
								<p>
									Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<br>                               Utenim
									ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis auteirure<br>                                dolor
									in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecatcupidatat<br>                             non
									proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
								</p>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

	</div>
 
	<!--script type="text/javascript" src="handy-collapse.js"></script-->
	<script type="text/javascript">
		var PANEL_EXPAND_CLASS    = "expand";
		var PANEL_COLLAPSED_CLASS = "collapsed";

		var _typeof = 
			typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? 
				function(obj) { return typeof obj; } : 
				function(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

		var _extends = Object.assign || function(target) 
		{
			for (var i = 1; i < arguments.length; i++) {
				var source = arguments[i];
				for (var key in source) {
					if (Object.prototype.hasOwnProperty.call(source, key)) {
						target[key] = source[key];
					}
				}
			}
			return target;
		};

		var _createClass = function() 
		{
			function defineProperties(target, props) {
				for (var i = 0; i < props.length; i++) {
					var descriptor = props[i];
			
					descriptor.enumerable = descriptor.enumerable || false;
					descriptor.configurable = true;
			
					if ("value" in descriptor) descriptor.writable = true;
			
					Object.defineProperty(target, descriptor.key, descriptor);
				}
			}
			return function(Constructor, protoProps, staticProps) {
				if (protoProps) defineProperties(Constructor.prototype, protoProps);
				if (staticProps) defineProperties(Constructor, staticProps);
		
				return Constructor;
			};
		}();
 
		function _classCallCheck(instance, Constructor) 
		{
			if (!(instance instanceof Constructor)) {
				throw new TypeError("Cannot call a class as a function");
			}
		}

		var HandyCollapse = function() 
		{
			function HandyCollapse() 
			{
				var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
		
				_classCallCheck(this, HandyCollapse);
		
				_extends(this, {
					nameSpace: "hc",
					toggleButtonAttr: "data-" + (options.nameSpace || "hc") + "-control",
					toggleContentAttr: "data-" + (options.nameSpace || "hc") + "-content",
					activeClass: "is-active",
					isAimation: true,
					closeOthers: true,
					animatinSpeed: 400,
					cssEasing: "ease-in-out",
					onSlideStart: function onSlideStart() {
						return false;
					},
					onSlideEnd: function onSlideEnd() {
						return false;
					}
				}, options);
		
				this.toggleBodyEls = document.querySelectorAll("[" + this.toggleContentAttr + "]");
				this.toggleButtomEls = document.querySelectorAll("[" + this.toggleButtonAttr + "]");
				this.itemsStatus = {};
		
				this.init();
			}
	
			_createClass( HandyCollapse, 
				[	
					{
						key: "init",
						value: function init() {
							if (this.toggleBodyEls) {
								this.setItem();
							}
							if (this.toggleButtomEls) {
								this.setListner();
							}
						}
					}, 
					{
						key: "setItem",
						value: function setItem() {
							var _this = this;
							this.itemsStatus = {};
							Array.prototype.slice.call(this.toggleBodyEls).forEach(function(contentEl) {
								contentEl.style.overflow = "hidden";
								contentEl.style.maxHeight = "none";
								var isOpen = contentEl.classList.contains(_this.activeClass);
								var id = contentEl.getAttribute(_this.toggleContentAttr);
								_this.setItemStetus(id, isOpen);
								if (!isOpen) {
									_this.close(id, false, false);
								} else {
									_this.open(id, false, false);
								}
							});
						}
					}, 
					{
						key: "setListner",
						value: function setListner() {
							var _this2 = this;
							Array.prototype.slice.call(this.toggleButtomEls).forEach(function(buttonEl, index) {
								var id = buttonEl.getAttribute(_this2.toggleButtonAttr);
								if (id) {
									buttonEl.addEventListener("click", function(e) {
										e.preventDefault();
										_this2.toggleSlide(id, buttonEl);
									}, false);
								}
							});
						}
					}, 
					{
						key: "setItemStetus",
						value: function setItemStetus(id, isOpen) {
							this.itemsStatus[id] = {
								isOpen: isOpen
							};
						}
					}, 
					{
						key: "toggleSlide",
						value: function toggleSlide(id) {
							var isRunCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
							if (this.itemsStatus[id].isOpen === false) {
								this.open(id, isRunCallback, this.isAimation);
							} else {
								this.close(id, isRunCallback, this.isAimation);
							}
						}
					}, 
					{
						key: "open",
						value: function open(id) {
							var _this3 = this;
							var isRunCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
							var isAimation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
							if (!id) return;
							if (this.closeOthers) {
								Array.prototype.slice.call(this.toggleBodyEls).forEach(function(contentEl, index) {
									var closeId = contentEl.getAttribute(_this3.toggleContentAttr);
									if (closeId !== id) _this3.close(closeId, false, isAimation);
								});
							}
							if (isRunCallback !== false) this.onSlideStart(true, id);
							var toggleBody = document.querySelector("[" + this.toggleContentAttr + "='" + id + "']");
							var toggleButton = document.querySelector("[" + this.toggleButtonAttr + "='" + id + "']");
							var clientHeight = this.getTargetHeight(toggleBody);
							toggleBody.classList.add(this.activeClass);
							toggleButton.classList.add(this.activeClass);
							toggleButton.parentNode.classList.remove(PANEL_COLLAPSED_CLASS); //REMOVE COLLAPSED
							toggleButton.parentNode.classList.add(PANEL_EXPAND_CLASS);       //ADD EXPAND 
							if (isAimation) {
								toggleBody.style.transition = this.animatinSpeed + "ms " + this.cssEasing;
								toggleBody.style.maxHeight = (clientHeight || "1000") + "px";
								setTimeout(function() {
									if (isRunCallback !== false) _this3.onSlideEnd(true, id);
									toggleBody.style.maxHeight = "none";
									toggleBody.style.transition = "";
								}, this.animatinSpeed);
							} else {
								toggleBody.style.maxHeight = "none";
							}
							if (this.itemsStatus.hasOwnProperty(id)) {
								this.itemsStatus[id].isOpen = true;
							}
						}
					}, 
					{
						key: "close",
						value: function close(id) {
							var _this4 = this;
							var isRunCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
							var isAimation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
							if (!id) return;
							if (isRunCallback !== false) this.onSlideStart(false, id);
							var toggleBody = document.querySelector("[" + this.toggleContentAttr + "='" + id + "']");
							var toggleButton = document.querySelector("[" + this.toggleButtonAttr + "='" + id + "']");
							toggleBody.classList.remove(this.activeClass);
							toggleButton.classList.remove(this.activeClass);
							toggleButton.parentNode.classList.remove(PANEL_EXPAND_CLASS); //REMOVE EXPAND
							toggleButton.parentNode.classList.add(PANEL_COLLAPSED_CLASS); //ADD COLLAPSED
							toggleBody.style.maxHeight = toggleBody.clientHeight + "px";
							setTimeout(function() {
								toggleBody.style.maxHeight = "0px";
							}, 5);
							if (isAimation) {
								toggleBody.style.transition = this.animatinSpeed + "ms " + this.cssEasing;
								setTimeout(function() {
									if (isRunCallback !== false) _this4.onSlideEnd(false, id);
									toggleBody.style.transition = "";
								}, this.animatinSpeed);
							} else {
								this.onSlideEnd(false, id);
							}
							if (this.itemsStatus.hasOwnProperty(id)) {
								this.itemsStatus[id].isOpen = false;
							}
						}
					}, 
					{
						key: "getTargetHeight",
						value: function getTargetHeight(targetEl) {
							if (!targetEl) return;
							var cloneEl = targetEl.cloneNode(true);
							var parentEl = targetEl.parentNode;
							cloneEl.style.maxHeight = "none";
							cloneEl.style.opacity = "0";
							parentEl.appendChild(cloneEl);
							targetEl.style.display = "block"; //CLICK BUTTON ... DISPLAY
							var clientHeight = cloneEl.clientHeight;
							parentEl.removeChild(cloneEl);
							return clientHeight;
						}
					}
				]
			);
    
			return HandyCollapse;
		}();

		if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === 'object') {
			module.exports = HandyCollapse;
		}
	</script>

	<script type="text/javascript">
		//Nested
		let nested = new HandyCollapse({
			nameSpace: "nested",
			closeOthers: false
		});
	</script>

</body>

</html>