جاوااسکریپت | JavaScript
494 subscribers
730 photos
183 videos
4 files
603 links
کانال @IR_javascript حاوی اطلاعات مفید در حوزه برنامه نویس فرانت که بصورت روزانه بروز می‌شود.
در این کانال شما به:
[1] مطالب تازه
[2] تحلیل‌های عمیق
[3] نکات آموزشی
[4] چالش
[5] ابزار و راهنمایی‌های کاربردی
دسترسی خواهید داشت.

🆔@IR_javascript
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
«چطور می‌توان یک آیکون را به فیلد ورودی اضافه کرد به‌طوری که تنها وقتی placeholder دیده می‌شود قابل مشاهده باشد و با وارد کردن متن ناپدید شود؟»

آیکون را داخل کانتینر label قرار دهید و سپس از pseudo-class :placeholder-shown روی فیلد ورودی استفاده کنید!

🔗https://codepen.io/alinaki/pen/xxMpgLK?editors=1100
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤3
اگر در پروژه Nuxt خود به پایگاه داده نیاز دارید (که معمولاً لازم است)، می‌توانید خیلی سریع آن را با استفاده از [Nuxt Hub](https://hub.nuxt.com) راه‌اندازی کنید.

این ابزار بر پایه Drizzle ORM کار می‌کند و از PostgreSQL**، **MySQL و SQLite پشتیبانی می‌کند.
همچنین، کار کردن به‌صورت محلی با Nuxt DevTools فوق‌العاده راحت است و تجربه توسعه را بسیار ساده می‌کند.

#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
‏ Proxy در JavaScript 👨‍🏫

‏Proxy یک واسطه بین کد و شیء است. این ابزار عملیات‌های روی شیء (خواندن، نوشتن، فراخوانی، پیمایش) را رهگیری می‌کند و به شما اجازه می‌دهد واکنش به این عملیات‌ها را تغییر دهید—از طریق مجموعه‌ای از handlerها یا همان تله‌ها (traps).


const p = new Proxy(target, handler);


### چطور کار می‌کند؟

1️⃣ ابتدا یک شیء واقعی target می‌سازید؛
2️⃣ سپس handler را تعریف می‌کنید—شیئی با توابع رهگیری‌کننده مانند get, set, apply و غیره؛
3️⃣ فراخوانی new Proxy(target, handler) یک پروکسی برمی‌گرداند: هر عملی روی شیء ابتدا تله مربوطه را فراخوانی می‌کند و تصمیم می‌گیرد که عمل استاندارد انجام شود (با استفاده از Reflect) یا تغییر کند؛

### مهم‌ترین تله‌ها:

* get — رهگیری خواندن یک ویژگی؛
* set — رهگیری نوشتن و امکان اعتبارسنجی یا بلاک کردن مقدار؛
* apply — رهگیری فراخوانی توابع؛
* ownKeys / getOwnPropertyDescriptor — تأثیر روی Object.keys و سریال‌سازی؛

### مثال عملی:

const obj = { name: "Katya" };
const p = new Proxy(obj, {
get(t, prop){
return prop in t ? Reflect.get(t, prop) : "—not found—";
},
set(t, prop, val){
if(prop === "age" && typeof val !== "number")
throw TypeError("age must be number");
return Reflect.set(t, prop, val);
}
});


این Proxy شیء را «هوشمند» می‌کند:

* هنگام خواندن ویژگی‌های موجود نبود، مقدار پیش‌فرض برمی‌گرداند؛
* هنگام نوشتن، بررسی می‌کند که age حتماً عدد باشد؛

### نکات مهم:

✔️ ویژگی‌های non-configurable را پنهان نکنید و به شیء غیرقابل گسترش فیلد اضافه نکنید—در غیر این صورت TypeError خواهید گرفت؛
const obj = {};
Object.defineProperty(obj, "fixed", {
value: 42,
configurable: false // غیرقابل تغییر
});

// این کار باعث خطا می‌شود
delete obj.fixed; // TypeError

✔️ برای ارجاع صحیح از Reflect.* (https://t.me/IR_javascript/1328) استفاده کنید (به‌ویژه برای getterها و پروتوتایپ‌ها)؛
✔️ از Proxy در حلقه‌های داغ (حلقه‌هایی که خیلی زیاد اجرا می‌شوند) اجتناب کنید—ممکن است کارایی کاهش یابد؛

### جمع‌بندی:

‏Proxy یک نقطه کنترل مرکزی برای تمام تعاملات با شیء فراهم می‌کند، اما استفاده از آن باید آگاهانه باشد. کاربردهای اصلی شامل:

* واکنش‌پذیری (reactivity)
* اعتبارسنجی
* ثبت لاگ (logging)
* ویژگی‌های مجازی

در اکثر کارهای روزمره، استفاده از Proxy ممکن است اضافه باشد، اما دانستن نحوه عملکرد آن مهم است: بهتر است ابزار را بشناسید و استفاده نکنید تا اینکه در کد با آن مواجه شوید و نفهمید چه اتفاقی می‌افتد. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
وقتی height: 100% روند چیدمان رو به هم ریخت 🙈

داشتم یه گرید ساده می‌ساختم: یه کانتینر با display: grid، ردیف‌ها با grid-template-rows: repeat(n, auto) و توی یه سلول، یه عنصری بود که براش height: 100% گذاشتم تا «قشنگ کش بیاد». تو کروم همه‌چیز عالی بود، ولی تو سافاری چیدمان به هم ریخت. ☹️

اولش فکر کردم: «خب، دیگه باگ مرورگره». ولی اگه یه کم عمیق‌تر بشیم، می‌بینیم که خبری از ماورا نیست: همه‌چیز به یه قانون CSS برمی‌گرده.

چه اتفاقی افتاد؟

‏height: 100% یعنی ۱۰۰٪ ارتفاع والد. و اینجا یه نکته کلیدی هست: ارتفاع درصدی فقط وقتی کار می‌کنه که والد یه ارتفاع مشخصی داشته باشه—منظور ارتفاعیه که بشه بدون در نظر گرفتن محتوا حسابش کرد.

خب، ما اینجا چی داریم؟ یه ردیف auto تو گرید که ارتفاعش دقیقاً موقع چیدمان و بر اساس محتوا تعیین می‌شه، پس از قبل ارتفاعش معلوم نیست. نتیجه می‌شه یه چرخه:

✔️ ردیف منتظر می‌مونه تا اندازه بچه‌اش معلوم بشه،
✔️ بچه می‌خواد ۱۰۰٪ ارتفاع ردیف رو بگیره،
✔️ ولی ردیف هنوز ارتفاع خودش رو نمی‌دونه—و همه‌چیز قفل می‌کنه.

➡️ درصد اصلاً نمیدونه باید از چی حساب کنه.

چرا تو مرورگرهای مختلف نتیجه فرق می‌کنه؟

موتورهای مختلف ممکن است این جور چرخه‌های اندازه‌گیری رو جور متفاوتی حل کنن.
توی بعضی‌ها نتیجه «به‌نظر» نرمال میاد، توی بعضی دیگه مشکل خودش رو نشون میده.

خلاصه اینکه، این باگ یه مرورگر خاص نیست. این تفاوت توی پیاده‌سازی الگوریتم محاسبه اندازه‌ها تو موقعیت‌های وابسته‌ست.

خب، چطور این مشکل رو حل کنیم؟ باید به درصد یه تکیه‌گاه بدیم—یعنی ارتفاع والد رو مشخص و معین کنیم. 👍

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
ترکیب بهینه برای LCP#
برای تصویری که LCP را تعیین می‌کند، دو بخش مهم وجود دارد: دانلود و رندرینگ.

ویژگی fetchpriority="high" اولویت دانلود را بالا می‌برد، اما فقط زمانی که پارسر تصویر را در HTML پیدا کند. اگر تصویر دیر در سند ظاهر شود — مثلاً داخل یک کامپوننت، یک کاروسل یا به‌عنوان پس‌زمینه CSS — ممکن است مرورگر آن را دیر کشف کند.

استفاده از <link rel="preload"> در <head> این مشکل را حل می‌کند: دانلود تصویر قبل از رسیدن پارسر به آن شروع می‌شود.

<!-- در <head>: دانلود را هرچه زودتر آغاز کنید -->
<link rel="preload" as="image" href="hero.jpg" fetchpriority="high" />


<!-- در <body>: با مشخصه‌های مناسب رندرینگ -->
<img
src="hero.jpg"
alt="Hero"
width="یک‌هزار و دویست"
height="ششصد"
loading="eager"
decoding="sync"
fetchpriority="high"
/>


اگر از srcset با فرمت‌های مدرن استفاده می‌کنید، تگ preload از imagesrcset و imagesizes پشتیبانی می‌کند تا مرورگر دقیقاً همان منبعی را پیش‌دانلود کند که استفاده خواهد شد:

<link
rel="preload"
as="image"
imagesrcset="hero-400.avif 400w, hero-800.avif 800w, hero-1600.avif 1600w"
imagesizes="(max-width: 600px) 100vw, 800px"
fetchpriority="high"
/>


و وقتی این روش با <picture>`، فرمت‌های مدرن و `srcset همراه با اندازه‌ها ترکیب شود، تصویر در تمام جنبه‌ها به‌خوبی سرو می‌شود.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
شبکه‌های توزیع محتوا CDN برای تصاویر: راهکار عملی
مدیریت دستی همهٔ فرمت‌ها و اندازه‌های مختلف تصاویر پرهزینه است. شبکه‌های توزیع محتوا برای تصاویر مانند Cloudinary**، **Imgix یا Cloudflare Images این کار سنگین را خودکار می‌کنند: آن‌ها بهترین فرمت را برای هر مرورگر از طریق هدر Accept تشخیص می‌دهند، اندازه‌های مورد نیاز را بر اساس تقاضا تولید می‌کنند و تصاویر بهینه‌شده را از نزدیک‌ترین سرور ارائه می‌دهند.

برای مثال در Cloudinary کافی است پارامترها را در URL اعلام کنید:

<img
src="https://res.cloudinary.com/demo/image/upload/f_auto,q_auto,w_800/photo.jpg"
width="هشتصد"
height="ششصد"
alt="Photo"
loading="lazy"
decoding="async"
/>


پارامتر f_auto فرمت مناسب را بین AVIF، WebP یا JPEG بر اساس مرورگر انتخاب می‌کند. q_auto کیفیت را به‌صورت خودکار تنظیم می‌کند. همهٔ این‌ها بدون مدیریت چند فایل مختلف انجام می‌شود.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
ویژگی‌های عملکرد: loading`، `decoding و fetchpriority
این سه ویژگی بیشترین تأثیر را روی معیارهای عملکرد دارند و متأسفانه اغلب اشتباه پیکربندی می‌شوند.

loading#
کنترل می‌کند که مرورگر چه زمانی تصویر را دانلود کند.

<!-- ❌ همه تصاویر را بلافاصله بارگذاری می‌کند، حتی آن‌هایی که خارج از نما هستند -->
<img src="photo.jpg" alt="Photo" />

<!-- ✅ بارگذاری تصاویر خارج از نما را به تعویق می‌اندازد -->
<img src="photo.jpg" alt="Photo" loading="lazy" />


ویژگی loading="lazy" برای هر تصویری که در نمای اولیه نیست ایمن است. برای تصاویری که در نما هستند — به‌ویژه تصویر LCP — از loading="eager" استفاده کنید (یا به‌سادگی این ویژگی را حذف کنید که پیش‌فرض مرورگر است).

width و height#
اعلام ابعاد در HTML به مرورگر اجازه می‌دهد تا قبل از دانلود تصویر، فضا را رزرو کند و از جابجایی طرح‌بندی که باعث جریمه CLS می‌شود جلوگیری کند.

<!-- ❌ بدون ابعاد: جابجایی طرح هنگام بارگذاری تصویر -->
<img src="photo.jpg" alt="Photo" />

<!-- ✅ با ابعاد: فضا از ابتدا رزرو شده است -->
<img src="photo.jpg" alt="Photo" width="800" height="600" />


این ابعاد لازم نیست با اندازهٔ نهایی نمایش مطابقت داشته باشند (CSS این کار را انجام می‌دهد). مهم آن است که نسبت تصویر صحیح باشد تا مرورگر فضای رزرو شده را به‌درستی محاسبه کند.

decoding#
به مرورگر می‌گوید آیا می‌تواند تصویر را به‌صورت غیرهمزمان رمزگشایی کند بدون اینکه رشتهٔ اصلی را مسدود کند.

<!-- برای تصاویر غیرضروری: بدون مسدود کردن رندرینگ -->
<img src="photo.jpg" alt="Photo" decoding="async" />

<!-- برای تصویر LCP: رمزگشایی همزمان -->
<img src="hero.jpg" alt="Hero" decoding="sync" />


ویژگی decoding="async" برای تصاویر ثانویه گزینهٔ خوبی است. برای تصویر LCP**، `decoding="sync"` تضمین می‌کند که تصویر بلافاصله پس از دانلود نمایش داده شود.

fetchpriority#

اولویت دانلود را در سیستم اولویت‌دهی مرورگر تنظیم می‌کند.

<!-- ❌ مرورگر ممکن است اولویت را درست تعیین نکند -->
<img src="hero.jpg" alt="Hero" />

<!-- ✅ به‌صورت صریح اعلام می‌کند که حیاتی است -->
<img src="hero.jpg" alt="Hero" fetchpriority="high" />

<!-- برای تصاویر غیرضروری که ممکن است زودتر از نیاز دانلود شوند -->
<img src="banner.jpg" alt="Banner" fetchpriority="low" />


ویژگی fetchpriority="high" مخصوصاً وقتی مفید است که تصویر LCP داخل یک کاروسل باشد یا دیر در HTML ظاهر شود و مرورگر به‌صورت خودکار آن را با اولویت بالا تشخیص ندهد.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
فرمت‌های مدرن با <picture>
فرمت‌های مدرن مانند AVIF یا WebP فشرده‌سازی بسیار بهتری نسبت به JPEG یا PNG ارائه می‌دهند. المان <picture> به شما اجازه می‌دهد چندین منبع تعریف کنید و مرورگر اولین فرمتی را که پشتیبانی می‌کند، بارگذاری می‌کند.

فرمت JPEG XL نیز وعدهٔ بهبود فشرده‌سازی قابل توجهی می‌دهد، اما پشتیبانی مرورگر بسیار محدود است: Chrome آن را در سال دو هزار و بیست و دو حذف کرد و تنها به‌صورت آزمایشی در Firefox و Safari در دسترس است. بنابراین، ترکیب AVIF + WebP در حال حاضر امن‌ترین انتخاب است.

<!-- ❌ فقط JPEG، بدون جایگزین -->
<img src="photo.jpg" alt="Photo" />

<!-- ✅ AVIF اول، WebP به‌عنوان جایگزین، JPEG به‌عنوان پایه -->
<picture>
<source type="image/avif" srcset="photo.avif" />
<source type="image/webp" srcset="photo.webp" />
<img src="photo.jpg" width="800" height="600" alt="Photo" />
</picture>


ترتیب اهمیت دارد: مرورگر از بالا به پایین بررسی می‌کند و اولین فرمتی را که قادر به رندر آن است استفاده می‌کند. AVIF بهترین فشرده‌سازی را ارائه می‌دهد اما پشتیبانی آن کمتر از WebP است. JPEG همچنان به‌عنوان جایگزین جهانی باقی می‌ماند.

ترکیب پاسخگویی و فرمت‌های مدرن
هر دو تکنیک می‌توانند با هم ترکیب شوند تا تصویر مناسب از نظر فرمت و اندازه ارائه شود:

<picture>
<source
type="image/avif"
srcset="photo-400.avif 400w, photo-800.avif 800w, photo-1600.avif 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
/>
<source
type="image/webp"
srcset="photo-400.webp 400w, photo-800.webp 800w, photo-1600.webp 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
/>
<img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
width="800"
height="600"
alt="Photo"
/>
</picture>


بله، مقدار کد بیشتر می‌شود، اما سرویس‌های CDN تصویر مانند Cloudinary این کار را به‌صورت خودکار انجام می‌دهند و از طریق هدر درخواست Accept فرمت بهینه را تشخیص می‌دهند، بدون اینکه نیاز باشد تمام این نسخه‌ها را دستی ایجاد کنید.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
تصاویر پاسخگو با srcset و `sizes`#
ویژگی `srcset` به شما اجازه می‌دهد چندین نسخه از یک تصویر تعریف کنید تا مرورگر مناسب‌ترین نسخه را بر اساس شرایط (چگالی صفحه، اندازهٔ viewport) انتخاب کند.

<!-- ❌ یک اندازه برای همه -->
<img src="hero.jpg" alt="Hero image" />

<!-- ✅ نسخه‌های مختلف برای چگالی‌ها و اندازه‌های متفاوت -->
<img
src="hero-800.jpg"
srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
width="800"
height="600"
alt="Hero image"
/>


ویژگی sizes به مرورگر می‌گوید که تصویر در هر نقطهٔ شکست (breakpoint) چه مقدار فضا در طرح‌بندی اشغال خواهد کرد. بدون `sizes`، مرورگر فرض می‌کند تصویر ۱۰۰٪ عرض صفحه را اشغال می‌کند و ممکن است نسخه‌ای بزرگ‌تر از نیاز دانلود شود.


🔗https://joanleon.dev/en/guia-practica-elemento-img/
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
کوتاه‌کردن انواع شناسه‌ها، مسیرهای فایل و نام فایل‌ها در وسط با css

🔗https://joanleon.dev/en/guia-practica-elemento-img/
#️⃣#code
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
🖤 سالروز شهادت امام حسن عسکری (ع)

⚫️ امام حسن عسکری (علیه السلام):
🖌 عبادت در زیاد انجام دادن نماز و روزه نیست ، بلکه عبادت با تفکّر و اندیشه در قدرت بی منتهای خداوند در امور مختلف می باشد.

📗 مستدرک الوسائل ، ج۱۱ ، ص۱۸۳

#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
❤7👎3
This media is not supported in your browser
VIEW IN TELEGRAM
ساده‌ترین روش برای غیرفعال کردن چندین عنصر فرم
می‌توانیم ویژگی disabled را روی عنصر <fieldset> قرار دهیم تا تمام عناصر فرمِ تو‌در‌توی آن به‌صورت خودکار غیرفعال شوند.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤1👍1
This media is not supported in your browser
VIEW IN TELEGRAM
بارگذاری تنبل ویدئوهای دارای پخش خودکار که پایین‌تر از اولین صفحه قرار دارند
ویژگی preload="none" را تنظیم کنید و ویژگی autoplay را از ویدئو حذف کنید تا ویدئو به‌صورت پیش‌فرض بارگذاری نشود. سپس با استفاده از API مربوط به Intersection Observer می‌توانیم زمانی که ویدئو در محدودهٔ قابل مشاهدهٔ صفحه قرار گرفت، پخش آن را آغاز کنیم.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1🙏1
This media is not supported in your browser
VIEW IN TELEGRAM
مجموعه‌ای جالب از کامپوننت‌های رابط کاربری با انیمیشن‌ها و جلوه‌های فیزیکی، با حال‌وهوای رابط‌های کاربری بازی‌ها.

این مجموعه هم برای طراحی رابط کاربری با استفاده از ابزارهای هوش مصنوعی مناسب است و هم برای پیاده‌سازی و کدنویسی دستی. چنین کامپوننت‌هایی کمک می‌کنند رابط کاربری زنده‌تر و تعاملی‌تر به نظر برسد ✌️


🔗feralui.dev
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
بیش از چهارصد و نود ابزار رایگان در یک سرویس تحت‌وب
این سرویس بدون نیاز به ثبت‌نام کار می‌کند و هیچ فایلی را روی سرور بارگذاری نمی‌کند؛ تمام داده‌ها به‌صورت محلی و در مرورگر پردازش می‌شوند.
در این مجموعه ابزارهایی برای کار با تصاویر، فایل‌های PDF، متن، طراحی، تبدیل فرمت، رمزنگاری و توسعه وجود دارد.
پیدا کردن بسیار کاربردی برای کسانی که برای زمان و حفظ حریم خصوصی خود ارزش قائل‌اند ✌️

🔗brevio.pro
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
پیشنهاد Await Dictionary برای ECMAScript در TC39 به مرحلهٔ سوم (Stage 3) رسید
در حال حاضر، Promise.all نتایج را به‌صورت یک آرایه برمی‌گرداند و مقادیر بر اساس موقعیت آن‌ها مشخص می‌شوند. روش جدید Promise.allKeyed امکان دریافت نتایج نام‌گذاری‌شده در قالب یک شیء را فراهم می‌کند؛ در نتیجه، کد خواناتر شده و کار با چندین Promise ساده‌تر می‌شود.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
از کلمهٔ کلیدی unset در CSS برای بازنشانی ویژگی‌ها استفاده کنید تا هر ویژگی به مقدار ارث‌بری‌شدهٔ خود برگردد؛ در صورت ارث‌بری، مقدار والد و در غیر این صورت مقدار پیش‌فرض آن ویژگی اعمال می‌شود.
استفاده از آن به‌عنوان مقدار ویژگی all بسیار کاربردی است.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤2
This media is not supported in your browser
VIEW IN TELEGRAM
کامپوننت‌های خلاقانه و چشم‌نواز متن‌باز برای رابط‌های کاربری که با استفاده از HTML-in-Canvas و WebGL ساخته شده‌اند.
این کامپوننت‌ها با JavaScript، React، Svelte و Vue سازگار هستند.
کافی است آن‌ها را کپی و پیست کنید و استفاده کنید:

🔗canvasui.dev
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
🤩3🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
نکته‌ای کوچک برای بهبود UX
در نسخهٔ موبایل Chrome و Safari، حروف موجود در فیلدهای متنی به‌صورت خودکار به حروف بزرگ تبدیل می‌شوند.
این رفتار در حالت عادی مشکلی ایجاد نمی‌کند؛ اما وقتی در جایی که انتظارش را نداریم فعال شود، باعث ایجاد اصطکاک اضافی و کاهش کیفیت تجربهٔ کاربری می‌شود.
راه‌حل: برای چنین فیلدهایی autocapitalize="off" را اضافه کنید. این ویژگی مشخص می‌کند که هنگام تایپ یا ویرایش متن، حروف به‌صورت خودکار به حروف بزرگ تبدیل شوند یا خیر.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤2👍1🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
🌺 میلاد با سعادت پیامبر اکرم(ص) و امام صادق(ع)

#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
❤7👎6🤬1