ساخت یک منو کشویی برای موبایل

گردآوری و تالیف : ارسطو عباسی
تاریخ انتشار : 15 فروردین 1397
دسته بندی ها : جاوا اسکریپت

در این آموزش قصد داریم به شما ساخت یک منو همبرگری را نشان دهیم و بعد از آن روشی برای نمایش منوی کشویی از طریق رویدادهای جی‌کوئری را بگوییم. در این آموزش ما از Jade و Sass بجای HTML و CSS استفاده می‌کنیم. پس نیاز است که یک آشنایی اولیه با این موارد را نیز داشته باشید. 

ساخت چهارچوب اصلی

مرحله اول این آموزش را با ساخت یک چهارچوب کلی شروع می‌کنیم. در این قسمت قصد دارم که فایل مربوط به Jade و Sass را آماده کنم، البته این موارد الزامی نیستند و پس از این آموزش اگر شما ایده دیگری برای اجرا کردن این طرح داشتید می‌توانید از آن استفاده کنید. همچنین می‌توانید در روند آموزشی از آیتم‌های دیگر و استایل‌های منحصر به فرد خودتان بهره بگیرید.

فایل Jade :

body
    #container
        #header
        #body
            .content
                .left
                .right
                    - for (i=1; i <= 5 ; i++ )
                        div( id="text" + i )
            .content
                .left
                .right
                    - for (j=6; j <= 10 ; j++ )
                        div( id="text" + j )
            .content
                .left
                .right
                    - for (k=11; k <= 15 ; k++ )
                        div( id="text" + k )

فایل Sass:

=flex()
  display: -webkit-box
  display: -moz-box
  display: -ms-flexbox
  display: -webkit-flex
  display: flex
   
=transition($time)
  -webkit-transition: all $time ease
  -moz-transition: all $time ease
  -ms-transition: all $time ease
  -o-transition: all $time ease
  transition: all $time ease
 
html, body
  margin: 0
  padding: 20px 0
  +flex()
  justify-content: center
 
//----------------------------------//
 
#container
  width: 320px
  height: 550px
  background-color: #ebebeb
  overflow: hidden
 
#header
  height: 45px
  background-color: #9b9b9b
  position: relative
 
 
#body
  padding: 0 20px
  padding-top: 40px
  +flex()
 
  flex-direction: column
  justify-content: flex-start
 
.content
  +flex()
 
  flex-direction: row
  justify-content: flex-start
  margin-bottom: 25px
 
 
  .left
    width: 100px
    height: 100px
    margin-right: 15px
    background-color: #e1e1e1
 
  .right
    @for $i from 1 through 15
      #text#{$i}
        margin-top: 10px
        width: 50 + random(100) + px
        height: 10px
        background-color: #e1e1e1

نکته : در فایل Sass من مخلوطی از flex و transition را استفاده کرده‌ام. این مخلوط کردن به من این کمک را می‌کند که بتوانم به صورت مجدد از این المان‌ها در ادامه استفاده بکنم. به این صورت از این به بعد بجای استفاده کردن از display:flex همراه با تمام پیشوندهای آن به سادگی می‌توانم تنها از +flex() استفاده کنم.

این ساختار را در ادامه کدها مجددا مشاهده خواهیم کرد. نتیجه نهایی کدها باید چیزی شبیه به زیر باشد:

اپلیکیشن موبایل

می‌توانید کدهای این قسمت را نیز در Codepen دنبال کنید.

آیکون‌های منوی همبرگری

حال ما نیاز داریم که منوی همبرگری ساده در عین حال جذاب با قابلیت متحرک بودن از طریق CSS را ایجاد کنیم. در داخل div مربوط به #header یک div به نام #hamburger ایجاد کنید. بعد از آن در این div دو فرزند ایجاد کنید. آن‌ها باید کلاس یکسان و آی‌دی منحصر به فردی داشته باشند. 

#hamburger
    .strip#top
    .strip#bottom

حال نیاز داریم که به div والد یعنی hamburger و divهای فرزند با کلاس strip استایل‌های خودمان را بدهیم.

#hamburger
  height: 100%
  width: 45
  +flex()
 
  flex-direction: column
  justify-content: space-between
  padding-left: 20px

ارتفاع divها را برابر با div والدشان یعنی همان header را در نظر می‌گیریم که برابر با 100% است. همچنین مقدار عرض هرکدام از divها را به میزانی قرار می‌دهیم که قابلیت کلیک داشته باشند و بتوان به آن‌ها دسترسی داشت. مقدار آن ها را برابر با ۴۵ درنظر می‌گیریم. 

حال زمان آن است که فلکس‌باکسی را که در قبل با تمام پیشوندها و موارد دیگر ترکیب کردیم را به کدهای‌مان اضافه کنیم. از آنجایی که می‌خواهیم divهای مربوط به .strip را به صورت عمودی قرار دهیم مقدار flex-direction را برابر با column قرار می‌دهیم و مقدار justify-content را نیز برابر با  space-between، دلیل این کار آن است که بین divها یک فاصله را رعایت کرده باشیم. حال نیاز داریم که این divها را به سمت همدیگر بکشیم برای این کار به صورت نسبی مقادیر top و bottom مربوط به margin را برابر ۱۷ قرار می‌دهیم. 

#top
  margin-top: 17px
   
#bottom
  margin-bottom: 17px

همچنین برای اینکه به میزان مناسبی divها را به سمت راست ببریم از padding-left استفاده می‌کنیم. مقدار padding-left را برابر ۲۰ پیکسل قرار دهید.

بعد از این کار حال نوبت به استایل دهی می‌رسد برای اینکار تنها کافی‌ست به کلاس strip دسترسی داشته باشیم و بعد از آن استایل‌های مربوطه را اعمال کنیم:

.strip
  width: 25px
  height: 2px
  background-color: #ffffff

نتیجه نهایی تا به این قسمت برابر با تصویر زیر خواهد بود :

اپلیکیشن موبایل

کار بعدی که باید انجام دهیم این است که آیکون مربوط به منو را متحرک کنیم. قصد داریم بعد از کلیک بر روی آیکون، به یک علامت صلیب مانند تبدیل شود. 

متحرک سازی آیکون منو همبرگری

در این مرحله قصد داریم تا از کمی جی‌کوئری برای تغییر دادن وضعیت کلاس‌های CSS استفاده کنیم. ابتدای کار بیاید کلاس‌های CSS را که قصد تغییر داریم ایجاد کنیم. ابتدای کار قصد داریم که از خاصیت transition برای ایجاد تغییرات و متحرک سازی استفاده کنیم.

برای اینکار به هر دو div خاصیت‌های زیر را اضافه می‌کنیم:

#top
  margin-top: 17px
  +transition(.25s)
 
#bottom
  margin-bottom: 17px
  +transition(.25s)

)

حال نیاز داریم که کلاس‌هایی که می‌خواهیم به آن‌ها تغییر وضعیت دهیم را استایل دهی کنیم. ما قصد داریم روند تغییرات و چرخش‌ها را برای هر کلاس به صورت جداگانه انجام دهیم پس برای این دو مورد دو استایل جداگانه می‌نویسیم:

#top
  margin-top: 17px
  +transition(.25s)
 
  &.topRotate
    transform-origin: center
    transform: translateY(4px) rotateZ(45deg)
 
#bottom
  margin-bottom: 17px
  +transition(.25s)
 
  &.bottomRotate
    transform-origin: center
    transform: translateY(-5px) rotateZ(-45deg)

در این کدها ما دو کلاس با نام‌های bottomRotate و topRotate ایجاد کرده‌ایم و آن‌ها را استایل داده‌ایم. بعد از این کار ویژگی‌ آن ها را می‌توانیم از طریق divهای اصلی یعنی #top و #bottom اضافه و حذف کنیم.

نکته اینجاست که اندازه کلاس strip می‌تواند روی اندازه‌های translateY و rotateZ نیز برای متحرک‌سازی تاثیرگذار باشد. 

جابجایی کلاس‌ها با jQuery

در قسمت‌های قبلی اینکه هر div مربوط به .strip چقدر متحرک شود را تعیین کردیم. در هر حال، ما نیاز داریم که این کلاس‌ها را به قسمت event listener اضافه کنیم.

یک فایل جاوااسکریپتی جدید ایجاد کنید و از طریق کدهای زیر جای کلاس‌های فعال را با همدیگر عوض کنید:

$(document).ready(function(){
  $("#hamburger").click(function(){
      $("#top").toggleClass("topRotate");
      $("#bottom").toggleClass("bottomRotate");
  });
})

تمام کدهای‌مان را در $(document).ready(function(){}) قرار دادیم تا مطمئن شویم که همه این امکانات بعد از بارگذاری کامل صفحه انجام می‌شود. بعد از اینکه روی div مربوط به آی‌دی hamburger کلیک کردیم، کلاس‌های مربوطه فعال می‌شوند. 

نکته مهم: یادتان نرود، جی‌کوئری را به فایل‌های‌تان اضافه کنید.

کدهای مربوط به این قسمت

ایجاد لیست منو

مرحله بعدی کار این است که لیست‌های مربوط به منو را ایجاد کنیم. برای اینکار از ساختار زیر استفاده کنید و یا اینکه به کلی آن را با HTML نیز می‌توانید ایجاد کنید:

#dropDown
    #background
    ul
        li Home
        li Blog
        li Projects
        li Authors
        li Jobs
        li Contact

در این کدها از ul به عنوان والد برای li استفاده شده، برای اینکه بتوانیم دامنه انیمیشن را نیز توسعه بدهیم، از یک دایو با آی‌دی background استفاده کرده‌ایم. 

حال بیاید به ul و li استایل بدهیم :

ul
  list-style: none
  padding: 0
  margin: 0

مقادیر بالا را به نوبت برابر none – 0 – 0 قرار داده‌ایم. مقدار none شکل آیتم‌های لیست را به حالت ساده و بدون دایره در می‌آورد و مقادیر صفر نیز به این دلیل قرار گرفته شده که مقادیر پیشفرض خنثی شوند. حال نوبت به استایل دهی به li می‌رسد:

li
    //display: none
    background-color: #9b9b9b
    color: #ffffff
 
    font-family: 'Quicksand', sans-serif
    font-weight: lighter
    font-size: 15px
    padding: 20px
    padding-left: 60px
 
    &:after
      position: absolute
      content: ''
      left: 60px
      width: 60%
      height: 1px
      bottom: 4px
      background: rgba(255, 255, 255, 0.25)
 
    &:last-child:after
      width: 0

فعلا display:none را به صورت کامنت قرار داده‌ام اما وقتی که بخواهیم متحرک سازی را انجام دهیم، برای اینکه فورا آیتم‌های لیست را پنهان کنیم باید از این مورد بهره ببریم.

همچنین از یک شبه کلاس after استفاده کرده‌ام به این دلیل که بعد از هر li با یک خط آن‌ها را از همدیگر جدا کنم. last-child:after نیز خط را برای آخرین المان li حذف می‌کند.

کدهای مربوط به این قسمت

متحرک‌سازی لیست منو 

در اینجا قصد دارم از دستورالعمل‌های کنترلی Sass استفاده کنم که با استفاده از آن keyframeهای انیمیشن مربوط به CSS را ایجاد کنم.

@keyframes drop
  0%
    opacity: 0
    transform: scale(1.3)
 
  100%
    opacity: 1
    transform: scale(1)
     
@keyframes fold
  0%
    opacity: 1
    transform: scale(1)
 
  100%
    opacity: 0
    transform: scale(0.7)

در اینجا انیمیشن‌های keyframe را برای drop و fold تعریف کرده‌ایم.

Drop برای زمانی است که منو باز می‌شود. Fold روند برعکس را دنبال می‌کند. حال نیاز داریم که این keyframeها را به المان‌های li اضافه کنیم. این مرحله جائیست که کنترل‌های Sass بیشترین کاربرد را دارند.

@for $i from 1 through 6
  li:nth-child(#{$i})
    animation:
      name: fold
      duration: 80ms*(6-$i) + 1ms
      timing-function: ease-in-out
      fill-mode: forwards
 
  li.anim:nth-child(#{$i})
    animation:
      name: drop
      duration: 100ms*$i
      timing-function: ease-in-out
      fill-mode: forwards

در اینجا من از یک حلقه for استفاده کرده‌ام که به لیست‌های مختلف دسترسی داشته باشد. حال ما نیاز داریم با هر شاخص المان انیمیشنی را به li مربوطه بدهیم. ابتدا خط li.anim:nth-child(#{$i}) را در نظر می‌گیریم. در اینجا ما $iامین المان li را با کلاس anim می‌گیریم. 

خاصیت مهم دیگر duration است. duration: 100ms*$i برای انیمیشن drop میزان طول انیمیشن را با هر المان فرزند بیشتر می‌کند. بنابراین در ابتدای کار وقتی برای بار اول پروژه را اجرا می‌کنیم، طول انیمیشن برای اولین المان برابر با duration: 100ms و برای المان آخر duration: 600ms خواهد بود.

برای انیمیشنfold نیز به همین صورت کار را انجام می‌دهیم با این تفاوت که باید نسب به قبل کمی سریع‌تر برای المان آخر انیمیشن را اجرا کنیم. (duration: 80ms*(6-$i) + 1ms). 

در بالاتر به display:none اشاره کردم و گفتم برای پنهان شدن منو الزامی است که از آن بهره ببریم. اگر از آن استفاده نکنیم و مقدار را برابر با none قرار ندهیم، انیمیشن fold تنها یک بار اجرا می‌شود.

ما می‌خواهیم بعد از اینکه روی دکمه کلیک شد انیمیشن اجرا شود. بگذارید برای تنظیم display و مقادیر آن از جی‌کوئری استفاده کنیم. 

$(document).ready(function(){
  $("#hamburger").click(function(){
      $("#top").toggleClass("topRotate");
      $("#bottom").toggleClass("bottomRotate");
 
      $("li").show();
      $("li").toggleClass("anim");
 
  });
})

کدهای این قسمت

حال می‌توانیم ببینیم که انیمیشن مربوط به هر li به صورت جداگانه بارگذاری می‌شود. با این حال ما قصد داریم که آن را با احساس بهتری نمایش دهیم.

برای این منظور تنها کافی‌ست که ارتفاع را کمی افزایش دهیم. برای این کار از آی‌دی مربوط به دایو background استفاده می‌کنیم که المان‌های ul و li در آن‌ها قرار دارد. 

#background
  width: 100%
  height: 0
  background-color: #9b9b9b
  position: absolute
  +transition(.45s)
 
  &.expand
    height: 550px

برای اینکار از کلاسexpand بهره برده‌ایم که بتوانیم عمل جایگزینی را انجام دهیم.

کدهای نهایی

در پایان

در روند این آموزش نکته جالب این بود که به خوبی می‌توانیم از حلقه for در قالب HTML استفاده کنیم. جدای از آن ما انیمیشن‌های keyframe مربوط به CSS را ایجاد کردیم و آن‌ها را به المان خاصی اضافه نمودیم. بعد از آن‌ با استفاده از جی‌کوئری کلاس‌ها را جابجا کردیم.

منبع

مقالات پیشنهادی

۵ پلتفرم برای ساخت اپلیکیشن بدون نیاز به کدنویسی

با افزایش استفاده از تلفن‌های هوشمند، اپلیکیشن‌های موبایل به پر استفاده ترین پلتفرم‌های حال حاضر تبدیل شده اند. توسعه‌دهندگان کنونی نیز استعداد‌های خو...

۱۱ اپلیکیشن موبایل برای طراحان وب

یکی از خوبی‌های فریلنسر بودن این است که شما تقریبا در هر جایی می‌توانید کارهای‌تان را انجام دهید. با این حال فشار کاری و مداوم نشستن پشت یک کامپیوتر م...

هک css - ساخت یک Dropdowns تنها با checkbox

در این آموزش سریع ، ما یک نگاه به تنها روش ساخت Dropdowns کردیم بعد تصمصیم گرفتیم به دنبال یک راه دیگه برای ساخت Dropdowns بگردیم که به یک روش هوشمندا...

ساخت یک سیستم متحرک فوق العاده برای پنل عضویت ویژه

طراحی یک فرآیند پرداخت آسان هرگز راحت نبوده چون هیچ استاندارد جهانی براش وجود نداره .اگه شما در ارائه و پیشنهاد دادن پنل های مختلف با قیمت های مختلف م...