پیمایش چرخ به صورت پیش فرض سریع

ساحل شریفی
Sahel Sharify

برای بهبود عملکرد اسکرول/زوم wheel ، توسعه دهندگان تشویق می شوند که شنوندگان رویداد wheel و mousewheel را با عبور گزینه {passive: true} به addEventListener() به عنوان غیرفعال ثبت کنند. ثبت شنوندگان رویداد به‌عنوان غیرفعال به مرورگر می‌گوید که شنوندگان چرخی preventDefault() فراخوانی نمی‌کنند و مرورگر می‌تواند با خیال راحت اسکرول و بزرگ‌نمایی را بدون مسدود کردن شنوندگان انجام دهد.

مشکل این است که اغلب شنوندگان رویداد چرخ از لحاظ مفهومی غیرفعال هستند ( preventDefault() فراخوانی نکنید) اما به طور صریح به این صورت مشخص نشده اند، و مرورگر باید منتظر بماند تا مدیریت رویداد JS قبل از شروع اسکرول/زوم کردن، حتی در انتظار باشد. ضروری نیست. در Chrome 56، ما این مشکل را برای touchstart و touchmove حل کردیم ، و این تغییر بعداً توسط سافاری و فایرفاکس پذیرفته شد. همانطور که از ویدیوی نمایشی که در آن زمان ساختیم مشاهده می‌کنید، این رفتار همانطور که ایجاد می‌شد تاخیر قابل توجهی در پاسخ اسکرول ایجاد کرد. اکنون در Chrome 73، ما همین مداخله را در رویدادهای wheel و mousewheel اعمال کرده‌ایم.

مداخله

هدف ما از این تغییر این است که پس از اینکه کاربر شروع به پیمایش با چرخ یا پد لمسی کرد، بدون نیاز به تغییر کد، زمان لازم برای به‌روزرسانی نمایشگر را کاهش دهیم. معیارهای ما نشان می‌دهد که 75 درصد از شنوندگان رویداد wheel و mousewheel که در اهداف ریشه (پنجره، سند یا بدنه) ثبت شده‌اند، هیچ مقداری را برای گزینه غیرفعال مشخص نمی‌کنند و بیش از 98 درصد از این شنوندگان preventDefault() فراخوانی نمی‌کنند. . در Chrome 73، شنونده‌های wheel و mousewheel ثبت‌شده در اهداف ریشه (پنجره، سند، یا بدنه) را به طور پیش‌فرض به حالت غیرفعال تغییر می‌دهیم. به این معنی است که شنونده رویداد مانند:

window.addEventListener("wheel", func);

معادل می شود:

window.addEventListener("wheel", func, {passive: true});

و فراخوانی preventDefault() در داخل شنونده با هشدار DevTools زیر نادیده گرفته می شود:

[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312

شکست و هدایت

در اکثریت قریب به اتفاق موارد شکستگی مشاهده نخواهد شد. فقط در موارد نادر (کمتر از 0.3٪ از صفحات بر اساس معیارهای ما)، پیمایش/زوم ناخواسته ممکن است به دلیل نادیده گرفتن فراخوان preventDefault() در داخل شنوندگان که به طور پیش‌فرض به عنوان غیرفعال در نظر گرفته می‌شوند، اتفاق بیفتد. برنامه شما می تواند با بررسی اینکه آیا فراخوانی preventDefault() اثری از طریق ویژگی defaultPrevented داشته است یا خیر، تعیین کند که آیا ممکن است این مورد را به طور طبیعی انجام دهد یا خیر. رفع موارد آسیب‌دیده نسبتاً آسان است: {passive: false} را به addEventListener() منتقل کنید تا رفتار پیش‌فرض را لغو کنید و شنونده رویداد را به‌عنوان مسدودکننده حفظ کنید.