منظور از منوی آکاردئون چیست؟
منوی آکاردئونی در واقع برگرفته از نام واژه آکاردئون (accordion) و به معنی یک نوع ساز بادی معروف است، قسمتی از این ساز دارای یک مجاری عبور هوای فنر مانند و پله پله ای است که نوازنده برای نواختن آهنگ باید آن را با دست خود به طور متناوب حرکت دهد، این ساز قدمت زیادی داشته و در خیلی از فیلم ها و سریال ها معمولا به عنوان ساز بینوایان استفاده می شود! به خاطر شباهت این نوع منو با این ساز به آن آکاردئونی می گوییم.
کد جاوا اسکریپت برای ساخت باکس آکاردئونی
همان طور که گفتیم برای ساختن منوها و باکس های آکاردئونی یا به اصلاح جمع شونده، می توان از جاوا اسکریپت استفاده کرد، از این رو در زیر یکی از سبک ترین و در عین حال سازگارترین توابعی که بدین منظور نوشته شده را با هم بررسی می کنیم.
<script type="text/javascript">
//<![CDATA[
var contentHeight = 34;
var TimeToSlide = 300.0;
var openprobox = ;
function runprobox(index){
var divID = "probox" + index + "content";
if(openprobox == divID){
divID = ;
}
setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + "," + openprobox + "," + divID + ")", 33);
openprobox = divID;
}
function animate(lastTick, timeLeft, closingId, openingId){
var curTick = new Date().getTime();
var elapsedTicks = curTick - lastTick;
var opening = (openingId == ) ? null : document.getElementById(openingId);
var closing = (closingId == ) ? null : document.getElementById(closingId);
if(timeLeft <= elapsedTicks){
if(opening != null){
opening.style.height = contentHeight + px;
}
if(closing != null){
closing.style.display = none;
closing.style.height = 0px;
}
return;
}
timeLeft -= elapsedTicks;
var newClosedHeight = Math.round((timeLeft/TimeToSlide) * contentHeight);
if(opening != null){
if(opening.style.display != block){
opening.style.display = block;
}
opening.style.height = (contentHeight - newClosedHeight) + px;
}
if(closing != null){
closing.style.height = newClosedHeight + px;
}
setTimeout("animate(" + curTick + "," + timeLeft +"," + closingId + "," + openingId + ")", 33);
}
//]]>
</script>
اگرچه درک صحیح عملکرد این کد نیازمند تجربه نسبی و کار با جاوا اسکریپت است، اما بد نیست برای آگاهی بیشتر هم که شده، نگاهی اجمالی به کد بالا داشته باشیم.
توضیح:
- در قسمت متغیر contentHeight در ابتدای کد، ارتفاع بلاک محتوا را به پیکسل مشخص می کنیم، این همان بلاکی است که محتویات هر منو را در خود نمایش می دهد.
- در متغیر TimeToSlide میزان زمان (به میلی ثانیه) را برای شروع و پایان انیمیشن تعیین می کنیم، هر چه این زمان بیشتر باشد، سرعت انمیشن کندتر و میزان فرم های بیشتری ایجاد می شود (توصیه می شود مقادیر پیش فرض را تغییر ندهید).
- تابع runprobox در کد بالا، یک عدد به عنوان آرگومان می پذیرد، این عدد در واقع در هنگام فراخوانی تابع (که در ادامه خواهیم دید) برای هر بلاک متفاوت خواهد بود، به این ترتیب تابع قادر خواهد بود تا بلاک هدف را از سایر موارد شناسایی کند.
- setTimeout در توابع بالا نقش یک وقفه را بازی می کند، به این ترتیب که با فراخوانی تابع animate در زمان های متوالی، بین فرم ها وقفه های خیلی کوتاهی ایجاد می شود تا در نهایت حاصل کار به شکل یک انیمیشن به نمایش درآید.
- تابع animate نیز به عنوان موتور کد عمل کرده و با دریافت چهار آرگومان و بررسی آنها، در نهایت انیمیشن را خلق می کند، در این تابع متغیر curTick زمان فعلی، elapsedTicks میزان اختلاف بین آخرین اجرای تابع animate و زمان فعلی و متغیر opening و closing نیز مقادیر id بلاک هدف را در خود دارند.
- همان طور که ملاحظه می کنید تابع animate برای کنترل استایل و ویژگی های css بلاک ها از متد style و object استفاده می کند، به طور مثال opening.style.height ارتفاع بلاک opening را تعیین می کند یا closing.style.display نوع display بلاک closing را مشخص می کند.
نکته: این کد با وجود حجم بسیار کم، تقریبا با تمام مرورگرها سازگار است، از جمله اینترنت اکسپلورر 6 و مابعد، فایرفاکس، گوگل کروم، اپرا، سافاری و...
کد css منوی آکاردئونی
برای اینکه منوهای ما به درستی کار کنند، علاوه بر کد جاوا اسکریپت، به استایل css و کلاس های آن نیازمندیم، بدین منظور استایل زیر را نیز باید در صفحه خود وارد کنیم (به صورت یک فایل خارجی و یا به صورت درون صفحه ای).
<style type="text/css">
.proboxtitle, .proboxcontent, .proboxmain{
position:relative;
}
.proboxtitle{
width:200px;
height:25px;
overflow:hidden;
text-align:right;
display:block;
cursor:pointer;
background-color:#666;
color:#FFF;
direction:rtl;
padding:4px;
text-align:center;
border-bottom:1px dashed #CCC;
}
.proboxcontent{
width:200px;
height:auto;
overflow:hidden;
display:none;
background-color:#F8F8F8;
padding:4px;
direction:rtl;
}
.proboxmain{
border:1px solid #F0F0F0;
width:208px;
}
</style>
همان طور که ملاحظه می کنید، کد css بالا سه کلاس دارد که با آن، ویژگی ها و خواص ظاهری سه بلاک را در صفحه کنترل می کنیم، همچنین برخی موارد در استایل بالا قابل تغییر و برخی نیز به نحوه عملکرد برنامه مربوط بوده و غیر قابل تغییر هستند.
نحوه استفاده از منوی آکاردئونی
برای استفاده از کدهای بالا، در نهایت باید منو و باکس ها را در بلاک های div تعریف کنیم، برای نمونه مثال زیر می تواند راهنمای ما باشد.
<div id="proboxmain" class="proboxmain">
<!-- منوی شماره 1 -->
<div class="proboxtitle" onclick="runprobox(1);">
تیتر باکس 1
</div>
<div id="probox1content" class="proboxcontent">
محتوای باکس آکاردئونی 1
</div>
<!-- منوی شماره 2 -->
<div class="proboxtitle" onclick="runprobox(2);">
تیتر باکس 2
</div>
<div id="probox2content" class="proboxcontent">
محتوای باکس آکاردئونی 2
</div>
<!-- منوی شماره 3 -->
<div class="proboxtitle" onclick="runprobox(3);">
تیتر باکس 3
</div>
<div id="probox3content" class="proboxcontent">
محتوای باکس آکاردئونی 3
</div>
<!-- منوی شماره 4 -->
<div class="proboxtitle" onclick="runprobox(4);">
تیتر باکس 4
</div>
<div id="probox4content" class="proboxcontent">
محتوای باکس آکاردئونی 4
</div>
</div>
توضیح:
- در مثال بالا، ابتدا یک بلاک اصلی با کلاس و آی دی proboxmain تعریف می کنیم، این بلاک تمام محتوای منوهای ما را در برمی گیرد.
- سپس برای هر منو، یک بلاک با کلاس proboxtitle و به همراه رویداد onclick تعریف می کنیم که تیتر منوها را در خود جای می دهد، این بلاک وظیفه فراخوانی تابع runprobox را دارد و یک عدد به عنوان آرگومان به تابع مذکور ارسال می کند، این عدد باید بین منوهای مختلف متفاوت و یکتا باشد تا برنامه بتواند بلاک مورد نظر را شناسایی کند.
- سپس در بلاک دیگری با آی دی و کلاس proboxcontent محتوای باکس خود را قرار می دهیم، در اینجا باید دقت کنید که برای آی دی، بعد از عبارت probox عدد آرگومان را قرار داده و سپس عبارت content را اضافه کنید، به فرض اگر آرگومان تابع runprobox عدد 3 باشد، آی دی بلاک محتوا باید به صورت probox3content تنظیم شود.
مثال و پیش نمایش آنلاین
برای بررسی و تست برنامه، می توانید از مثال و پیش نمایش آنلاین زیر استفاده کنید.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>وبگو | باکس آکاردئونی با جاوا اسکریپت</title>
<!-- http://webgoo.ir -->
<style type="text/css">
body{
font-family:Tahoma, Geneva, sans-serif;
font-size:12px;
direction:rtl;
}
.proboxtitle, .proboxcontent, .proboxmain{
position:relative;
}
.proboxtitle{
width:200px;
height:25px;
overflow:hidden;
text-align:right;
display:block;
cursor:pointer;
background-color:#666;
color:#FFF;
direction:rtl;
padding:4px;
text-align:center;
border-bottom:1px dashed #CCC;
}
.proboxcontent{
width:200px;
height:auto;
overflow:hidden;
display:none;
background-color:#F8F8F8;
padding:4px;
direction:rtl;
}
.proboxmain{
border:1px solid #F0F0F0;
width:208px;
}
</style>
<script type="text/javascript">
//<![CDATA[
var contentHeight = 34;
var TimeToSlide = 300.0;
var openprobox = ;
function runprobox(index){
var divID = "probox" + index + "content";
if(openprobox == divID){
divID = ;
}
setTimeout("animate(" + new Date().getTime() + "," + TimeToSlide + "," + openprobox + "," + divID + ")", 33);
openprobox = divID;
}
function animate(lastTick, timeLeft, closingId, openingId){
var curTick = new Date().getTime();
var elapsedTicks = curTick - lastTick;
var opening = (openingId == ) ? null : document.getElementById(openingId);
var closing = (closingId == ) ? null : document.getElementById(closingId);
if(timeLeft <= elapsedTicks){
if(opening != null){
opening.style.height = contentHeight + px;
}
if(closing != null){
closing.style.display = none;
closing.style.height = 0px;
}
return;
}
timeLeft -= elapsedTicks;
var newClosedHeight = Math.round((timeLeft/TimeToSlide) * contentHeight);
if(opening != null){
if(opening.style.display != block){
opening.style.display = block;
}
opening.style.height = (contentHeight - newClosedHeight) + px;
}
if(closing != null){
closing.style.height = newClosedHeight + px;
}
setTimeout("animate(" + curTick + "," + timeLeft +"," + closingId + "," + openingId + ")", 33);
}
//]]>
</script>
</head>
<body>
<noscript>
جاوا اسکریپت در مرورگر شما غیرفعال است یا پشتیبانی نمی شود!<br />
</noscript>
<div id="proboxmain" class="proboxmain">
<!-- منوی شماره 1 -->
<div class="proboxtitle" onclick="runprobox(1);">
تیتر باکس 1
</div>
<div id="probox1content" class="proboxcontent">
محتوای باکس آکاردئونی 1
</div>
<!-- منوی شماره 2 -->
<div class="proboxtitle" onclick="runprobox(2);">
تیتر باکس 2
</div>
<div id="probox2content" class="proboxcontent">
محتوای باکس آکاردئونی 2
</div>
<!-- منوی شماره 3 -->
<div class="proboxtitle" onclick="runprobox(3);">
تیتر باکس 3
</div>
<div id="probox3content" class="proboxcontent">
محتوای باکس آکاردئونی 3
</div>
<!-- منوی شماره 4 -->
<div class="proboxtitle" onclick="runprobox(4);">
تیتر باکس 4
</div>
<div id="probox4content" class="proboxcontent">
محتوای باکس آکاردئونی 4
</div>
</div>
<hr />
برای بررسی ویژگی های منو، بر روی یکی از آیتم ها کلیک کنید.
</body>
</html>