This media is not supported in your browser
VIEW IN TELEGRAM
بهترین کدنویسی آن است که اصلاً نیازی به انجامش نباشد.
به همین دلیل من عاشق کانستراکتورها (Constructors) هستم. اما منظور ما از کانستراکتور اینجا، ساخت طرحبندیها و Layoutها است، نه ابزارهایی مثل Tilda.
امروز یک ابزار جدید پیدا کردم: FlexBox Labs
🔗https://flexboxlabs.netlify.app
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
به همین دلیل من عاشق کانستراکتورها (Constructors) هستم. اما منظور ما از کانستراکتور اینجا، ساخت طرحبندیها و Layoutها است، نه ابزارهایی مثل Tilda.
امروز یک ابزار جدید پیدا کردم: FlexBox Labs
🔗https://flexboxlabs.netlify.app
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👍4🔥1
اگر زمانی که موتور خودرو را روشن میکنیم، موتور سرد باشد، Cold Start رخ میدهد. در این حالت، دور موتور بیش از حد نرمال افزایش مییابد تا زمانی که موتور به دمای محیطی که در آن قرار دارد برسد. این کار باعث میشود موتور سریعتر به شرایط عملکردی مناسب خود برسد.
در دنیای نرمافزار، هوش مصنوعی و سرویسهای ابری نیز مفهوم مشابهی وجود دارد. «شروع سرد» (Cold Start) به وضعیتی گفته میشود که وقتی یک سرویس، مدل یا برنامه برای اولین بار اجرا میشود، باید همه چیز را از صفر بارگذاری کند. به همین دلیل، معمولاً در این مرحله زمان پاسخدهی طولانیتر از حالت عادی است.
در سرویسهای ابری (Cloud Services):
وقتی یک تابع یا کانتینر برای اولین بار اجرا میشود، سیستم باید محیط آن را آماده کند، کتابخانهها و وابستگیها را بارگذاری کند و سپس کد را اجرا کند. این زمان اولیه همان Cold Start است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
در دنیای نرمافزار، هوش مصنوعی و سرویسهای ابری نیز مفهوم مشابهی وجود دارد. «شروع سرد» (Cold Start) به وضعیتی گفته میشود که وقتی یک سرویس، مدل یا برنامه برای اولین بار اجرا میشود، باید همه چیز را از صفر بارگذاری کند. به همین دلیل، معمولاً در این مرحله زمان پاسخدهی طولانیتر از حالت عادی است.
در سرویسهای ابری (Cloud Services):
وقتی یک تابع یا کانتینر برای اولین بار اجرا میشود، سیستم باید محیط آن را آماده کند، کتابخانهها و وابستگیها را بارگذاری کند و سپس کد را اجرا کند. این زمان اولیه همان Cold Start است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤1
### مقادیر دوگانه در ویژگی display در CSS 🤔
ویژگی display در CSS تعیین میکند که عناصر چگونه در صفحه نمایش داده شوند. هنگامی که از مقادیر دوگانه استفاده میکنیم، میتوانیم دو نوع رفتار نمایش را برای یک عنصر ترکیب کنیم و در نتیجه انعطافپذیری بیشتری به دست آوریم.
#### مقادیر دوگانه چیست؟
🧩 مقدار نخست، رفتار اصلی عنصر را مشخص میکند (مانند *block*، *inline* یا *flex*).
🧩 مقدار دوم، این رفتار را تکمیل و اصلاح میکند.
بهعنوان نمونه، در حالت inline-block**، عنصر مانند یک عنصر درونخطی رفتار میکند، اما در عین حال میتوان برای آن ابعاد مشخص کرد، درست مانند یک عنصر بلوکی. 👍
```html
<div style="display: inline-block; width: 100px; height: 50px; background-color: lightblue;">بلوک</div>
```
#### نمونههای دیگر:
✔️ **inline-block:
⏺️ *inline* — عنصر در همان خط باقی میماند.
⏺️ *block* — امکان تعریف اندازهها فراهم است.
✔️ inline-flex:
⏺️ *inline* — ظرف (container) موجب شکستن خط نمیشود.
⏺️ *flex* — عناصر درون ظرف بر اساس قوانین فِلِکسباکس چیده میشوند.
---
### نتیجهگیری
مقادیر دوگانه در CSS باعث سادهتر شدن ساختار صفحه میشوند و امکان طراحی صفحات منعطفتر و واکنشگرا را با حداقل میزان کدنویسی فراهم میآورند. 💗
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
ویژگی display در CSS تعیین میکند که عناصر چگونه در صفحه نمایش داده شوند. هنگامی که از مقادیر دوگانه استفاده میکنیم، میتوانیم دو نوع رفتار نمایش را برای یک عنصر ترکیب کنیم و در نتیجه انعطافپذیری بیشتری به دست آوریم.
#### مقادیر دوگانه چیست؟
🧩 مقدار نخست، رفتار اصلی عنصر را مشخص میکند (مانند *block*، *inline* یا *flex*).
🧩 مقدار دوم، این رفتار را تکمیل و اصلاح میکند.
بهعنوان نمونه، در حالت inline-block**، عنصر مانند یک عنصر درونخطی رفتار میکند، اما در عین حال میتوان برای آن ابعاد مشخص کرد، درست مانند یک عنصر بلوکی. 👍
```html
<div style="display: inline-block; width: 100px; height: 50px; background-color: lightblue;">بلوک</div>
```
#### نمونههای دیگر:
✔️ **inline-block:
⏺️ *inline* — عنصر در همان خط باقی میماند.
⏺️ *block* — امکان تعریف اندازهها فراهم است.
✔️ inline-flex:
⏺️ *inline* — ظرف (container) موجب شکستن خط نمیشود.
⏺️ *flex* — عناصر درون ظرف بر اساس قوانین فِلِکسباکس چیده میشوند.
---
### نتیجهگیری
مقادیر دوگانه در CSS باعث سادهتر شدن ساختار صفحه میشوند و امکان طراحی صفحات منعطفتر و واکنشگرا را با حداقل میزان کدنویسی فراهم میآورند. 💗
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
بستهٔ @unpic/vue قابلیتهای قدرتمند و مدرن بهینهسازی تصویر را با حداقل پیکربندی به برنامههای Vue شما میآورد. با پشتیبانی درونی از بارگذاری تنبل، واکنشگرایی و انتخاب خودکار فرمت، هم در زمان توسعه صرفهجویی میشود و هم کارایی کلی بهطور چشمگیری بهبود پیدا میکند.
+پشتیبانی از تصاویر واکنشگرا با استفاده از srcset
+بارگذاری تنبل بهصورت پیشفرض
+انتخاب خودکار فرمت (برای نمونه WebP یا AVIF)
+سازگاری با سرویسهایی مانند Cloudinary، Imgix، Vercel، Sanity و بسیاری دیگر
🔗https://unpic.pics/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
+پشتیبانی از تصاویر واکنشگرا با استفاده از srcset
+بارگذاری تنبل بهصورت پیشفرض
+انتخاب خودکار فرمت (برای نمونه WebP یا AVIF)
+سازگاری با سرویسهایی مانند Cloudinary، Imgix، Vercel، Sanity و بسیاری دیگر
🔗https://unpic.pics/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
🔥2
### ویژگی
(منبع: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/))
این موضوع کمی پیچیده است و در مقاله اصلی حتی سختتر توضیح داده شده، اما این دانش روزی بهکار شما خواهد آمد.
احتمالاً دیدهاید که بعضی تصاویر با ویژگی
بارری پولارد این سوال را مطرح کرد و با صحبت با توسعهدهندگان مرورگرها به نکات جالبی رسید.
---
### مقادیر ویژگی
طبق مشخصات، این ویژگی سه مقدار دارد:
* sync → درخواست رمزگشایی همزمان تصویر
* async → درخواست رمزگشایی ناهمزمان تصویر
* auto → مرورگر خودش تصمیم میگیرد
---
### روند کار تصویر در مرورگر
تصاویر مراحل زیر را طی میکنند:
1. مرورگر
2. سپس یک فرآیند کمکی تصویر را رمزگشایی میکند (تبدیل بایتها به دادههای قابل رندر).
3. در نهایت تصویر در صفحه نمایش داده میشود.
نکته جالب این است که در صفحات استاتیک، این ویژگی تقریباً تأثیری ندارد، زیرا مرورگرها هوشمندانه تغییرات را جمعآوری کرده و به شکل chunks رندر میکنند و تصاویر در جریان اصلی رندر بلوکه نمیشوند.
* در Firefox بهصورت پیشفرض
* در Chrome پیشفرض
* در WebKit بیشتر مواقع
بنابراین مرورگرها هنوز روی یک رفتار پیشفرض توافق ندارند.
---
### تفاوت واقعی هنگام استفاده از JavaScript
در SPAها (برنامههای تکصفحهای) وقتی تصاویر توسط JS اضافه میشوند، تفاوت محسوس میشود:
* اگر داخل JS یک
* با sync → صفحه ممکن است کمی گیر کند زیرا مرورگر منتظر رمزگشایی تصویر میماند.
* با async → ابتدا پسزمینه قرمز نمایش داده میشود و بعد تصویر رندر میشود، اما ممکن است موقعیت چشمک زدن ایجاد شود.
* مرورگرهای مدرن تصاویر خارج از viewport را تا زمانی که به آنها اسکرول نشود، رمزگشایی نمیکنند تا حافظه اضافی مصرف نشود. اما اگر صفحه پر از تصویر باشد و کاربر کلید
---
### توصیهها
* اگر تصاویر را با JS بارگذاری میکنید، بهتر است از async استفاده کنید. این روش هم ناهمزمان است و هم قبل از رندر، تصویر آماده است.
*
* برای بهینهسازی Core Web Vitals، به ویژه LCP**، بهتر است مقادیر مختلف را امتحان کنید. هرچند intuitively به نظر میرسد `sync` بهتر باشد، اما مرورگرها هوشمند هستند و باید تست و مقایسه کنید.
* اگر روی بهینهسازی رمزگشایی تصاویر کار میکنید، یا سایتتان از قبل عالی است، یا بهتر است روی مسائل مفیدتری مثل **بارگذاری تنبل تصاویر و بهینهسازی خود تصاویر تمرکز کنید.
---
منبع اصلی: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/)
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
decoding در تگ <img> واقعاً چه کاری انجام میدهد؟(منبع: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/))
این موضوع کمی پیچیده است و در مقاله اصلی حتی سختتر توضیح داده شده، اما این دانش روزی بهکار شما خواهد آمد.
احتمالاً دیدهاید که بعضی تصاویر با ویژگی
decoding="async" اضافه میشوند. شاید خودتان هم طبق توصیههای مقالات بهینهسازی عملکرد چنین ویژگیای را استفاده کردهاید. اگر از کامپوننت Image در NextJS استفاده میکنید، بهصورت پیشفرض این ویژگی روی تصاویر فعال است. اما آیا واقعاً مهم است؟بارری پولارد این سوال را مطرح کرد و با صحبت با توسعهدهندگان مرورگرها به نکات جالبی رسید.
---
### مقادیر ویژگی
decodingطبق مشخصات، این ویژگی سه مقدار دارد:
* sync → درخواست رمزگشایی همزمان تصویر
* async → درخواست رمزگشایی ناهمزمان تصویر
* auto → مرورگر خودش تصمیم میگیرد
---
### روند کار تصویر در مرورگر
تصاویر مراحل زیر را طی میکنند:
1. مرورگر
<img src="..."> را میبیند و ابتدا تصویر را از شبکه یا کش دریافت میکند.2. سپس یک فرآیند کمکی تصویر را رمزگشایی میکند (تبدیل بایتها به دادههای قابل رندر).
3. در نهایت تصویر در صفحه نمایش داده میشود.
نکته جالب این است که در صفحات استاتیک، این ویژگی تقریباً تأثیری ندارد، زیرا مرورگرها هوشمندانه تغییرات را جمعآوری کرده و به شکل chunks رندر میکنند و تصاویر در جریان اصلی رندر بلوکه نمیشوند.
* در Firefox بهصورت پیشفرض
async است.* در Chrome پیشفرض
sync است.* در WebKit بیشتر مواقع
sync است اما در بعضی استثناها async است.بنابراین مرورگرها هنوز روی یک رفتار پیشفرض توافق ندارند.
---
### تفاوت واقعی هنگام استفاده از JavaScript
در SPAها (برنامههای تکصفحهای) وقتی تصاویر توسط JS اضافه میشوند، تفاوت محسوس میشود:
* اگر داخل JS یک
div با پسزمینه قرمز بسازید و بعد یک تصویر بزرگ داخل آن اضافه کنید:* با sync → صفحه ممکن است کمی گیر کند زیرا مرورگر منتظر رمزگشایی تصویر میماند.
* با async → ابتدا پسزمینه قرمز نمایش داده میشود و بعد تصویر رندر میشود، اما ممکن است موقعیت چشمک زدن ایجاد شود.
* مرورگرهای مدرن تصاویر خارج از viewport را تا زمانی که به آنها اسکرول نشود، رمزگشایی نمیکنند تا حافظه اضافی مصرف نشود. اما اگر صفحه پر از تصویر باشد و کاربر کلید
End را بزند، ممکن است صفحه کمی گیر کند.---
### توصیهها
* اگر تصاویر را با JS بارگذاری میکنید، بهتر است از async استفاده کنید. این روش هم ناهمزمان است و هم قبل از رندر، تصویر آماده است.
*
async مناسب زمانی است که متن صفحه مهمتر از تصاویر است. در این حالت دو مرحله رندر داریم ولی متن سریعتر نمایش داده میشود.* برای بهینهسازی Core Web Vitals، به ویژه LCP**، بهتر است مقادیر مختلف را امتحان کنید. هرچند intuitively به نظر میرسد `sync` بهتر باشد، اما مرورگرها هوشمند هستند و باید تست و مقایسه کنید.
* اگر روی بهینهسازی رمزگشایی تصاویر کار میکنید، یا سایتتان از قبل عالی است، یا بهتر است روی مسائل مفیدتری مثل **بارگذاری تنبل تصاویر و بهینهسازی خود تصاویر تمرکز کنید.
---
منبع اصلی: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/)
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
Tunetheweb
What does the image decoding attribute actually do?
An in-depth look at the decoding attribute and how it affects web performance differently when using sync, async or not at all
❤2
در media queries نمیتوان از ویژگیهای CSS (@property) استفاده کرد، اما راههای جایگزینی وجود دارد از طریق container queries.
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
@property --inline-size-s {
syntax: "<length-percentage>";
inherits: true;
initial-value: ۱۰۰vi;
}
:root {
--breakpoint-s: ۴۸em;
--inline-size-s: min(var(--breakpoint-s), ۱۰۰vi);
}
body {
background-color: var(--bg-color);
--bg-color: oklch(۰.۹۴ ۰.۰۱ ۹۹);
@container style(--inline-size-s: var(--breakpoint-s)) {
--bg-color: oklch(۰.۸۷ ۰.۲۱ ۹۵.۸۲);
}
}#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
در عنصر <link rel="stylesheet"> میتوان ویژگی media را با یک عبارت مشابه آنچه در دستور @media استفاده میشود، تعیین کرد. مرورگر این عبارت رسانهای را با محیط فعلی تطبیق میدهد و نتیجهی آن بر نحوهی بارگذاری فایل استایل تأثیر میگذارد:
اگر شرط برقرار نباشد، فایل سبک با اولویت پایین و بهصورت ناهمزمان (بدون مسدود کردن فرآیند رندر) بارگذاری میشود، اما خود استایلها اعمال نخواهند شد.
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
<link
rel="stylesheet"
href="mobile.css"
media="(width < 600px)"
>
اگر شرط برقرار نباشد، فایل سبک با اولویت پایین و بهصورت ناهمزمان (بدون مسدود کردن فرآیند رندر) بارگذاری میشود، اما خود استایلها اعمال نخواهند شد.
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍3
بارگذاری فایلهای CSS در لایههای مجزا با استفاده از @import
مرورگر فایل utils.css را بارگذاری کرده و آن را در لایهای با نام utils قرار میدهد. این کار امکان کنترل ترتیب و اولویت آبشاریِ سبکهای این فایل نسبت به سایر لایهها را فراهم میآورد — یعنی میتوان اولویت آن را نسبت به فایلهای دیگر بالا برد یا پایین آورد.
با این حال، دستور
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
<style>
@import url('utils.css') layer(utils);
</style>
مرورگر فایل utils.css را بارگذاری کرده و آن را در لایهای با نام utils قرار میدهد. این کار امکان کنترل ترتیب و اولویت آبشاریِ سبکهای این فایل نسبت به سایر لایهها را فراهم میآورد — یعنی میتوان اولویت آن را نسبت به فایلهای دیگر بالا برد یا پایین آورد.
با این حال، دستور
@import از نظر کارایی انتخاب مطلوبی نیست و معمولاً توصیه میشود از آن پرهیز شود، زیرا وجود `@import`های تودرتو موجب میشود فایلهای سبک بهصورت متوالی و نه موازی بارگذاری شوند.#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
همهی فضاهای ذخیرهسازی مثل هم نیستند؛ با «سطلهای ذخیرهسازی» آشنا شوید
وقتی حافظهی دستگاه کاربر تمام میشود، دادههایی که با APIهایی مثل IndexedDB یا localStorage ذخیره شدهاند، بیاختیار حذف میشوند و کاربر نمیتواند جلویش را بگیرد. راه فعلی برای «دائمی» کردن این است که متد persist() را صدا بزنیم:
این روش «همه یا هیچ» است؛ نمیتوانید بگویید «فقط فلان داده مهم بماند». همهچیز در یک سطل ذخیرهسازی واحد میریزد.
API سطلهای ذخیرهسازی (Storage Buckets API)
ایدهی اصلی این است که سایتها بتوانند چند سطل (bucket) جداگانه بسازند؛ مرورگر میتواند هر سطل را مستقل از بقیه حذف کند. بدینترتیب توسعهدهنده میگوید «اگر مجبور به پاککردن شدی، اول سراغ این سطل برو، آن یکی را آخرش بگذار».
مثال عملی
فرض کنید یک برنامهی ایمیل داریم. از دست رفتن پیشنویسهای ذخیرهنشده روی دستگاه فاجعه است، اما اگر ایمیلهای قدیمیِ Inbox حذف شوند چندان مهم نیست، چون روی سرور باقیماندهاند.
چطور از API استفاده کنیم؟
دو پارامتر اختیاری میتوان داد:
persisted: false (پیشفرض) یا true
durability: 'relaxed' (پیشفرض) یا 'strict'
'strict': در برابر قطع برق ایمنتر است؛ ممکن است سرعت نوشتن کم شود، باتری بیشتر مصرف کند و عمر حافظهی فیزیکی کوتاهتر شود.
'relaxed': در صورت قطع برق ممکن است چند ثانیهی آخر اطلاعات از بین برود؛ در عوض نوشتن سریعتر و دوام باتری و حافظهی بیشتر است.
دسترسی به APIهای حافظه از داخل هر سطل
هر سطل به همان APIهای همیشگی (IndexedDB، Cache، File و …) وصل است؛ فقط ورودی از طریق خود سطل انجام میشود.
🔗https://developer.chrome.com/docs/web-platform/storage-buckets
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
وقتی حافظهی دستگاه کاربر تمام میشود، دادههایی که با APIهایی مثل IndexedDB یا localStorage ذخیره شدهاند، بیاختیار حذف میشوند و کاربر نمیتواند جلویش را بگیرد. راه فعلی برای «دائمی» کردن این است که متد persist() را صدا بزنیم:
const persisted = await navigator.storage.persist();
if (persisted) {
/* حافظه فقط با دستور مستقیم کاربر پاک میشود. */
}
این روش «همه یا هیچ» است؛ نمیتوانید بگویید «فقط فلان داده مهم بماند». همهچیز در یک سطل ذخیرهسازی واحد میریزد.
API سطلهای ذخیرهسازی (Storage Buckets API)
ایدهی اصلی این است که سایتها بتوانند چند سطل (bucket) جداگانه بسازند؛ مرورگر میتواند هر سطل را مستقل از بقیه حذف کند. بدینترتیب توسعهدهنده میگوید «اگر مجبور به پاککردن شدی، اول سراغ این سطل برو، آن یکی را آخرش بگذار».
مثال عملی
فرض کنید یک برنامهی ایمیل داریم. از دست رفتن پیشنویسهای ذخیرهنشده روی دستگاه فاجعه است، اما اگر ایمیلهای قدیمیِ Inbox حذف شوند چندان مهم نیست، چون روی سرور باقیماندهاند.
چطور از API استفاده کنیم؟
// سطل پیشنویسها که فقط روی کلاینت است
const draftsBucket = await navigator.storageBuckets.open('drafts', {
durability: 'strict', // یا 'relaxed'
persisted: true, // یا false
});
دو پارامتر اختیاری میتوان داد:
persisted: false (پیشفرض) یا true
durability: 'relaxed' (پیشفرض) یا 'strict'
'strict': در برابر قطع برق ایمنتر است؛ ممکن است سرعت نوشتن کم شود، باتری بیشتر مصرف کند و عمر حافظهی فیزیکی کوتاهتر شود.
'relaxed': در صورت قطع برق ممکن است چند ثانیهی آخر اطلاعات از بین برود؛ در عوض نوشتن سریعتر و دوام باتری و حافظهی بیشتر است.
دسترسی به APIهای حافظه از داخل هر سطل
هر سطل به همان APIهای همیشگی (IndexedDB، Cache، File و …) وصل است؛ فقط ورودی از طریق خود سطل انجام میشود.
const inboxDb = await new Promise((resolve, reject) => {
const request = inboxBucket.indexedDB.open('messages');
request.onupgradeneeded = () => { /* کد مهاجرت */ };
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});🔗https://developer.chrome.com/docs/web-platform/storage-buckets
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🎯 بارگذاری مشروط فایلهای CSS با استفاده از @supports
دستور کاربردی دیگری که در این زمینه مطرح میشود، `@supports` است. با استفاده از آن میتوان برخی سبکها را تنها زمانی بارگذاری کرد که مرورگر از قابلیتهای خاص CSS پشتیبانی کند. این ویژگی ابزاری قدرتمند برای پیادهسازی بهبود تدریجی (Progressive Enhancement) به شمار میآید و به توسعهدهندگان کمک میکند تا تجربهی کاربری یکسانی را در مرورگرهای مختلف حفظ کنند.
در این مثال، مرورگر فایل `scroll-animations.css` را فقط در صورتی بارگذاری میکند که از ویژگی `animation-timeline: scroll()` پشتیبانی داشته باشد. این روش راهی تمیز و هوشمندانه برای استفادهی بهینه از قابلیتهای مدرن CSS است.
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
دستور کاربردی دیگری که در این زمینه مطرح میشود، `@supports` است. با استفاده از آن میتوان برخی سبکها را تنها زمانی بارگذاری کرد که مرورگر از قابلیتهای خاص CSS پشتیبانی کند. این ویژگی ابزاری قدرتمند برای پیادهسازی بهبود تدریجی (Progressive Enhancement) به شمار میآید و به توسعهدهندگان کمک میکند تا تجربهی کاربری یکسانی را در مرورگرهای مختلف حفظ کنند.
<style>
@import url('scroll-animations.css') supports(animation-timeline: scroll());
</style>
در این مثال، مرورگر فایل `scroll-animations.css` را فقط در صورتی بارگذاری میکند که از ویژگی `animation-timeline: scroll()` پشتیبانی داشته باشد. این روش راهی تمیز و هوشمندانه برای استفادهی بهینه از قابلیتهای مدرن CSS است.
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
کار با dispatchEvent در جاوااسکریپت 👨🏫
متد dispatchEvent در جاوااسکریپت این امکان را میدهد که رویدادها را بهصورت برنامهنویسی برای عناصر ارسال کرد؛ در نتیجه، هندلرهای رویداد همانطور فعال میشوند که گویی کاربر آن را رقم زده است.
📚 اصول استفاده
برای ارسال یک رویداد باید:
✔️ رویداد را بسازید؛
✔️ آن را با dispatchEvent ارسال کنید.
حالا اگر روی دکمهای هندلر رویداد click تعریف شده باشد، اجرا میشود، درست همانند زمانی که کاربر واقعاً کلیک کرده باشد. 👍
📚 رویدادهای همراه با داده
اگر لازم است دادههای اضافی همراه رویداد ارسال شود، از CustomEvent استفاده میکنیم؛ رویدادی ویژه که امکان انتقال دادهها را از طریق ویژگی detail فراهم میکند.
✔️ detail: شیئی است که هر دادهای را که بخواهید میتواند در خود جای دهد؛
✔️ bubbles (اختیاری): رویداد میتواند در درخت DOM به سمت بالا «بجهد»؛
✔️ cancelable (اختیاری): اجازه میدهد رفتار پیشفرض رویداد لغو شود.
📚 چرا به این ابزار نیاز داریم؟
⏺️ میتوان در هر لحظهای رویداد را بهراحتی ارسال کرد؛
⏺️ با CustomEvent هر دادهای را میان اجزا رد و بدل کرد؛
⏺️ برای تست یا شبیهسازی اعمال کاربر روی صفحه بسیار کارآمد است.
در مجموع، این ابزار برای ساخت رابطهایی پویا و انعطافپذیر بینظیر است؛ از آن بهره بگیرید تا رویدادها را مدیریت کرده و دادهها را میان عناصر صفحه جابهجا کنید. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
متد dispatchEvent در جاوااسکریپت این امکان را میدهد که رویدادها را بهصورت برنامهنویسی برای عناصر ارسال کرد؛ در نتیجه، هندلرهای رویداد همانطور فعال میشوند که گویی کاربر آن را رقم زده است.
📚 اصول استفاده
برای ارسال یک رویداد باید:
✔️ رویداد را بسازید؛
✔️ آن را با dispatchEvent ارسال کنید.
const button = document.querySelector('button');
const event = new Event('click'); // ساخت رویداد
button.dispatchEvent(event); // ارسال رویدادحالا اگر روی دکمهای هندلر رویداد click تعریف شده باشد، اجرا میشود، درست همانند زمانی که کاربر واقعاً کلیک کرده باشد. 👍
📚 رویدادهای همراه با داده
اگر لازم است دادههای اضافی همراه رویداد ارسال شود، از CustomEvent استفاده میکنیم؛ رویدادی ویژه که امکان انتقال دادهها را از طریق ویژگی detail فراهم میکند.
const customEvent = new CustomEvent('dataChanged', {
detail: { value: 'متن جدید' },
bubbles: true, // رویداد در DOM به سمت بالا میجهد
cancelable: true // امکان لغل رفتار پیشفرض وجود دارد
});✔️ detail: شیئی است که هر دادهای را که بخواهید میتواند در خود جای دهد؛
✔️ bubbles (اختیاری): رویداد میتواند در درخت DOM به سمت بالا «بجهد»؛
✔️ cancelable (اختیاری): اجازه میدهد رفتار پیشفرض رویداد لغو شود.
📚 چرا به این ابزار نیاز داریم؟
⏺️ میتوان در هر لحظهای رویداد را بهراحتی ارسال کرد؛
⏺️ با CustomEvent هر دادهای را میان اجزا رد و بدل کرد؛
⏺️ برای تست یا شبیهسازی اعمال کاربر روی صفحه بسیار کارآمد است.
در مجموع، این ابزار برای ساخت رابطهایی پویا و انعطافپذیر بینظیر است؛ از آن بهره بگیرید تا رویدادها را مدیریت کرده و دادهها را میان عناصر صفحه جابهجا کنید. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍3
Vue Bits گنجینهای بزرگ از اجزای رابط کاربری متحرک VueJS است که طراحی شده تا به وبسایتهایتان جان تازهای ببخشد. انیمیشنهای خیرهکننده، کامپوننتهای متنوع، پسزمینههای خلاقانه و امکاناتی منحصربهفرد را در اختیارتان میگذارد — و همهی اینها کاملاً رایگاناند!
هر کامپوننت با گزینههای شخصیسازی بهصورت prop همراه شده تا بتوانید در سریعترین زمان نتیجهی دلخواهتان را بگیرید.
ویژگیهای کلیدی
بیش از نود کامپوننت (انیمیشن متن، انیمیشن، کامپوننت و پسزمینه) که هر هفته افزوده میشود
کمترین وابستگیها و امکان تنظیم کامل همهی اجزا از طریق prop
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
هر کامپوننت با گزینههای شخصیسازی بهصورت prop همراه شده تا بتوانید در سریعترین زمان نتیجهی دلخواهتان را بگیرید.
ویژگیهای کلیدی
بیش از نود کامپوننت (انیمیشن متن، انیمیشن، کامپوننت و پسزمینه) که هر هفته افزوده میشود
کمترین وابستگیها و امکان تنظیم کامل همهی اجزا از طریق prop
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
🔥1
موارد استفاده از <datalist> 🎨
عنصر <datalist> اغلب نادیده گرفته میشود، در حالی که قابلیتهای بسیار مفیدی دارد. 😔
با کمک این تگ میتوان فهرستی از گزینههای از پیش تعریفشده را در اختیار کاربر گذاشت تا از میان آنها انتخاب کند، بدون آنکه از وارد کردن مقدار دلخواه خود بازداشته شود.
این ویژگی زمانی ایدئال است که بخواهیم گزینههای رایج یا پرکاربرد را پیشنهاد دهیم، اما کاربر را به انتخاب آنها مجبور نکنیم.
📚 برای استفاده از <datalist> باید چند گام ساده را انجام داد:
✔️ ایجاد عنصر <datalist> با یک شناسهی منحصربهفرد؛
✔️ افزودن عناصر <option> درون <datalist> برای نمایش گزینههای قابل انتخاب؛
✔️ درون فیلد ورودی (<input>)، افزودن ویژگی list که مقدار آن باید با شناسهی عنصر <datalist> یکسان باشد.
نمونه:
گذشته از فیلدهای متنی، میتوان از <datalist> برای انتخاب رنگ نیز استفاده کرد. مرورگرها یک انتخابگر رنگ استاندارد در اختیار کاربر قرار میدهند که امکان انتخاب از میان رنگهای پیشنهادی را فراهم میکند.
کاربر میتواند یکی از رنگهای ارائهشده را انتخاب کند یا رنگ دلخواه خود را وارد نماید، و این انعطافپذیری باعث میشود روند انتخاب سادهتر و کاربرپسندتر شود. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
عنصر <datalist> اغلب نادیده گرفته میشود، در حالی که قابلیتهای بسیار مفیدی دارد. 😔
با کمک این تگ میتوان فهرستی از گزینههای از پیش تعریفشده را در اختیار کاربر گذاشت تا از میان آنها انتخاب کند، بدون آنکه از وارد کردن مقدار دلخواه خود بازداشته شود.
این ویژگی زمانی ایدئال است که بخواهیم گزینههای رایج یا پرکاربرد را پیشنهاد دهیم، اما کاربر را به انتخاب آنها مجبور نکنیم.
📚 برای استفاده از <datalist> باید چند گام ساده را انجام داد:
✔️ ایجاد عنصر <datalist> با یک شناسهی منحصربهفرد؛
✔️ افزودن عناصر <option> درون <datalist> برای نمایش گزینههای قابل انتخاب؛
✔️ درون فیلد ورودی (<input>)، افزودن ویژگی list که مقدار آن باید با شناسهی عنصر <datalist> یکسان باشد.
نمونه:
<label for="browsers">مرورگر را انتخاب کنید:</label>
<input list="browser-list" name="browsers" id="browsers">
<datalist id="browser-list">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
</datalist>
گذشته از فیلدهای متنی، میتوان از <datalist> برای انتخاب رنگ نیز استفاده کرد. مرورگرها یک انتخابگر رنگ استاندارد در اختیار کاربر قرار میدهند که امکان انتخاب از میان رنگهای پیشنهادی را فراهم میکند.
کاربر میتواند یکی از رنگهای ارائهشده را انتخاب کند یا رنگ دلخواه خود را وارد نماید، و این انعطافپذیری باعث میشود روند انتخاب سادهتر و کاربرپسندتر شود. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
چگونه باید پارامترها را بهدرستی در نشانی اینترنتی (URL) ارسال کرد؟ 🤔
هنگام ارسال پارامترها از طریق نشانی اینترنتی، بسیار مهم است که آنها را بهدرستی کُدگذاری کنیم. این کار باعث میشود درخواستها بهدرستی اجرا شوند و دادهها دچار اعوجاج نشوند. در JavaScript چند تابع مفید برای این کار وجود دارد:
---
### ۱️⃣ encodeURIComponent()
از این تابع برای کُدگذاری مقدار پارامترها در نشانی اینترنتی استفاده میشود. این تابع تضمین میکند که همهٔ نویسههای خاص (مانند فاصله، علامت &، علامت =، یا /) به معادلهای ایمن درصدیشان تبدیل شوند.
نمونه:
➡️ همیشه زمانی که مقدار پارامترها (مثل نام یا شهر) را کُدگذاری میکنید از
---
### ۲️⃣ encodeURI()
از این تابع برای کُدگذاری کل نشانی اینترنتی استفاده میشود، اما نویسههایی مانند ?, &, = و / را که بخشی از ساختار درخواست هستند، دستنخورده باقی میگذارد. این روش زمانی مفید است که میخواهید کل URL را کُدگذاری کنید، اما نمیخواهید جداکنندههای پارامترها تغییر کنند.
نمونه:
➡️ از
---
### ۳️⃣ URLSearchParams
این شیء برای کار آسانتر با پارامترهای URL طراحی شده است. بهطور خودکار مقادیر پارامترها را کُدگذاری میکند و متدهایی برای افزودن، حذف یا تغییر آنها در اختیار میگذارد که کار با دادههای پویا را سادهتر میکند.
---
### در نتیجه:
✔️
✔️
✔️
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
هنگام ارسال پارامترها از طریق نشانی اینترنتی، بسیار مهم است که آنها را بهدرستی کُدگذاری کنیم. این کار باعث میشود درخواستها بهدرستی اجرا شوند و دادهها دچار اعوجاج نشوند. در JavaScript چند تابع مفید برای این کار وجود دارد:
encodeURIComponent()`، `encodeURI() و URLSearchParams. بیایید ببینیم هرکدام چه کاری انجام میدهند و در چه شرایطی بهتر است از آنها استفاده شود. 😁---
### ۱️⃣ encodeURIComponent()
از این تابع برای کُدگذاری مقدار پارامترها در نشانی اینترنتی استفاده میشود. این تابع تضمین میکند که همهٔ نویسههای خاص (مانند فاصله، علامت &، علامت =، یا /) به معادلهای ایمن درصدیشان تبدیل شوند.
نمونه:
const name = "Katerina & Pro Frontend";
const encodedName = encodeURIComponent(name);
console.log(encodedName); // Katerina%20%26%20Pro%20Frontend
➡️ همیشه زمانی که مقدار پارامترها (مثل نام یا شهر) را کُدگذاری میکنید از
encodeURIComponent() استفاده کنید تا از تفسیر نادرست نویسههایی مانند فاصله یا علامت & جلوگیری شود.---
### ۲️⃣ encodeURI()
از این تابع برای کُدگذاری کل نشانی اینترنتی استفاده میشود، اما نویسههایی مانند ?, &, = و / را که بخشی از ساختار درخواست هستند، دستنخورده باقی میگذارد. این روش زمانی مفید است که میخواهید کل URL را کُدگذاری کنید، اما نمیخواهید جداکنندههای پارامترها تغییر کنند.
نمونه:
const url = "https://example.com/search?channel=Katerina | Pro Frontend";
const encodedUrl = encodeURI(url);
console.log(encodedUrl); // https://example.com/search?channel=Katerina%20%7C%20Pro%20Frontend
➡️ از
encodeURI() برای کُدگذاری کل URL (هم مسیر و هم پارامترها) استفاده کنید، در حالی که ساختار کلی پرسوجو را حفظ میکنید.---
### ۳️⃣ URLSearchParams
این شیء برای کار آسانتر با پارامترهای URL طراحی شده است. بهطور خودکار مقادیر پارامترها را کُدگذاری میکند و متدهایی برای افزودن، حذف یا تغییر آنها در اختیار میگذارد که کار با دادههای پویا را سادهتر میکند.
const params = new URLSearchParams();
params.append('name', 'John Doe');
console.log(params.toString()); // 'name=John+Doe' —
---
### در نتیجه:
✔️
encodeURIComponent() — برای کُدگذاری مقادیر پارامترها (مانند name=Katerina & Pro Frontend)✔️
encodeURI() — برای کُدگذاری کل نشانی اینترنتی همراه با ساختار پرسوجو✔️
URLSearchParams — برای افزودن، ویرایش و مدیریت آسان پارامترهای URL#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
⚜️عزیز خدا ذلیل نمیشود
💚سالروز ولادت حضرت زینب(س)
🔗https://www.youtube.com/watch?v=pg9wdMnPfcg
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
💚سالروز ولادت حضرت زینب(س)
🔗https://www.youtube.com/watch?v=pg9wdMnPfcg
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
❤9👎2🙏1
آشنایی با
این ویژگی رشتهای است که توسط شیء
به کمک آن میتوان وبسایت را متناسب با مرورگر یا دستگاه خاصی تنظیم و بهینه کرد. 😁
---
### 🔹 نمونهٔ رشته:
---
### اجزای اصلی رشتهٔ
⏺️ Mozilla/5.0 — برچسب تاریخی؛
⏺️ Macintosh; Intel Mac OS X 10_15_7 — اطلاعات مربوط به سیستمعامل؛
⏺️ AppleWebKit/537.36 — موتور رندر مرورگر؛
⏺️ Chrome/141.0.0.0 — نسخهٔ مرورگر؛
⏺️ Safari/537.36 — اجزای تکمیلی.
---
### 🎯 چرا این اطلاعات مفید است؟
✔️ تشخیص دستگاه و پلتفرم: میتوان فهمید کاربر از موبایل، تبلت یا رایانهٔ شخصی استفاده میکند.
✔️ سازگاری: دانستن نوع مرورگر کمک میکند سایت با ویژگیها و محدودیتهای آن تطبیق یابد.
✔️ طراحی واکنشگرا: نمایش درست و بهینهٔ سایت روی دستگاههای گوناگون را ممکن میسازد.
---
### 💡 نمونهٔ استفاده از
---
### ⚠️ نکات مهم:
✔️ قابل تغییر بودن رشته: کاربران میتوانند با افزونهها مقدار
✔️ دقت پایین اطلاعات: برخی مرورگرها خود را بهجای مرورگر دیگر معرفی میکنند.
برای نتایج قابلاعتمادتر، بهتر است بهجای تکیه بر
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
navigator.userAgent 🧐این ویژگی رشتهای است که توسط شیء
navigator برگردانده میشود و شامل اطلاعاتی دربارهٔ مرورگر، سیستمعامل و دستگاه کاربر است.به کمک آن میتوان وبسایت را متناسب با مرورگر یا دستگاه خاصی تنظیم و بهینه کرد. 😁
---
### 🔹 نمونهٔ رشته:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
---
### اجزای اصلی رشتهٔ
userAgent:⏺️ Mozilla/5.0 — برچسب تاریخی؛
⏺️ Macintosh; Intel Mac OS X 10_15_7 — اطلاعات مربوط به سیستمعامل؛
⏺️ AppleWebKit/537.36 — موتور رندر مرورگر؛
⏺️ Chrome/141.0.0.0 — نسخهٔ مرورگر؛
⏺️ Safari/537.36 — اجزای تکمیلی.
---
### 🎯 چرا این اطلاعات مفید است؟
✔️ تشخیص دستگاه و پلتفرم: میتوان فهمید کاربر از موبایل، تبلت یا رایانهٔ شخصی استفاده میکند.
✔️ سازگاری: دانستن نوع مرورگر کمک میکند سایت با ویژگیها و محدودیتهای آن تطبیق یابد.
✔️ طراحی واکنشگرا: نمایش درست و بهینهٔ سایت روی دستگاههای گوناگون را ممکن میسازد.
---
### 💡 نمونهٔ استفاده از
userAgent:if (/Chrome/.test(navigator.userAgent)) {
console.log("کاربر از مرورگر Chrome استفاده میکند");
}---
### ⚠️ نکات مهم:
✔️ قابل تغییر بودن رشته: کاربران میتوانند با افزونهها مقدار
userAgent را تغییر دهند.✔️ دقت پایین اطلاعات: برخی مرورگرها خود را بهجای مرورگر دیگر معرفی میکنند.
برای نتایج قابلاعتمادتر، بهتر است بهجای تکیه بر
userAgent از روش feature detection (شناسایی قابلیتها) استفاده کنید — که در پست بعدی دربارهاش صحبت خواهیم کرد. 😉#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2🔥1
گاهی بهنظر میرسد که فهمیدن وضعیت کلیدهای ترکیبی مانند Shift**، **Control**، **Alt یا Meta کار پیچیدهای است. 🙈
«اصلاً چطور باید این کار را انجام داد؟ آیا باید هر کلید را جداگانه بررسی کنیم؟» 🤔
نگران نباشید — راهحل وجود دارد و بسیار سادهتر از چیزی است که تصور میکنید! تنها چیزی که نیاز دارید، متد `getModifierState()` در جاوااسکریپت است که در رویدادهای صفحهکلید در دسترس میباشد.
این متد به شما اجازه میدهد بهراحتی بفهمید آیا یک کلید ترکیبی (مثلاً Shift یا Ctrl یا Alt) در لحظهٔ وقوع رویداد فشرده شده است یا نه.
---
### 💡 نمونهٔ استفاده:
متد
---
### 🎯 مثال کاربردی
فرض کنید میخواهیم از رفتار پیشفرض مرورگر هنگام فشردن ترکیب Ctrl + S (ذخیرهٔ صفحه) جلوگیری کنیم:
---
### ✅ نتیجه
با استفاده از تنها چند خط کد و متد **
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
«اصلاً چطور باید این کار را انجام داد؟ آیا باید هر کلید را جداگانه بررسی کنیم؟» 🤔
نگران نباشید — راهحل وجود دارد و بسیار سادهتر از چیزی است که تصور میکنید! تنها چیزی که نیاز دارید، متد `getModifierState()` در جاوااسکریپت است که در رویدادهای صفحهکلید در دسترس میباشد.
این متد به شما اجازه میدهد بهراحتی بفهمید آیا یک کلید ترکیبی (مثلاً Shift یا Ctrl یا Alt) در لحظهٔ وقوع رویداد فشرده شده است یا نه.
---
### 💡 نمونهٔ استفاده:
document.addEventListener('keydown', function(event) {
if (event.getModifierState('Shift')) {
console.log('کلید Shift فشرده شده است!');
}
if (event.getModifierState('Control')) {
console.log('کلید Control فشرده شده است!');
}
});متد
getModifierState() مقدار true برمیگرداند اگر کلید ترکیبی در آن لحظه فشرده شده باشد، و در غیر این صورت false. به همین سادگی! 😁---
### 🎯 مثال کاربردی
فرض کنید میخواهیم از رفتار پیشفرض مرورگر هنگام فشردن ترکیب Ctrl + S (ذخیرهٔ صفحه) جلوگیری کنیم:
document.addEventListener('keydown', function(event) {
if (event.getModifierState('Control') && event.key === 's') {
event.preventDefault(); // جلوگیری از عملکرد پیشفرض
console.log('عملیات ذخیرهسازی لغو شد!');
}
});---
### ✅ نتیجه
با استفاده از تنها چند خط کد و متد **
getModifierState()**، میتوانیم بهسادگی وضعیت کلیدهای ترکیبی موردنیاز را بررسی و کنترل کنیم. 👍#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript