چگونه هدر وب سایت خود را در هنگام اسکرول کردن ثابت کنیم! ثابت کردن هدر هنگام اسکرول کردن را یاد بگیریم!

چگونه هدر وب سایت خود را در هنگام اسکرول کردن ثابت کنیم! ثابت کردن هدر هنگام اسکرول کردن را یاد بگیریم!
آکادمی آی تی
آکادمی آی تی
dots

چگونه هدر وب سایت خود را در هنگام اسکرول کردن ثابت کنیم! ثابت کردن هدر هنگام اسکرول کردن را یاد بگیریم!

زمان مورد نیاز برای مطالعه 5 دقیقه

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

دپارتمان ‌ها: آموزش طراحی سایت
1398/08/01
19,574 بازدید

در این مقاله ما سعی داریم که ببینیم چگونه هدر وب سایت خود را در هنگام اسکرول کردن ثابت کنیم! با اجرای تک به تک قوانینی که در این خصوص وجود دارد و کدهای مربوط به آن می توانیم یک هدر ثابت را ایجاد کنیم که با اسکرول کردن به سمت پایین محرک شود.

کد های HTML

ما این تمرین خودمون رو با تگ های header ،nav و دیگر تگ های تو در تو پیش می بریم.

Logo

  • about
  • Services
  • Portfolio
  • Contact

تگ nav که قسمتی از header است داری 3 المان می باشد. logo ،main menu و همچنین از یه button هم برای این که برای ما منو رو در هنگام ریسپانسیو شدن نمایش دهد استفاده می کنیم (below 1061px).

 

CSS اولیه

ابتدا اجازه بدین تا نگاهی به کد های CSS  بندازیم تا کمی بیشتر وارد داستان بشیم:

 header {
 position: fixed;
 top: 0;
 width: 100%;
 padding: 20px;
 box-sizing: border-box;
 background: #DD3543;
 }
 nav {
 display: flex;
 align-items: flex-end;
 justify-content: space-between;
 transition: align-items .2s;
 }
 .logo {
 font-size: 2rem;
 display: inline-block;
 padding: 20px 30px;
 background: #F35B66;
 color: #fff;
 margin: 50px 0 0 50px;
 transition: all .2s;
 } 
 ul {
 display: flex;
 margin: 50px 50px 0 0;
 padding: 0;
 transition: margin .2s;
 }
 li:not(:last-child) {
 margin-right: 20px;
 }
 li a {
 display: block;
 padding: 10px 20px;
 }
 .toggle-menu {
 display: none;
 font-size: 2rem;
 color: #fff;
 margin: 10px 10px 0 0;
 transition: margin .2s;
 }
 main { 
 display: block;
 padding: 0 20px;
 } 

 

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

  • پوزیشن برای تگ header ما fix می باشد (position:fixed).
  • ما برای طراحی تگ nav از flexbox استفاده کرده ایم.
  • لوگو ما margin-top:50px و margin-left:50px دارد و علاوه بر اون ما به لوگو خودمون ویژگی padding: 20px 30px هم داده ایم.
  • دکمه ای که برای ریسپانسیو بودن ترتیب داده ایم هم hidden می باشد و هنگاهی نمایش داده می شود که اندازه ی صفحه ی ما کمتر از 1061px  باشد (یعنی هنگامی که با تغییر دادن اندازه صفحه پنجره ی ما 1061px شود)؛ علاوه بر اون هم به دکمه ی موردنظر که در هنگام ریسپانسیو شدن نمایش داده می شود هم margin-top:10px و margin-right:10px داده ایم.
  • ما به المان هایی که مقدار خصوصیت آن ها در اینده تغییر می کنه هم transition داده ایم. با این کار ما بین حالت اولیه و حالت نهایی خود از  یک transition ظریفی استفاده کرده ایم.

 

با اعمال تغییرات بالا صفحه ما به شکل زیر در می آید:

Logo

 

Header-تحرک دادن به هدر

جهت ثابت کردن هدر هنگام اسکرول کردن باید دو مسئله را در نظر بگیریم. تا الان ما یه ساختار ساده ای از چیزی که می خواستیم رو درست کردیم. خب حالا وقتشه که بریم سراغ مرحله ی بعد:
کار اول المان main دقیقا باید در زیر header قرار بگیرد. به خاطر داشته باشیم که ما به header پوزیشن fix داده بودیم. (position:fixed) از این رو پوزیشن آن بالای main ما می باشد.
و کار دوم اینه کهHeader ما زمانی که به پایین صفحه scroll می کنیم باید حرکت کند.

برای حل کردن مسئله اول ما خصوصیت padding-top رو به المان main  خود اضافه می کنیم. مقداری که برای این خصوصیت در نظر می گیریم باید به میزان ارتفاع ای که برای header در نظر گرفته ایم باشه. در این مورد ما ارتفاع به خصوصی رو خب برای header خود در نظر نگرفته ایم بنابراین ما از javascript برای محاسبه آن کمک گرفته و سپس مقدار به دست آمده رو دقیقا برای مقدار padding خود قرار می دهیم.

برای حل مسئله دوم خود باید کار های زیر انجام گیرد:

میزانی که صفحه ی ما تا به حال به پایین اسکرول (scroll down) شده رو باز می یابیم.
اگر مقداری که به دست می آید از 150px بیشتر باشد، ما کلاس scroll را به header خود نسبت می دهیم. 

 

 

JavaScript–جاوا اسکریپت

کدهای جاوا اسکریپتی که ما به آن ها نیاز داریم رو برای شما آماده کرده ایم و  شما در تصویر زیر مشاهده می کنید.
ما با معرفی یک سری متغیر ها کار رو شروع کرده ایم، میزان ارتفاع header رو محاسبه کرده ایم و سپس این مقداری که با کمک جاوا اسکریپت محاسبه کردیم رو به خصوصیت padding-top که برای المان main  در نظر گرفته بودیم اضافه می کنیم.

 

 var m = document.querySelector("main"), h = document.querySelector("header"), hHeight; function setTopPadding() { hHeight = h.offsetHeight; m.style.paddingTop = hHeight + "px"; }


برای اعمال این تغییرات ما از خصوصیت offsetHeight برای بازگرداندن ارتفاع header  استفاده کرده ایم. در نظر داشته باشیم که برای به دست آوردن این مقدار ما می توانستیم از تابعی به نام getBoundingClientRect() هم استفاده کنیم. با استفاده از این تابع ما مقدار های کسری هم می توانیم به دست آوریم ولی خب خیلی به کار ما نمیاد.
حالا برای زمانی که scroll کردیم:

 function onScroll() { window.addEventListener("scroll", callbackFunc); function callbackFunc() { var y = window.pageYOffset; if (y > 150) { h.classList.add("scroll"); } else { h.classList.remove("scroll"); } } }


در این جا ما از یکی از خصوصیت های صفحه ی خود به نام pageYOffset  بهره می بریم تا میزانی که به سمت پایین scroll شده است (scroll down) رو خب به دست آوریم.
لازم به ذکر است که در ورژن های قدیمی تر (از 9 به پایین) IE  این تابع javascript  رو موردحمایت قرار نمی دهند.

بعد از اون ما از classList استفاده می کنیم تا بتونیم کلاس scroll رو در مواقع لزوم به header بدهیم یا از اون بگیریم. باید به این نکته هم توجه بشه که همه ی مرورگرها از این خصوصیت ای که ما استفاده کردیم حمایت نمی کنند؛ بنابراین اگر شما می خواهید از هر کدام از این خصوصیت ها در برنامه خود استفاده کنید بهتر است یک نگاهی به classList.js و همین طور classie.js بیاندازید. برای این مثال ما می تونستیم از خصوصیت className برای دستکاری کردن تک کلاس خود استفاده کنیم اما در عمل این راه حل خوبی برای زمانی که ما تعداد زیادی کلاس داریم نیست!
 
در نهایت ما تابع های خود را در 2 حالت صدا می زنیم:

  • اول زمانی که صفحه ما در حال لود/بارگذاری است.
  • و دوم زمانی که ما اندازه صفحه ی خود را دست کاری می کنیم.
 window.onload = function() { setTopPadding(); onScroll(); }; window.onresize = function() { setTopPadding(); };


در زمانی که اسکرول کردن ما از حد 150px تجاوز کرد ما یک سری قوانین دیگر CSS ای جایگزین می کنیم:

 .scroll { box-shadow: 0 7px 0 0 rgba(0, 0, 0, .1); } .scroll .logo { padding: 10px 20px; font-size: 1.5rem; } .scroll nav { align-items: center; } .scroll .logo, .scroll ul, .scroll .toggle-menu { margin: 0; } 

 

به طور مشخص ما تغییرات زیر رو نیز اعمال می کنیم:

  • یک box shadow ای به رنگ توسی به header خود اضافه می کنیم.
  • همچنین کم کردن میزان 2 خصوصیت رو به رو برای لوگو: padding  و font-size.
  • تغییر دادن ترتیب بندی برای المان هایی که ویژگی flex (که در بالا توضیح دادیم) دارند در میان cross-axis.
  • باید از logo ،menu و دکمه ای که برای اعمال ریسپانسیو ساخته ایم margin را حذف کنیم. ما تغییرات بالا رو براتون اعمال کردیم که شما می تونین در تصویر پایین مشاهده کنین:

اعمال تغییرات جاوا اسکریپت در logo

 

Going Responsive–اعمال ریسپانسیو

همان طور که در قسمت قبل هم ذکر شد زمانی که اندازه صفحه ی ما کمتر از 1061px شود ما منو رو پنهان کرده و دکمه ای رو که برای نمایش منو در نظر گرفته بودیم رو نمایش می دهیم.
که در زیر شما می تونید تغییرات اولیه ای که در هنگام ریسپانسیو شدن header صفحه شما می کنه رو مشاهده کنید:

Going Responsive–اعمال ریسپانسیو

 

و همین طور در زیر CSS ها مربوط به آن رو هم براتون آوردیم:

 @media screen and (max-width: 1060px) { header { padding: 10px; } nav { align-items: center; } ul { display: none; } .logo { font-size: 1.8rem; margin: 10px 0 0 10px; } .toggle-menu { display: block; } }

 

در اینجا زمانی که header جا به جا می شود هم مشاهده می کنید:

مشاهده جابه جایی هدر

 

Performance Considerations-نگاهی به عملکرد:

ثابت کردن هدر هنگام اسکرول کردن قوانین خاص  و کدهای مربوط به خود را دارد.  حالا که تونستیم به header خودمون جوری بسازیم که اون رفتاری که می خوایم رو داشته باشه به مرحله ای جلوتر می ریم و حرفه ای تر درباره ی چیزهایی مربوط به عملکرد این تغییرات هست بحث می کنیم.
تا الان تو مثال خودمون، کدهایی برای تغییر در حرکت کردن هدر نوشتیم که زمانی که صفحه رو scroll می کنیم، اجرا می شود. این به این معنی است که می تواند صدها بار و حتی بیشتر اتفاق بیافتد. این ممکن است که بعضی مشکلات رو در هنگام اجرا برای ما درست کند که خب خوشایند نیست به خصوص در زمانی که تابع callbackFunc ما شامل بسیاری از مواردی می شود که در زمان scroll up و scroll down کردن صفحه باید اجرا شوند.
در مثال ما با یک حرکت بسیار جزیی سر و کار داریم ولی در دنیای واقعی اینگونه نیست! در دنیای واقعی ما می خواهیم بسیاری از کار های پیچیده و تغییر مکان های گوناگون و بسیاری از امور دیگر رو هم همزمان انجام دهیم..

 

در نتیجه راه حل چیست؟

خب، در این جا راه کارهای گوناگونی وجود داره، ولی در حال به بررسی مختصر یکی از راه حل ها می پردازیم. به خصوص ما می خواهیم به تابع های خود اجازه بدیم که در 200 میلی ثانیه یک بار اجرا شوند ( البته این یک مقدار دلخواه است).
برای پیاده سازی این تابع ما از Lodash بهره می بریم که یک کتابخانه سودمند به زبان javascript می باشد. این کتابخانه دریچه هایی که ما نیاز داریم را در اختیار ما می گذارد.
اول ما این کتابخانه رو در پروژه خود تعریف کرده سپس کد زیر رو جایگزینش می کنیم:

 window.addEventListener("scroll", callbackFunc); 

و همین طور:

 window.addEventListener("scroll", _.throttle(callbackFunc, 200)); 


برای درک تفاوت اون اجازه بدین تا تست کوچکی انجام بدیم. ما یک شماره گری تعریف می کنیم که هر دفعه که callbackFunc ما اجرا شد این شماره گر افزایش پیدا کند. حالا سعی کنید که اسکرول به بالا و پایین کنید. وقتی این کار رو انجام می دهید، متوجه می شوید که شماره گر شما هر 200 میلی ثانیه تغییر می کند؛ سپس این پروسه رو بار دیگر بدون استفاده از Lodash تکرار کرده و متوجه می شوید که افزایش یافتن شماره گر بسیار سریع تر است. با اینکه برای مثال ساده ی ما این آزمون بلااستفاده به نظر می آید ولی شما در نظر داشته باشید که در اصل شما با کار های بسیار پیچیده تری سر و کار دارید.
با همین روش می توان اتفاقی که در هنگام resize کردن هم می افتد رو بهینه کرد.

تعریف شمارشگر

 

Browser Supports–حمایت مرورگرها

این effect در بسیاری از مرورگرها و دستگاه ها کار می کند ولی نمیشه گفت که با همه ی دستگاه ها سازگاری دارد، به طور مثال دستگاه های حاوی سیستم عامل iOS .
این اتفاق به این علت می افتد که scroll کردن رفتار متفاوتی در مرورگر های دسکتاپ در مقایسه با دستگاه های موبایل دارد.
به طور مثال در مرورگر های دسکتاپ scroll کردن پیوسته اتفاق می افتد در صورتی که در iPad به طور مثال شما انگشت خودتون رو باید روی صفحه گذاشته و تکان دهید.
با دانستن مسئله بالا باید تصمیم بگیرید که آیا استفاده از این الگو برای شما در صفحات وب سایت معقول می باشد یا نه.


خب دوستان و کاربران محترم آکادمی آی تی در این قسمت ما یک header ثابت برای شما ساختیم که در هنگامی که scroll به سمت پایین (scroll down) می کنیم محرک می شود.