توابع وقفه را حذف کنید و از شر اشکالهای آنها خلاص شوید، این همان رویدادی است که واقعاً به آن نیاز دارید: scrollend.
قبلاز رویداد scrollend، روش قابلاعتمادی برای تشخیص کامل شدن پیمایش وجود نداشت. این یعنی رویدادها دیر یا زمانی که انگشت کاربر هنوز روی صفحهنمایش بود، اجرا میشدند. این عدم اطمینان در دانستن اینکه پیمایش واقعاً چه زمانی پایان یافته است، منجر به اشکال و تجربه ضعیف برای کاربر میشود.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
بهترین کاری که این استراتژی setTimeout() میتواند انجام دهد این است که بداند آیا پیمایش برای
100ms متوقف شده است یا نه. این باعث میشود که بیشتر شبیه رویداد توقف پیمایش باشد تا رویداد پایان پیمایش.
پساز رویداد
scrollend
، مرورگر همه این ارزیابیهای دشوار را برای شما انجام میدهد.
document.onscrollend = event => {…}
این چیز خوبی است. Perfectly timed and packed full of meaningful conditions before emitting.
امتحان کنید!
جزئیات رویداد
رویداد scrollend زمانی فعال میشود که:
- مرورگر دیگر پیمایش را پویانمایی یا ترجمه نمیکند.
- کاربر لمس را رها کرده است.
- اشارهگر کاربر از روی دکمه پیمایش برداشته شده است.
- کلید فشردهشده توسط کاربر رها شده است.
- پیمایش به قطعه تکمیل شده است.
- میزان کردن پیمایش تکمیل شد.
- scrollTo() تکمیل شده است.
- کاربر نمای دیداری را پیمایش کرده است.
رویداد scrollend در شرایط زیر فعال نمیشود:
- اشاره کاربر منجر به هیچ تغییری در موقعیت پیمایش نشود (هیچ ترجمهای انجام نشده باشد).
- scrollTo() به هیچ ترجمهای منجر نشد.
A reason this event took so long to come to the web platform was due to the many
small details that needed specification details. یکی از پیچیدهترین حوزهها
بیان جزئیات scrollend برای نمای دیداری
درمقابل سند بود. صفحه وبی را درنظر بگیرید که روی آن زومپیش میکنید. در این حالت بزرگنماییشده میتوانید پیمایش کنید، و این پیمایش لزوماً پیمایش سند نیست. مطمئن باشید که حتی این تعامل پیمایش کاربرمحور در نمای دیداری
پساز تکمیل، رویداد scrollend را منتشر خواهد کرد.
استفاده از رویداد
مانند سایر رویدادهای پیمایش، میتوانید شنوندگان را به چند روش ثبت کنید.
addEventListener("scrollend",> (event) = {
// scroll ended
});
aScrollingElement.addEventListener("scroll>end", (event) = {
// scroll ended
});
یا از خصوصیت رویداد زیر استفاده کنید:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
شبیهسازهای مرورگر و ارتقای پیشرو
اگر میخواهید همین حالا از این رویداد جدید استفاده کنید، بهترین توصیه ما این است. میتوانید به استفاده از استراتژی پایان پیمایش فعلیتان (اگر دارید) ادامه دهید و در ابتدای آن، پشتیبانی را با این کد بررسی کنید:
'onscrollend' in window
// true, if available
این مقدار بسته به اینکه مرورگر رویداد را ارائه میدهد یا نه، درست یا نادرست را گزارش میکند. با این بررسی، میتوانید کد را منشعب کنید:
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll => event = {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
این شروع خوبی برای ارتقای پیشرو رویداد scrollend شما در زمان دردسترس بودن آن است. همچنین میتوانید
شبیهساز مرورگر
(NPM) را امتحان کنید که من ساختهام و بهترین عملکردی را که
مرورگر میتواند داشته باشد ارائه میدهد:
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
شبیهساز مرورگر بهتدریج ارتقا مییابد تا از رویداد scrollend داخلی مرورگر (درصورت دردسترس بودن) استفاده کند. اگر دردسترس نباشد، اسکریپت رویدادهای اشارهگر را تماشا میکند و
پیمایش میکند تا بهترین تخمین ممکن را از پایان رویداد انجام دهد.
موارد استفاده
بهتر است از انجام کارهای سنگین محاسباتی درحین پیمایش خودداری کنید. این روش تضمین میکند که پیمایش آزادانه از هر مقدار حافظه و پردازش که میتواند استفاده کند تا تجربه روان باقی بماند. استفاده از رویداد scrollend زمان مناسبی برای فراخوانی و انجام کارهای سخت فراهم میکند، زیرا پیمایش دیگر اتفاق نمیافتد.
از رویداد scrollend میتوان برای راهاندازی کنشهای مختلف استفاده کرد. یک مورد استفاده رایج
همگامسازی عناصر میانای کاربر مرتبط با موقعیتی است که پیمایش
متوقف شده است. برای مثال:
- همگامسازی موقعیت پیمایش گردونه با نشانگر نقطهای.
- همگامسازی کردن مورد گالری با فراداده آن.
- واکشی دادهها پساز اینکه کاربر به برگه جدیدی پیمایش میکند.
سناریویی را تصور کنید که در آن کاربر ایمیلی را با تند کشیدن رد میکند. پساز اینکه کاربر تند کشیدن را تمام کرد، میتوانید کنش را براساس جایی که کاربر به آن پیمایش کرده است انجام دهید.
همچنین میتوانید از این رویداد برای همگامسازی پساز پیمایش برنامهای یا کاربر، یا کنشهایی مثل ثبت گزارش تجزیهوتحلیل استفاده کنید.
در اینجا نمونه خوبی آورده شده است که در آن چندین عنصر مانند پیکانها، نقطهها، و تمرکز باید براساس موقعیت پیمایش بهروز شوند. ببینید چطور این گردونه را در YouTube ساختم. همچنین، نسخه نمایشی زنده را امتحان کنید.
از مهدی کاظمی برای کار مهندسیاش روی این موضوع و از رابرت فلک برای راهنماییاش درباره API و پیادهسازی سپاسگزاریم.