Chrome DevTools در حال راهاندازی درخت دسترسپذیری کامل است که به توسعهدهندگان کمک میکند تا یک نمای کلی از کل درخت را دریافت کنند. در این پست با نحوه ایجاد این درخت و نحوه استفاده از آن در کار خود آشنا شوید.
درخت دسترسی چیست؟
فناوری کمکی مانند صفحهخوانها از API دسترسی Chromium برای تعامل با محتوای وب استفاده میکند. مدل زیربنایی این API درخت دسترسی است: درختی از اشیاء دسترسی که فناوری کمکی میتواند ویژگیها و ویژگیها را جستجو کند و اقداماتی را روی آن انجام دهد . توسعه دهندگان وب درخت دسترسی را عمدتاً از طریق ویژگی های DOM مانند ویژگی های ARIA برای HTML شکل می دهند و دستکاری می کنند.
در Chrome DevTools ، ما بخش دسترسپذیری را ارائه میکنیم تا به توسعهدهندگان کمک کنیم بفهمند محتوایشان چگونه در معرض فناوری کمکی قرار میگیرد. به طور مشخص، هنگامی که یک گره در نمایشگر درختی DOM انتخاب میشود، ویژگیهای گره دسترسی متناظر به همراه نمایی از اجداد گره و فرزندان مستقیم آن در صفحه نمایش داده میشود.
درخت چگونه ایجاد می شود؟
قبل از اینکه به نمای درختی کامل جدید در DevTools بپردازیم، اجازه دهید به طور خلاصه به این موضوع بپردازیم که درخت دسترسپذیری در شرایط ملموستر چیست. درخت دسترسی مشتق شده از درخت DOM است. ساختار آن تقریباً یکسان است، اما برای حذف گرههایی که محتوای معنایی ندارند، مانند عنصر <div>
که صرفاً برای استایلسازی استفاده میشود، ساده شده است. هر گره در درخت نقشی مانند Button
یا Heading
و اغلب نامی دارد که می تواند از ویژگی های ARIA یا مشتق از محتویات گره باشد. اگر به یک سند HTML نگاه کنیم:
<html>
<head>
<title>How old are you?</title>
</head>
<body>
<label for="age">Age</label>
<input id="age" type="number" name="age" value="42">
<div>
<button>Back</button>
<button>Next</button>
</div>
</body>
</html>
رندر کننده در Chromium، به نام Blink، یک درخت دسترسی داخلی را تقریباً به شرح زیر استخراج می کند.
role='rootWebArea' focusable name='How old are you?'
role='genericContainer' ignored
role='genericContainer' ignored
role='labelText'
role='staticText' name='Age'
role='spinButton' editable focusable name='Age' value='42'
role='genericContainer' editable
role='staticText' editable name='42'
role='genericContainer'
role='button' focusable name='Back'
role='staticText' name='Back'
role='button' focusable name='Next'
role='staticText' name='Next'
توجه داشته باشید که این نمایش حاوی چندین گره اضافی با نقش genericContainer
است که ظاهراً با بیانیه بالا که درخت دسترسی یک مشتق ساده شده از درخت DOM است در تضاد است. با این حال، بیشتر این گره ها فقط در درخت داخلی رخ می دهند و در معرض فناوری کمکی قرار نخواهند گرفت. از آنجایی که DevTools اطلاعات دسترسی خود را مستقیماً از فرآیند رندر جمعآوری میکند، این نمایش درختی است که DevTools مدیریت میکند.
درخت دسترسی کامل در DevTools
درخت دسترسی کامل و جدید با درخت DOM همگام شده است تا توسعه دهندگان بتوانند بین این دو درخت جابجا شوند. ما امیدواریم که درخت جدید قابل بررسی تر، مفیدتر و استفاده آسان تر باشد.
اکنون که می دانید درخت دسترسی چگونه کار می کند، می توانید از DevTools برای مشاهده نمای درختی جدید استفاده کنید. سند HTML زیر با عنوان، عنوان و دو دکمه برای نشان دادن درخت استفاده می شود.
<!DOCTYPE html>
<title>Test</title>
<h1>Heading for example page</h1>
<div>
<button>Back</button>
<button>Next</button>
</div>
نمای درختی قبلی فقط به شما امکان می دهد یک گره و اجداد آن را کشف کنید.
اکنون، وقتی درخت جدید را تغییر میدهید، نمای درختی DOM را جایگزین میکند و به شما امکان میدهد درخت دسترسی کامل برای صفحه را ببینید:
درخت سازی تنبل
برای اینکه درخت حتی برای مکانهای بزرگتر کارایی داشته باشد، درخت بهطور تنبلی در قسمت جلویی در حین کاوش ساخته میشود. هنگامی که یک گره در درخت گسترش می یابد، فرزندان برای گره ها از طریق پروتکل Chrome DevTools Protocol (CDP) واکشی می شوند و درخت بازسازی می شود.
زندگی کنید
نمای درختی جدید زنده است و اگر درخت دسترسی در رندر تغییر کند به صورت پویا به روز می شود. به همان مکانیکهایی متصل میشود که فناوری کمکی را از تغییرات درخت مطلع میکند و از آن برای انتشار رویدادها به جلوی ابزار DevTools با گرههای بهروز شده استفاده میکند. در عمل، پشتیبان CDP به بهروزرسانی درخت گوش میدهد، گرههایی که قبلاً درخواست شدهاند را پیگیری میکند، و در صورت تغییر هر یک از این گرهها، رویدادها را به frontend DevTools ارسال میکند.
داستان درختان زیاد
در توضیح اینکه درخت دسترسپذیری چیست، یاد گرفتید که چگونه Blink یک درخت دسترسی برای DOM که در حال ارائه است میسازد و DevTools این درخت را از طریق CDP واکشی میکند. در حالی که این درست است، ما برخی از پیچیدگیها را در این توصیف حذف کردیم. در واقعیت، روشهای بسیار زیادی برای تجربه درخت دسترسی در Chromium وجود دارد. هنگام طراحی نمای درختی جدید برای DevTools، ما در طول مسیر انتخاب هایی در مورد اینکه چه بخشی از داخلی های دسترسی Chromium را می خواهیم ظاهر کنیم، انجام داده ایم.
پلتفرم ها
هر پلتفرمی یک API دسترسی متفاوت دارد و در حالی که شکل درخت در همه پلتفرمها یکسان است، API برای تعامل با درخت متفاوت است و نام ویژگیها میتواند متفاوت باشد. DevTools درخت داخلی Chromium را نشان میدهد که در آن نقشها و ویژگیها با آنچه در مشخصات ARIA تعریف شده است مطابقت دارند.
فریم های متعدد و جداسازی سایت
از آنجایی که Chromium نه تنها محتوای هر برگه را در فرآیندهای رندر مختلف قرار می دهد، بلکه اسناد بین سایتی را نیز در فرآیندهای رندر مختلف ایزوله می کند ، ما باید به هر سند فرزند خارج از فرآیند جداگانه از طریق CDP متصل شویم و درخت دسترسی آن را واکشی کنیم. سپس این زیردرخت ها را در قسمت جلویی به هم می چسبانیم تا توهم یک درخت منسجم را ایجاد کنیم، اگرچه آنها در فرآیندهای رندر متفاوت در Chromium زندگی می کنند.
گره های نادیده گرفته شده و غیر جالب
ما برخی از گره ها را به صورت پیش فرض پنهان می کنیم: گره های نادیده گرفته شده، و گره هایی با نقش "عمومی" بدون نام. این گره ها هیچ معنای معنایی ندارند و در مورد گره های نادیده گرفته شده، در معرض فناوری کمکی قرار نمی گیرند. ما این گره ها را پنهان می کنیم تا از بهم ریختگی نمای درختی جلوگیری کنیم. اگر این کار را نمیکردیم، درخت دسترسپذیری برای اکثر صفحات وب در عوض چیزی شبیه به این بود:
احتیاط در اینجا این است که اساساً به این معنی است که ما باید درخت دیگری غیر از آنچه در backend موجود است بسازیم. مثلاً بگویید که گرههای A، B، C و X داریم که در آن A دارای فرزند X و B است، و X دارای فرزند C است. اگر X یک گره نادیده گرفته شده است، X را از درخت هرس میکنیم و در عوض درختی ایجاد میکنیم. C فرزند A است.
در قسمت جلویی، درخت کامل شامل گرههای نادیده گرفته شده را میسازیم و فقط آنها را درست قبل از رندر کردن گرهها هرس میکنیم. ما این کار را به دو دلیل انجام می دهیم:
- مدیریت بهروزرسانیهای گره از باطن را بسیار سادهتر میکند ، زیرا ساختار درختی یکسانی در هر دو نقطه پایانی داریم. به عنوان مثال، اگر گره B در مثال حذف شود، یک به روز رسانی برای گره X دریافت می کنیم (از آنجایی که فرزندان آن تغییر کرده اند)، اما اگر آن گره را هرس کرده بودیم، به سختی متوجه می شدیم که چه چیزی را به روز کنیم.
- این تضمین می کند که تمام گره های DOM دارای یک گره دسترسی متناظر هستند. هنگامی که درخت تغییر می کند، گره مربوط به گره انتخاب شده در درخت DOM را انتخاب می کنیم. بنابراین برای مثال قبلی، اگر کاربر درخت را تغییر دهد در حالی که گره DOM مربوط به X انتخاب شده است، X را بین گره های A و B تزریق می کنیم و X را در درخت انتخاب می کنیم. این به کاربر اجازه می دهد تا گره دسترسی را برای همه گره های DOM بررسی کند و به تعیین دلیل نادیده گرفتن گره کمک کند.
ایده های آینده
راه اندازی درخت دسترسی جدید فقط شروع است. ما چند ایده برای پروژههای آینده داریم که میتوانیم بر روی نمای جدید ایجاد کنیم، اما مشتاق شنیدن نظرات شما نیز هستیم!
فیلترهای جایگزین
همانطور که در بالا توضیح داده شد، ما در حال حاضر گره هایی را که غیر جالب تلقی می شوند فیلتر می کنیم. ما میتوانیم راهی برای غیرفعال کردن این رفتار و نمایش همه گرهها ارائه کنیم یا فیلترهای جایگزینی مانند نمایش گرههای مشخصه یا نمایش سرفصلها ارائه کنیم.
مسائل a11y را برجسته کنید
ما میتوانیم تحلیل «بهترین عملکرد دسترسی» را با درخت ترکیب کنیم و مسائل دسترسی را مستقیماً در گرههای متخلف برجسته کنیم.
اقدامات دسترسی سطحی در DevTools
درختی که در حال حاضر نشان میدهیم صرفاً یک طرفه است: به ما امکان میدهد در هنگام مرور یک صفحه وب خاص، ایدهای از اطلاعاتی که به فناوری کمکی داده میشود، داشته باشیم. اقدامات دسترسپذیری ارتباط را در جهت دیگر نشان میدهند: آنها به فناوری کمکی اجازه میدهند تا بر روی رابط کاربری ارائهشده عمل کند. ما میتوانیم چنین کنشهایی را در DevTools نشان دهیم تا با استفاده از API موجود برای فناوری کمکی، به اعمالی مانند «کلیک کردن»، پیمایش، یا تغییر مقادیر روی صفحه اجازه دهیم.