Приветствую, дорогие друзья!

 

Хочу предложить Вашему вниманию ещё одно аккордеонное вертикальное меню с использованием JavaScript. В отличие от предыдущего меню в данном аккордеоне скрипт вынесен в отдельный файл и оформлен в виде класса, что делает его более универсальным и расширяемым, а также и позволяет разделить логику работы от представления. Кроме того, для более приятного визуального восприятие введена функция раздвигающегося слайдера (эффект движения).

 

HTML код может выглядеть примерно так:

JavaScript Accordion
<ul id="acc">
<li>
<h3>ПУНКТ №1</h3>
<div class="acc-content">
<ul>
<li><a href="#">Ссылка 1.1</a></li>
<li><a href="#">Ссылка 1.2</a></li>
<li><a href="#">Ссылка 1.3</a></li>
<li><a href="#">Ссылка 1.4</a></li>

			</ul>

		</div>

	</li>
<li>
<h3>ПУНКТ №2</h3>
<div class="acc-content">
<ul>
<li><a href="#">Ссылка 2.1</a></li>
<li><a href="#">Ссылка 2.2</a></li>
<li><a href="#">Ссылка 2.3</a></li>
<li><a href="#">Ссылка 2.4</a></li>
<li><a href="#">Ссылка 2.5</a></li>

			</ul>

		</div>

	</li>
<li>
<h3>ПУНКТ №3</h3>
<div class="acc-content">
<ul>
<li><a href="#">Ссылка 3.1</a></li>
<li><a href="#">Ссылка 3.2</a></li>
<li><a href="#">Ссылка 3.3</a></li>
<li><a href="#">Ссылка 3.4</a></li>
<li><a href="#">Ссылка 3.5</a></li>
<li><a href="#">Ссылка 3.6</a></li>
<li><a href="#">Ссылка 3.7</a></li>
<li><a href="#">Ссылка 3.8</a></li>

			</ul>

		</div>

	</li>
<li>
<h3>ПУНКТ №4</h3>
<div class="acc-content">
<ul>
<li><a href="#">Ссылка 4.1</a></li>
<li><a href="#">Ссылка 4.2</a></li>
<li><a href="#">Ссылка 4.3</a></li>
<li><a href="#">Ссылка 4.4</a></li>

			</ul>

		</div>

	</li>

</ul>

Видно, что сам аккордеон представляет собой список ul с идентификатором асс, в элементах которого содержатся пункты меню (заголовки h3) и соответствующие этим пунктам контейнеры div с одержимым. В принципе содержимое может быть любым, но в нашем случае – это список соответствующих ссылок-подпунктов каждого из пунктов.

 

Скрипт, посредством которого организовано раздвижение аккордеона, представлен ниже и представляет собой класс my_accordion.slider и двумя вспомогательными функциями.

 



<script type="text/javascript" src="script1.js"></script>
<script type="text/javascript">// <![CDATA[
	// создаём экземпляр аккардеона
	var Acc=new my_accordion.slider("Acc");
	// инициализируем его
	Acc.init("acc",1);
// ]]></script>

my_accordion=function(){	//Слайдер
	function slider(n){
		this.n=n; 															// имя переменной слайдера (Асс)
		this.h=[]; 															// массив для элементов пунктов меню (для h3)
		this.c=[]															// массив для элементов содержимого пунктов меню (для div)
	}
	
	//добавляем к слайдеру функцию инициализации init
	slider.prototype.init=function(t,o){
		// идентификатор аккордеона
		// номер открытого пункта при инициализации
		i=x=0;																// переменные для цикла и счётчика 										
		w=[];																	// массив для дочерних элементов
		var a=_$(t);														//	находим элемент с id,указанном в t("acc") -в переменную a
		n=a.childNodes;													// находим у этого элемента все дочерние
		l=n.length;															// находим их количество 
		for(i;i<l;i++){if(n[i].nodeType==1){w[x]=n[i]; x++}} 	// заносим в массив, отфильтровывае не-элементы
		this.l=x;															// корректируем колличество
		for(i=0;i<this.l;i++){											// проходимся по каждому элементу (по li)
			var v=w[i];														// текущий элемент в переменную v
			this.h[i]=h=_$$('h3',v)[0];								// находим массив элементов в нём по тегу h3
			this.c[i]=c=_$$('div',v)[0];								// находим массив элементов в нём по тегу div
			h.onclick=new Function(this.n+'.pr(this)');			//
			if(o==i){														// если текущий в цикле совпадает с номером открытого по умолчанию, то:
				c.style.height='auto'; 									// раскрываем текущий
				c.d=1															// устанавливаем атрибут что он развёрнут
			}else{															// в противном случае:
				c.style.height=0; 										// скрываем текущий
				c.d=-1														// устанавливаем атрибут, что он свёрнут
			}
		}
	};
	
	//добавляем к слайдеру функцию 
	slider.prototype.pr=function(d){
		for(var i=0;i<this.l;i++){										// проходимся по каждому пункту меню
			var h=this.h[i];												// текущий пункт меню (h3)
			c=this.c[i];													// содержимое текущего пункта (div)
			k=c.style.height; 											// высота этого div ('auto'или'0px' )
			k=(k=='auto')?1:parseInt(k); 								// приведение в числовое значение (если 'auto', то k=1)
			clearInterval(c.t);											// очистка таймера с идентификатором c.t
			if((k!=1)&&(h==d)){											// если текущий - свйрнут и он свопадает с тем, на ктором событие, то:
				c.style.height='auto'; 
				c.m=c.offsetHeight; 
				c.style.height=k+'px'; 
				c.d=1; 														// устанавливаем атрибут развёртывания
				su(c)															// идём на таймер
			}else if((k>0)&&(h!=d)){ 									// в противном случае: за исключением того, на котором событие
				c.d=-1; 														// устанавливаем атрибут сворачивания
				su(c)															// идём на таймер
			}
		}
	};
	
	// таймер с идентификатором c.t,выполняющий функцию sl(c) каждые 10 мс.
	function su(c){c.t=setInterval(function(){sl(c)},10)};
	
	// функция частичного изменения высоты DIVа
	function sl(c){
		var h=c.offsetHeight;											// текущая высота текущего div
		d=(c.d==1)?c.m-h:h; 												// устанавливаем d в зависимости о того свёрнут div или нет
		c.style.height=h+(Math.ceil(d/10)*c.d)+'px';				// частичное изменение высоты
		if((c.d==1&&h>=c.m)||(c.d!=1&&h==1)){						// если высота изменена полностьтю, то
			clearInterval(c.t)											// очищаем таймер
		}
	};
	return{slider:slider}
}();

 

Логика работы этого скрипта ясна из приведенных в нём комментариев. Для того чтобы использовать скрипт, достаточно в html-документе создать экземпляр соответствующего класса и инициализировать его. В качестве передаваемых параметров при создании используется – имя создаваемого экземпляра класса, а при инициализации – идентификатор элемента (в рассматриваемом случае это идентификатор ‘acc’  спиcка ul ),  а также номер пункта меню, разворачиваемого при инициализации.

 

Осталось немножко оформить аккордеон в таблице стилей:

* {margin:0; padding:0; font:12px Verdana,Arial}
#acc {
	width:357px; 
	list-style:none; 
	color:#033; 
	margin:40px auto 40px;
	border:1px solid #bbb; 
}
	
#acc h3 {
	width:auto; 
	padding:6px 6px 8px; 
	margin-top:0px; 
	cursor:pointer; 
	color: #567;
	font-size: 12px;
	background: -moz-linear-gradient(top, #ffffff 1%, #eaeaea 100%);
	background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,#ffffff), color-stop(100%,#eaeaea));
	background: -webkit-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
	background: -o-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
	background: -ms-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
	background: linear-gradient(top, #ffffff 1%,#eaeaea 100%);
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eaeaea',GradientType=0 );
}

#acc h3:hover {
	box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5) inset;
	-moz-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5) inset;
	-webkit-box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5) inset;
}


#acc .acc-content {
	overflow:hidden; 
	width:auto; 
	background:#fff;
}
#acc .acc-content ul{
	list-style:none; 
	height:200px;
}
#acc .acc-content ul li a{
	color:#555;
	text-decoration: none;
	font-size: 11px;
	line-height: 20px;
	display: block;
	padding-left:20px;
}
#acc .acc-content ul li a:hover{
	color:#55d;	
	background: #f6f6f6;
}
 

 

На этом пока всё. До встречи!