• توجه: در صورتی که از کاربران قدیمی ایران انجمن هستید و امکان ورود به سایت را ندارید، میتوانید با آیدی altin_admin@ در تلگرام تماس حاصل نمایید.

جاوا اسکریپت-menu accordion (منو جمع شونده)

sky boy

متخصص بخش برنامه نویسی

ساخت منوها و باکس های آکاردئونی (accordion) یا به اصطلاح جمع شونده، یکی از قابلیت هایی است که جاوا اسکریپت (JavaScript) و
کتابخانه های زیرمجموعه آن مانند جی کئوری (jQuery) در اختیار برنامه نویسان و طراحان وب قرار میدند،
قابلیت تعاملی که این نوع منوها به رابط کاربری (Interface) سایت یا وبلاگ میدن باعث میشه که خیلی از مدیران وب گرایش به سمت استفاده از اون رو داشته باشند،
البته در این مورد باید همیشه به مقوله سازگاری، سرعت و سبکی صفحات دقت کرد،
چرا که هرچند میتونیم جلوه های خیلی خاصی در صفحات وب ایجاد کنیم، اما باید توجه داشت که این جلوه ها سرعت بارگذاری و قابلیت سازگاری سایت یا وبلاگ رو
در مرورگرها و سیستم های مختلف تحت تاثیر قرار ندهند،همیشه استفاده از کدهای کم حجم با بیشترین سازگاری توصیه میشه.

منظور از منوی آکاردئون :

منوی آکاردئونی در واقع برگرفته از نام واژه آکاردئون (accordion) و به معنی یک نوع ساز بادی معروفه،
قسمتی از این ساز دارای یک مجاری عبور هوای فنر مانند و پله پله ای هست که نوازنده برای نواختن آهنگ باید اون رو با دست خودش به طور متناوب حرکت بده،
به خاطر شباهت این نوع منو با این ساز آکاردئونی گفته میشه.

 
آخرین ویرایش:

sky boy

متخصص بخش برنامه نویسی

کد جاوا اسکریپت برای ساخت باکس آکاردئونی

یکی از سبک ترین و سازگارترین توابع برای این کار:

کد:
<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 و مابعد، فایرفاکس، گوگل کروم، اپرا، سافاری و...

 

sky boy

متخصص بخش برنامه نویسی

کد 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 تعریف کنیم، برای نمونه مثال:

HTML:
<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 تنظیم شود.

 

sky boy

متخصص بخش برنامه نویسی

کد کامل این منو:


HTML:
<!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>
<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>
 
بالا