Popover های منطقه متنی در مورد API های مرورگر به من آموختند

من به تازگی چندین سوراخ خرگوش راجع به ساخت ویراستاران Wysiwyg و پوپورها پایین رفتم. در حالی که در مرخصی زایمان است ، سرانجام وقت دارم که مشکلات فنی تصادفی را بدون مهلت کشف کنم – یک فرصت نادر.
تا کنون ، من به مشارکت در یک عامل منبع باز هوش مصنوعی به نام Codename Goose ساخته شده با یک پشتیبان زنگ زدگی و رابط چت مبتنی بر الکترونی متمرکز شده ام. من یک درخواست کشش برای اضافه کردن یک ویرایشگر WYSIWYG به رابط چت خود ارسال کردم و تصمیم گرفتم به جای استفاده از بسته های موجود ، یک راه حل سفارشی بسازم. نگهبانان از این رویکرد قدردانی می کنند زیرا وابستگی ویرایشگر اندازه بسته های نفخ ، اما نگرانی در مورد نوار ابزار مصرف فضای بیش از حد بصری را ایجاد می کند. آنها پیشنهاد کردند که به جای آن یک نوار ابزار پوپور را اجرا کنید.
من به اشتباه تصور کردم ایجاد یک نوار ابزار شناور ساده خواهد بود. هدف من:
- هنگام انتخاب متن ، نوار ابزار Popover را نشان دهید
- آن را دقیقاً بالاتر از انتخاب قرار دهید
- متن متن بسته بندی شده را که چندین خط را پوشانده است کنترل کنید
- در طول پیمایش موقعیت دقیق را حفظ کنید
دست زدن به پاپورها در یک عنصر منطقه متن پیچیده تر از حد انتظار بود. در این پست وبلاگ ، آنچه را که آموخته ام به اشتراک می گذارم.
مناطق متن عناصر متوسط DOM شما نیستند.
بر خلاف عناصر HTML معمولی که در آن می توانیم محتویات را دستکاری کنیم ، موقعیت ها را اندازه گیری کنیم و عناصر جدید را اضافه کنیم ، مناطق متن فقط محتوای متن خام و API های انتخاب اساسی را در معرض نمایش قرار می دهند. مرورگرها رندر خود را در پشت صحنه کنترل می کنند.
من از کلود خواستم تا یک قیاس برای تصویر بیشتر ایجاد کند:
- عناصر HTML منظم مانند داشتن خانه ای هستند که می توانید مبلمان را به اطراف خود جابجا کنید ، موارد جدیدی را اضافه کنید ، مسافت بین چیزها و غیره را اندازه گیری کنید.
- مناطق متنی بیشتر شبیه این هستند که از طریق پنجره به اتاقی که نمی توانید وارد کنید ، نگاه کنید. شما می توانید آنچه در داخل است مشاهده کنید و برخی از تغییرات اساسی را ایجاد کنید (مانند اضافه کردن/حذف متن) ، اما نمی توانید به طور مستقیم به مواردی برسید و دستکاری کنید. این مرورگر با استفاده از قابلیت ویرایش متن سیستم عامل بومی ، تمام کارهای داخلی را کنترل می کند.
پاپ های خارج از مناطق متن
API پوپور
همه مرورگرهای مدرن شامل یک API داخلی داخلی برای ایجاد عناصر پنجره است. در اینجا یک مثال آورده شده است:
محدودیت ها
در حالی که این API سازگار با مرورگر متقاطع و ساده برای اجرای آن است ، اما دارای چندین محدودیت است:
- این فقط با عناصر دکمه از زمان لازم کار می کند
popovertarget
ویژگی فقط روی دکمه ها موجود است - شما باید از CSS برای قرار دادن پوپور نسبت به عنصر هدف آن استفاده کنید
- و بزرگترین محدودیت من این است که در مناطق متنی کار نمی کند.
فریاد بزنید تا از طریق گفتگوی کنفرانس Una Kravets به نام Techson برای معرفی من به API POPOVER API استفاده کنید ، به نام کمتر Cruft ، Power More: از قدرت پلت فرم وب استفاده کنید.
API انتخاب
من می خواستم Popover من در هر کجا که کاربر انتخاب شده باشد ظاهر شود. این به من نیاز داشت:
- موقعیت متن انتخاب شده را بدانید
- گوش دادن به رویدادهایی که هنگام انتخاب متن اتفاق افتاد و انتخاب شد
من در پست وبلاگ Colby Fayock به نام How To Shiping Text Selected in React با API انتخابی روبرو شدم. در حالی که تمرکز کلبی روی قابلیت اشتراک گذاری متن بود ، پست وی من را با انتخاب API معرفی کرد – که می تواند به من کمک کند تا از طریق متن انتخاب شده ، پاپور خود را قرار دهم.
API انتخاب در زندگی می کند window.getSelection()
بشر وقتی این روش را صدا می کنید ، یک شی انتخاب را برمی گرداند که در مورد متنی که کاربر در صفحه انتخاب کرده است به شما می گوید.
GetAngeat (0)
از این شیء انتخاب ، می توانید تماس بگیرید getRangeAt(0)
برای اطلاع از دقیقاً از کجا انتخاب و پایان می یابد. این دو شماره به شما می دهد:
-
startOffset
– از کجا انتخاب شروع می شود -
endOffset
– جایی که انتخاب به پایان می رسد
در یک انتخاب ، هر شخصیت دارای یک شاخص است. برای متن “سلام ، جهان! خوش آمدید.” ، فهرست ها به این شکل هستند:
اگر کلمه “جهان” را انتخاب کنید ، پس startOffset
7 است (جایی که “W” آغاز می شود) و endOffset
12 است (درست بعد از “D”).
نکته جانبی: من آموخته ام که پارامتر 0 در GetRangeat (0) به مرورگر می گوید که انتخابی را که می خواهید در مورد آن انتخاب کنید. هنگامی که متن را انتخاب می کنید ، هر انتخاب در یک فهرست مختلف در یک آرایه ذخیره می شود. اکثر مرورگرها فقط به شما امکان می دهند یک قطعه متن را همزمان انتخاب کنید ، بنابراین فقط یک مورد در فهرست 0 خواهید داشت. اما مرورگرهایی مانند Firefox به شما امکان می دهند CTRL را برای انتخاب چندین قطعه متن نگه دارید. اگر سعی می کنید در مرورگرهایی که از انتخاب های متعدد پشتیبانی نمی کنند ، به شاخص های بیشتر از 0 دسترسی پیدا کنید ، خطایی دریافت خواهید کرد.
getBoundingClientRect ()
getRangeAt(0)
به شما دسترسی می دهد getBoundingClientRect()
بشر
getBoundingClientRect()
یک جعبه اندازه گیری را در اطراف متن انتخاب شده خود برمی گرداند. این موقعیت های بالا ، راست ، پایین و سمت چپ این جعبه را به شما می گوید ، به علاوه عرض و ارتفاع آن.
با این اندازه گیری ها ، می توانم پوپور خود را درست بالاتر از هر متنی که کاربر انتخاب می کند ، قرار دهم ، مانند این:
در حالی که این رویکرد برای اکثر عناصر HTML کار می کرد ، عناصر منطقه متن دسترسی محدود به API انتخاب را فراهم می کنند ، بنابراین من به یک روش جایگزین نیاز داشتم.
Div آینه دار
از طریق اردک لاستیکی با کلود ، من در مورد رویکرد Div Mirrored ، یک راه حل برای تعیین مختصات انتخاب در یک منطقه متن ، آموختم.
در اینجا نحوه عملکرد آن آورده شده است: یک تقسیم نامرئی ایجاد کنید که قسمت متن را پوشانده باشد ، حاوی همان محتوای و یک ظاهر طراحی شده باشد. هنگامی که کاربر متن را انتخاب می کند ، آنها در واقع با این بخش نامرئی به جای منطقه متن در زیر آن تعامل دارند. این امر به شما امکان می دهد ضمن حفظ آنچه به نظر می رسد و مانند یک متن متنی استاندارد برای کاربر است ، به API انتخاب کامل دسترسی پیدا کنید.
من اعتبار این تکنیک را در پست وبلاگ Jhey Thompkins “چگونه به: مکان نما متن؟” پیدا کردم ، که من را به آن معرفی کرد getComputedStyle()
روش این API سبک های CSS محاسبه شده از عناصر HTML را برمی گرداند و به توسعه دهندگان اجازه می دهد تا ظاهر منطقه متن را در قسمت پوشش با دقت مطابقت دهند.
اما دقیقاً مانند یک آینه واقعی ، همه چیز همیشه آن چیزی نیست که به نظر می رسد. مشابه هشدار در آینه های اتومبیل مبنی بر اینکه “اشیاء ممکن است نزدیک تر از آنچه ظاهر می شوند” ، Div آینه ما می تواند واقعیت را به روش های ظریف تحریف کند:
- متن می تواند در نقاط مختلف بین قسمت DIV و متن بسته شود
- مرورگرها از فاصله و رندر فونت متفاوت برخوردار هستند و باعث می شوند موقعیت های متن به طور غیر منتظره تغییر کند
چرا از بسته NPM استفاده نمی کنید؟
من چند بسته را امتحان کردم و فهمیدم که بیشتر این بسته ها با عناصر معمولی DOM خوب کار می کنند. با این حال ، آنها به دلیل همان محدودیت های اساسی که قبلاً بیان کردم با مناطق متنی مبارزه می کنند – دسترسی محدود به ارائه و موقعیت داخلی منطقه متن.
پایان
در حالی که مرورگرها در پشتیبانی از تعامل متن غنی ، مسیری طولانی را طی کرده اند ، کار با مناطق متن به طرز شگفت آور پیچیده است. من در مورد این API های مرورگر از یادگیری لذت بردم ، اما هنوز راه حلی پیدا نکردم که متناسب با مورد استفاده من باشد. شاید API های آینده وظایفی مانند پاپ های مبتنی بر انتخاب را ساده تر کنند.
اگر به روشی که من کاوش نکرده ام ، با سفارشی سازی منطقه متن مقابله کرده اید ، دوست دارم در مورد رویکردهای شما بشنوم.