قطعا تا الان در سایت های زیادی مشاهده کرده اید که وقتی صفحه را اسکرول می کنید به محض اینکه یک عنصر کاملا درون صفحه نمایش قرار می گیرد افکتی بر روی آن اجرا می شود.
برای روشن شدن موضوع در دموی زیر اسکرول کنید تا مربع موجود کاملا درون صفحه قرار گیرد:
See the Pen isElementInViewport by Mojtaba Seyedi (@seyedi) on CodePen.
مشاهده می کنید که به محض ورود کامل آن به Viewport به دایره تبدیل می شود و رنگ آن نیز تغییر می کند. در ادامه یکی از روش های انجام این کار را بررسی می کنیم.
مرحله اول: تشخیص ورود کامل عنصر در Viewport
در جاوااسکریپت متدی به نام getBoundingClientRect وجود دارد که می توان از طریق آن موقعیت عنصر را نسبت به viewport تشخیص داد. پس کافی است بصورت زیر موقعیت عنصر را به نسبت به Viewport بررسی کرد:
var rect = el.getBoundingClientRect();
rect.top >= 0 // لبه بالای عنصر از لبه بالای ویوپرت پایین تر قرار دارد
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) // لبه پایین عنصر از لبه پایین ویوپرت بالاتر قرار دارد
حال اگر نیاز باشد تا بررسی کنیم که آیا عنصر از نظر افقی هم درون Viewport قرار دارد یا نه, می توانیم بصورت زیر عمل کنیم:
var rect = el.getBoundingClientRect();
rect.left >= 0
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
و در نهایت می توانیم تابعی تعریف کنیم که عنصری را به عنوان ورودی بگیرد و اگر عنصر درون Viewport قرار داشت true
و در غیر این صورت false
بر گرداند:
function isElementInViewport(el) {
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
برای بررسی کامل این روش و نکات خاص آن به این سوال در stackoverflow سر بزنید.
مرحله دوم: اضافه کردن کلاس
در ادامه تابعی را در زمان بارگذاری صفحه و همچنین در زمان اسکرول شدن صفحه هر بار فراخوانی می کنیم. که کار این تابع این است که اگر عنصری که به آن به عنوان ورودی می دهیم درون Viewport قرار داشت کلاسی به نام in-viewport
را به آن اضافه کند:
var element = document.querySelector(".my-element");
function addClassOnScroll() {
if (isElementInViewport(element)) {
element.classList.add("in-viewport");
}
}
window.addEventListener("load", addClassOnScroll);
window.addEventListener("scroll", addClassOnScroll, {passive: true});
از {passive: true}
جهت پرفرمنس بهتر کار در زمان اسکرول استفاده می شود. اما توجه کنید که در مرورگر IE این مورد پشتیبانی نمی شود و خطا ایجاد میکند.
مرحله سوم: اعمال افکت در CSS
تا اینجا همه مقدمه بود تا به قسمت شیرین کار برسیم. اینجا شما هستید و خلاقیتتان. یک کلاس دارید و یک عنصر و یک دنیا افکت که می توانید از طریق CSS بر روی عنصر اعمال کنید. در مثالی که در اول مطلب مشاهده کردید بصورت زیر عمل شده بود:
.element.in-viewport {
background-color: red;
border-raidus: 50%;
}
یعنی زمانی که کلاس in-viewport
به عنصر داده شود تغییرات بالا بر روی عنصر اعمال می شود.
دموی نهایی
دو نکته در دموی زیر وجود دارد:
1. اعمال این روش بر روی چندین عنصر
2. حذف کلاس in-viewport
در زمان خروج عنصر از Viewport.
See the Pen Running CSS animation by Mojtaba Seyedi (@seyedi) on CodePen.
منبع
مثل همیشه مطلب عالی بود
ببخشید سوالمو اینجا مطرح میکنم … حتما تو این سایت ها دیدن که یه فایل زنده دارن که 3d هست و کاربر میتونه با موس حرکتش بده و همه جهاتش رو ببینه!؟ اون چجوریه!؟
مجتبی جان عشقی خیلی وقته میام تو این سایت تقریبا هر مشکلی هر سوالی دارم یه سر به اینجا میزنم علاوه بر اینکه جواب سوالمو پیدا میکنم چیزای باحال تری پیدا میکنم واقعا مخلصم
خدا کمک کنه بیشتر و بهتر در خدمت باشیم، براتون آرزوی موفقیت میکنم.