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

🆔@IR_javascript
Download Telegram
گاهی اوقات هنگام نوشتن یک کامپوننت، انواع ویژگی‌ها مانند id`، `class`، `style و یا ویژگی‌هایی با پیشوند data-* را به آن ارسال می‌کنید، اما این ویژگی‌ها در خروجی نهایی ناپدید می‌شوند. چرا؟ چون Vue به‌صورت پیش‌فرض این ویژگی‌ها را به‌طور خودکار روی تمام المنت‌ها اعمال نمی‌کند. ولی موضوع به همین سادگی هم نیست — ظرافت‌هایی دارد.

### دقیقاً چه اتفاقی می‌افتد؟

Vue تمامی ویژگی‌هایی را که صراحتاً به‌عنوان props تعریف نکرده‌اید**، جمع‌آوری کرده و آن‌ها را روی **المان ریشه‌ای (Root Element) کامپوننت شما قرار می‌دهد.

#### مثال:
<MyButton class="big red" id="super-btn" />


و درون MyButton.vue چنین چیزی نوشته‌اید:

<template>
<button>کلیک کن</button>
</template>


در این صورت، ویژگی‌های class="big red" و id="super-btn" به دکمه اضافه می‌شوند.
ساده و کاربردی، نه؟

---

### اگر از ساختار سفارشی استفاده کرده باشم چه می‌شود؟

اگر نخواهید Vue به‌طور خودکار این ویژگی‌ها را به هر جایی منتقل کند و ترجیح دهید خودتان تعیین کنید این ویژگی‌ها به کدام عنصر بروند**، در این صورت می‌توانید از `v-bind="$attrs"` استفاده کنید.

#### نمونه:

<template>
<div>
<button>دکمه شماره یک</button>
<button v-bind="$attrs">دکمه شماره دو</button>
</div>
</template>



در اینجا فقط دکمه دوم ویژگی‌هایی مثل `id` و `class` را دریافت می‌کند.

---

### اگر اصلاً نخواهید Vue چیزی منتقل کند چه؟

اگر بخواهید کنترل کامل را در دست داشته باشید، می‌توانید انتقال خودکار ویژگی‌ها را غیرفعال کنید. کافی‌ست گزینه زیر را در کامپوننت‌تان اضافه کنید:


<template>
<div class="wrapper">
<button v-bind="$attrs">دکمه</button>
</div>
</template>

<script setup>
defineOptions({
inheritAttrs: false
})
</script>



در این حالت، **هیچ ویژگی‌ای به عنصر ریشه‌ای (div) اضافه نمی‌شود
و تنها به دکمه منتقل خواهد شد. این کار زمانی بسیار مفید است که بخواهید استایل‌ها یا رویدادها دقیقاً روی یک عنصر تعاملی مثل دکمه اعمال شوند.

---

### نکات مهم:

- هر چیزی که prop نباشد، در $attrs قرار می‌گیرد.
- به‌صورت پیش‌فرض، تمام این ویژگی‌ها به عنصر ریشه‌ای کامپوننت افزوده می‌شوند.
- اگر می‌خواهید کنترل بیشتری داشته باشید، از inheritAttrs: false و v-bind="$attrs" استفاده کنید.
- می‌توان $attrs را هم در بخش setup و هم در template به‌کار برد.
- اگر نام یک ویژگی با نام prop یکی باشد، آن ویژگی دیگر وارد $attrs نمی‌شود.

این ویژگی‌ها به شما کمک می‌کنند کنترل دقیق‌تری بر ساختار، استایل و رفتار کامپوننت‌های خود داشته باشید — خصوصاً در کامپوننت‌های قابل استفاده مجدد و پیچیده.

#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
👍2
برخی وب‌سایت‌ها وجود دارند که امکان باز کردن ابزارهای توسعه‌دهنده مرورگر (DevTools) در آن‌ها فراهم نیست. این محدودیت‌ها به روش‌های خاصی اعمال می‌شوند:

### جلوگیری از نمایش منو و کلیدهای میان‌بر

در جاوااسکریپت، با استفاده از کد زیر می‌توان دسترسی به منوی راست‌کلیک و برخی کلیدهای ترکیبی مانند F۱۲ یا Ctrl + Shift + I را مسدود کرد:

document.addEventListener('contextmenu', event => event.preventDefault());

document.addEventListener('keydown', event => {
if (event.key === 'F12' || (event.ctrlKey && event.shiftKey && event.key === 'I')) {
event.preventDefault();
}
});



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
کتاب Chibi Vue نوشته‌ی یویچی کیکوچی، راهنمایی جامع و دقیق درباره‌ی ساختار درونی فریم‌ورک Vue ۳ است. این کتاب به‌ویژه برای توسعه‌دهندگانی که به‌صورت عمیق در حال یادگیری Vue هستند، بسیار سودمند است.

در این کتاب می‌خوانید:

تحلیل جامع هسته‌ی Vue، شامل: سامانه‌ی واکنش‌پذیری، کامپایلر قالب‌ها، و سیستم رندرینگ.

پیاده‌سازی عملی و گام‌به‌گام نسخه‌ای ساده‌شده از Vue از ابتدا.

زبان این کتاب انگلیسی است.
🔗https://book.chibivue.land/
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
💚میلاد امام رضا علیه السلام مبارک باد
🔻برخورد زیبای امام رضا(ع) به کسی که با بی‌رحمی خانه‌اش را غارت کرد.

🔗 [+لینک ویدیو]
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
10
کار با عددها و تاریخ‌ها در عناصر <input> می‌تواند بسیار ساده‌تر از چیزی باشد که معمولاً انجام می‌دهیم.

به‌طور پیش‌فرض، وقتی مقدار یک <input> را می‌گیریم، آن را به صورت رشته (string) دریافت می‌کنیم:

const raw = myInput.value; // نوع string


اگر این مقدار در واقع یک عدد یا تاریخ باشد، ناچاریم آن را به‌صورت دستی تبدیل (parse) کنیم:

const num = Number(myInput.value);
const date = new Date(myInput.value);


این کار تا حدی تکراری و خسته‌کننده به نظر می‌رسد، درست است؟
اینجاست که دو ویژگی ویژه به کمکمان می‌آیند:
valueAsNumber و valueAsDate

---

### valueAsNumber — تبدیل خودکار به عدد، بدون نیاز به parseInt یا parseFloat

// به‌جای:
const num = Number(myInput.value);

// استفاده از:
const num = myInput.valueAsNumber; // عدد یا NaN


اگر ورودی چیزی باشد که به‌درستی قابل تبدیل به عدد نباشد، مقدار NaN بازگردانده می‌شود، که می‌توان با استفاده از isNaN(num) آن را بررسی کرد.

این ویژگی فقط مختص type="number" نیست، بلکه برای type="range" نیز کار می‌کند.

---

### valueAsDate — دریافت مستقیم یک شیء Date

// به‌جای:
const dt = new Date(myInput.value);

// استفاده از:
const dt = myInput.valueAsDate; // شیء Date یا null


اگر فیلد خالی باشد، مقدار بازگشتی null خواهد بود. بررسی آن نیز ساده است:

if (!dt) {
// مقدار تاریخ وارد نشده است
}


نکته مهم اینجاست که تاریخ‌ها به‌صورت زمان UTC (ساعت صفر به وقت هماهنگ جهانی) در نظر گرفته می‌شوند.
برای نمایش محلی، از متدهای toLocaleString() یا توابعی مانند getUTCFullYear() استفاده کنید.

---

### نتیجه:

با استفاده از valueAsNumber و valueAsDate می‌توانیم از نوشتن کدهای اضافی مانند Number(...) یا new Date(...) خلاص شویم و کدی تمیزتر و خواناتر بنویسیم.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥2👍1
جاوااسکریپت | JavaScript pinned «لیستی از سایت هایی که در آنها می توانید آموزش های رایگان پیدا کنید https://downloadly.ir/ https://www.bilibili.com/ https://oneddl.net/?do=search https://oneddl.org/search/Computer+Networking/ https://www.avxgfx.com/video_tutorials/ https://www.4shared.com/…»
قالب‌های HTML

یکی از روش‌های مؤثر برای سامان‌دهی کد HTML، استفاده از *قالب‌ها*ست؛ این تکنیک به کاهش تکرار، تقسیم‌بندی منطقی کد و در نهایت بهبود درک ساختار صفحه کمک می‌کند.

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

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

برای ایجاد قالب، از تگ <template> استفاده می‌کنیم. به‌عنوان مثال:

<template id="tmp">
<h1>عنوان</h1>
<p>متن...</p>
</template>


### استفاده از قالب:

برای استفاده از محتوای یک قالب، کافی‌ست آن را *کلون* کرده و در جای دلخواه در صفحه قرار دهید. این کار امکان استفاده‌ی چندباره از یک بخش مشخص از کد را فراهم می‌سازد:

let elem = document.createElement('div');
elem.append(tmp.content.cloneNode(true));
document.body.append(elem);


نکته مهم:
مرورگر محتویات تگ <template> را نادیده می‌گیرد و تنها از نظر نحوی (syntax) بررسی می‌کند. این بدان معناست که کد داخل قالب تا زمانی که فعالانه در صفحه درج نشود، اجرا یا نمایش داده نمی‌شود.




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
نتیجه چه خواهد بود؟

"🤦‍♂️".substr(0,2);
"🤦‍♂️".substr(2,3);

#️⃣#code
👥@IR_javascript_group
🆔@IR_javascript
چه چیزی DOM است و چرا به آن نیاز داریم؟

«همه‌جا صحبت از DOM است... اما واقعاً DOM چیست؟»

DOM (مخفف *Document Object Model*) یا مدل شیء‌گرای سند، نمایی ساختاری از یک صفحه وب به شکل یک درخت است. در این مدل، هر تگ HTML به یک گره تبدیل می‌شود—یا شاخه، یا برگ. این ساختار به JavaScript اجازه می‌دهد تا در میان این درخت حرکت کرده، ویژگی‌های گره‌ها را بخواند و ساختار یا محتوای آن‌ها را در لحظه تغییر دهد.

### چرا به DOM نیاز داریم؟

پویایی محتوا

* امکان تغییر متن، سبک‌ها و ساختار صفحه بدون نیاز به بارگذاری مجدد
* پیاده‌سازی برنامه‌های تک‌صفحه‌ای (*SPA*) و رابط‌های فوق‌العاده سریع

تعامل‌پذیری

* واکنش به کلیک، حرکت ماوس، یا ورود اطلاعات از صفحه‌کلید
* ساخت منوهای کشویی، پنجره‌های مودال، اسلایدرها و سایر قابلیت‌هایی که به یک وب‌سایت «جان» می‌بخشند

ارتباط با JavaScript

* DOM پلی است میان HTML و CSS ایستا با منطق پویا در JavaScript
* این امکان را به اسکریپت‌ها می‌دهد که عناصر را جابه‌جا کرده، حذف یا اضافه کنند و به آن‌ها انیمیشن بدهند


### نکات مهم:

هنگامی که شروع به اعمال تغییرات متعدد در DOM می‌کنید، به خاطر داشته باشید که هر تغییر می‌تواند پرهزینه باشد. افزودن یا حذف عناصر، تغییر در سبک‌ها یا بازآرایی ساختار صفحه، باعث رخ دادن «بازمحاسبه» (*reflow*) و «بازنقاشی» (*repaint*) می‌شود—یعنی مرورگر مجبور است دوباره ابعاد و موقعیت عناصر را محاسبه کرده و صفحه را مجدداً ترسیم کند. اگر این تغییرات زیاد و پراکنده باشند، ممکن است باعث کند شدن رابط کاربری شود.

برای جلوگیری از این مشکل، سعی کنید تغییرات را دسته‌بندی و یکجا اعمال کنید؛ به عنوان مثال، ابتدا گره‌های جدید را در یک *DocumentFragment* قرار دهید و سپس آن را به‌صورت یکجا به DOM اضافه کنید، به‌جای آنکه هر گره را جداگانه درج نمایید.

نکته‌ای دیگر، مسئله امنیت است. استفاده‌ی مستقیم از innerHTML برای درج کد HTML، می‌تواند زمینه‌ساز حملات XSS شود. اگر کدی مخرب وارد شود، ممکن است در صفحه شما اجرا گردد. برای جلوگیری از این خطر، به‌جای innerHTML از textContent برای درج متن استفاده کنید و برای ایجاد عناصر جدید، از document.createElement و روش‌هایی مانند appendChild یا insertBefore بهره بگیرید.

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

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




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
:hover > \:not(\:hover)
معمولاً از ویژگی hover برای برجسته‌سازی یک عنصر خاص استفاده می‌شود؛ اما گاهی‌اوقات زیباتر است اگر به‌جای آن، کاری با سایر عناصر انجام دهیم.

CSS

ul {
@media (hover) and (prefers-reduced-motion: no-preference) {
& > li {
transform-origin: left center;
transition: transform یک ثانیه با تابع زمان‌بندی var(--ease-spring-۳)،
opacity صفر ممیز سه ثانیه با تابع زمان‌بندی var(--ease-۳);
}
&:hover > li:not(:hover) {
opacity: ۰.۲۵;
transform: scale(۰.۸);
}
}
}


در این مثال، زمانی که کاربر نشان‌گر ماوس را روی یکی از آیتم‌های فهرست می‌برد، سایر آیتم‌ها به‌طور خودکار کوچک‌تر شده و شفافیت آن‌ها کاهش می‌یابد. این تکنیک ظاهری حرفه‌ای، مینیمال و کاربرپسند ایجاد می‌کند، به‌ویژه در رابط‌های کاربری تعاملی.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍4
افزونه‌هایی مفید برای vscode:

Angular Language Service – پیشنهاد خودکار کد و امکان پیمایش آسان بین کامپوننت‌ها

ESLint + Prettier – کدی پاک و یکپارچه، بدون نیاز به تلاش اضافی

Import/Export Sorter برای JavaScript/TypeScript – مرتب‌سازی خودکار import و export هنگام ذخیره‌سازی

Path IntelliSense – تکمیل خودکار مسیر فایل‌ها با سرعت و دقت

Gremlins – هشدار در صورت وارد کردن اشتباه حروف، مانند تایپ «С» روسی به‌جای «C» انگلیسی

GitLen‎s – مشاهده‌ی تاریخچه تغییرات در کد: چه کسی، چه زمانی، چه چیزی را تغییر داده است


Run Terminal Command — امکان اجرای مستقیم دستورات (مثل npm، ng، یا git) از طریق منوی زمینه‌ی فایل‌ها یا از پنل فرمان را فراهم می‌کند.

CSS Peek — اجازه می‌دهد از کلاس‌ها یا شناسه‌های (id) موجود در HTML، مستقیماً به محل تعریف آن‌ها در فایل‌های CSS یا SCSS بروید.

Import ‎Cost — اندازه‌ی هر ماژول واردشده را نمایش می‌دهد و کمک می‌کند وابستگی‌های «سنگین» پروژه را تحت کنترل داشته باشید.


#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
رویداددهی تفویضی (Event Delegation) چیست؟
رویداددهی تفویضی یا Event Delegation تکنیکی در برنامه‌نویسی است که به‌جای آن‌که برای هر عنصر تعاملی (دکمه، لینک، آیتم فهرست و غیره) یک شنونده‌ی رویداد (event listener) جداگانه تعریف کنیم، یک شنونده‌ی واحد را روی عنصر والد آن‌ها (یا حتی روی کل سند document) قرار می‌دهیم.
زمانی که کاربر روی یک عنصر فرزند کلیک می‌کند، رویداد به سمت بالا در سلسله‌مراتب عناصر حرکت می‌کند (این پدیده به نام *Event Bubbling* شناخته می‌شود)، و ما می‌توانیم آن را در نقطه‌ای بالاتر دریافت و مدیریت کنیم.

### چرا این روش مفید است؟

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

پشتیبانی خودکار از عناصر اضافه‌شده به‌صورت دینامیک
وقتی با کد دکمه‌ها یا آیتم‌های جدیدی (مثلاً با جاوااسکریپت) ایجاد می‌کنید، نیازی به تعریف شنونده برای هرکدام نیست—چراکه شنونده‌ی والد از قبل آماده‌ی دریافت رویداد آن‌هاست.

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

---

### چند نکته‌ی کاربردی:

* از e.target.matches() استفاده کنید
برای آن‌که تشخیص دهید رویداد دقیقاً روی کدام عنصر اتفاق افتاده است.

* از closest() بهره بگیرید
برای پیدا کردن نزدیک‌ترین عنصر والد مانند یک <li> که حاوی دکمه یا عنصر موردنظر باشد.

* محدوده‌ی تفویض را هوشمندانه انتخاب کنید
نیازی نیست شنونده را روی کل سند (document) قرار دهید؛ اگر می‌توان آن را به نزدیک‌ترین والد مشترک محدود کرد، از این کار بهره‌مند شوید تا از پردازش‌های غیرضروری جلوگیری شود.

---

### جمع‌بندی

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


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
بررسی Type Guardهای امن در TypeScript برای مقادیر unknown یا any

در اینجا به یکی از ویژگی‌های موردعلاقه‌ام در TypeScript می‌پردازم:
استفاده از عبارت value is Type که به کامپایلر کمک می‌کند تا نوع واقعی یک مقدار را شناسایی کرده و بدون نیاز به تبدیل‌های پرخطر از نوع any یا بروز خطاهای زمان اجرا، با آن کار کند.

### چرا نباید از as به‌صورت سرسری استفاده کنیم؟

اغلب هنگام مواجهه با مقادیر از نوع unknown یا `any`، خیلی ساده می‌نویسیم:

const data = value as MyType;


یا حتی:

const data = value as any;


در این حالت، در واقع چشم خود را بر هشدارهای کامپایلر می‌بندیم. اما این کار باعث می‌شود از مزایای سیستم نوع‌گذاری TypeScript محروم شویم و ممکن است در زمان اجرا با مقدار `undefined` به‌جای فیلدی که انتظار داریم، مواجه شویم.

### راه‌حل: استفاده از تابع تشخیص (Type Predicate)

به‌جای تبدیل‌های کورکورانه، می‌توانیم با صرف کمی وقت بیشتر، تابعی بنویسیم که:

۱. بررسی کند مقدار null یا undefined نباشد
۲. وجود ویژگی‌های موردنیاز را بررسی کند
۳. نوع این ویژگی‌ها را با دقت بررسی نماید (مثلاً string، number، و غیره)

### نمونه‌ای از یک بررسی امن:

function isMyType(value: unknown): value is MyType {
return (
typeof value === 'object' &&
value !== null &&
/* بررسی وجود ویژگی‌ها */
/* بررسی نوع اولیه‌ی آن‌ها */
);
}


در اینجا:

* value: unknown یعنی ما به ورودی اعتماد نداریم.
* value is MyType به کامپایلر قول می‌دهد: «اگر خروجی true بود، قطعاً نوع مقدار MyType است».
* درون تابع، می‌توانیم از انواع بررسی‌ها استفاده کنیم: بررسی کلیدها، استفاده از instanceof`، `Array.isArray() و هر روش منطقی دیگری.

### یک مثال واقعی از کاربرد:

function handle(resp: unknown) {
if (isMyType(resp)) {
// در اینجا مطمئن هستیم که resp از نوع MyType است
// بنابراین می‌توانیم با خیال راحت از ویژگی‌های آن استفاده کنیم
}
}


### نتیجه‌گیری

این روش، راهکاری مؤثر برای حفظ ایمنی نوع‌ها هنگام کار با مقادیر unknown یا any است. نه‌تنها به کدی مطمئن‌تر منجر می‌شود، بلکه تجربه‌ی توسعه را نیز با خطاهای کمتر و پیش‌بینی‌پذیری بیشتر بهبود می‌بخشد.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
دسترس‌پذیری وب‌سایت و نقش ویژگی‌های ARIA

به‌تازگی شروع کرده‌ام درباره‌ی اهمیت دسترس‌پذیری وب‌سایت‌ها صحبت کنم. امروز این موضوع را ادامه می‌دهم و درباره‌ی ویژگی‌های ARIA توضیح می‌دهم؛ عناصری کلیدی که باعث می‌شوند رابط‌های کاربری وب برای همه‌ی کاربران قابل فهم باشند.

ARIA (مخفف *برنامه‌های اینترنتی غنی قابل دسترس*) مجموعه‌ای از ویژگی‌هاست که به عناصر HTML افزوده می‌شود تا فناوری‌های کمکی مانند صفحه‌خوان‌ها، نمایشگرهای بریل و ابزارهای مشابه، اطلاعات بیشتری درباره‌ی نقش و وضعیت عناصر رابط کاربری دریافت کنند.

مثالی بدون استفاده از ARIA:
فرض کنید یک دکمه‌ی چندرسانه‌ای داریم که به هر دلیلی فقط با یک عنصر <div> ساخته شده است. در این حالت، یک صفحه‌خوان قادر نخواهد بود تشخیص دهد که این عنصر در واقع یک دکمه است.

نمونه‌ی بهبودیافته با استفاده از ARIA:
در این مثال ما صراحتاً مشخص می‌کنیم که این عنصر یک دکمه است:

<div role="button" tabindex="0">Play</div>


چطور می‌توان این موارد را پیاده‌سازی کرد؟
می‌توان از گام‌های کوچک آغاز کرد: بررسی دکمه‌ها، فرم‌ها و بخش‌های تعاملی. بررسی کنیم که آیا صفحه‌خوان‌ها می‌توانند مفهوم آن‌ها را درک کنند یا خیر، و در صورت نیاز، ویژگی‌های ARIA را به آن‌ها اضافه کنیم.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
رنگ currentColor
یکی از قابلیت‌های CSS که گاهی فراموش می‌شود، اما می‌تواند در مدیریت رنگ‌ها بسیار مفید واقع شود، ویژگی currentColor است.

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

این ویژگی، یک واژه‌ی کلیدی خاص در CSS است که برای ارجاع به رنگ فعلی عنصر به کار می‌رود.

به عنوان مثال، اگر رنگ متن یک عنصر با استفاده از ویژگی color تعیین شده باشد، currentColor به همان رنگ اشاره خواهد کرد، فارغ از این‌که در کجا یا چگونه مورد استفاده قرار می‌گیرد.

چه زمانی باید از currentColor استفاده کرد؟
زمانی که می‌خواهید رنگ متن، حاشیه و سایر ویژگی‌ها یکسان باشند و به‌راحتی قابل تغییر باشند.

در فایل‌های SVG نیز می‌توان رنگ پرشدگی یا خط دور عناصر را با currentColor تعیین کرد. این موضوع زمانی بسیار کاربردی است که نیاز دارید رنگ آیکون با رنگ متن یا سایر عناصر هماهنگ باشد.

مثال:

button {
color: blue; /* تعیین رنگ متن */
background-color: white;
border: ۲px solid currentColor; /* حاشیه به رنگ آبی، همانند رنگ متن خواهد بود */
}

svg {
fill: currentColor; /* آیکون به رنگ آبی، همانند رنگ متن نمایش داده می‌شود */
}


در مجموع، استفاده از currentColor روشی عالی برای بهبود مدیریت سبک‌ها و کاهش تکرار در کدنویسی است.




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍31
all: unset – بازنشانی تمام استایل‌ها تنها با یک خط

احتمالاً بارها پیش آمده که به‌صورت دستی استایل‌های پیش‌فرض یک عنصر را پاک کرده‌اید؛ مثلاً به این شکل:

button {
background: none;
border: none;
padding: 0;
font: inherit;
color: inherit;
}


حالا تصور کنید تمام این تنظیمات را بتوان فقط با یک خط جایگزین کرد:

button {
all: unset;
}


و دقیقاً همان نتیجه را گرفت!

### ویژگی all: unset چیست؟

این ویژگی تمام استایل‌های اعمال‌شده را ــ حتی استایل‌های پیش‌فرض مرورگر ــ بازنشانی می‌کند،
در عین حال، ویژگی‌هایی که قابل ارث‌بری هستند (مانند color یا font-family) را از عنصر والد حفظ می‌کند.

در واقع، این ویژگی مانند فشردن دکمه «پاک کردن همه چیز» است؛
و بعد از آن، می‌توانید ظاهر دلخواه خود را از پایه و با کنترل کامل طراحی کنید.

### نمونه‌ی نهایی:

button {
all: unset;
background-color: blue;
color: white;
font-size: ۱۶px;
padding: ۱۰px ۲۰px;
border-radius: ۵px;
}


اکنون شما هستید که ظاهر دکمه را مشخص می‌کنید — بدون مزاحمت از سمت استایل‌های مرورگر.

### چه زمانی از all: unset استفاده کنیم؟

* زمانی که می‌خواهید تمام استایل‌های پیش‌فرض را حذف کنید؛
* هنگام طراحی مؤلفه‌های سفارشی (custom components) با ظاهر کاملاً خالص؛
* وقتی که می‌خواهید همه چیز دقیقاً از «صفر» شروع شود.

all: unset ابزاری قدرتمند برای بازنشانی استایل است —
اما باید با احتیاط از آن استفاده کنید،
چرا که ممکن است ناخواسته ویژگی‌هایی را نیز حذف کنید که قصد حفظ آن‌ها را داشتید.
در چنین مواردی، گاهی بهتر است به‌صورت انتخابی استایل‌ها را پاک کنید تا بعداً مجبور به بازگرداندن دستی آن‌ها نشوید.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍4
متوقف کردن یک Watcher

Watcher**هایی که به‌صورت هم‌زمان (synchronous) درون تابع `setup()` یا در قالب `<script setup>` تعریف می‌شوند، به نمونه (instance) کامپوننت مالک وابسته هستند و به‌طور خودکار هنگام **unmount شدن آن کامپوننت متوقف خواهند شد. در اغلب موارد، نیازی نیست نگران متوقف کردن دستی آن‌ها باشید.

نکته‌ی کلیدی در این‌جاست که Watcher باید به‌صورت هم‌زمان ایجاد شود؛ اگر Watcher در یک تابع غیرهم‌زمان (asynchronous) مانند setTimeout ایجاد گردد، دیگر به کامپوننت والد وابسته نخواهد بود و باید به‌صورت دستی متوقف شود تا از نشت حافظه (memory leak) جلوگیری شود. به مثال زیر توجه کنید:
<script setup>
import { watchEffect } from 'vue'

// این Watcher به‌صورت خودکار متوقف خواهد شد
watchEffect(() => {})

// ...اما این یکی نه!
setTimeout(() => {
watchEffect(() => {})
}, ۱۰۰)
</script>

برای متوقف کردن دستی یک Watcher**، می‌توان از تابع بازگشتی استفاده کرد. این روش هم برای `watch` و هم برای `watchEffect` کاربرد دارد:


const unwatch = watchEffect(() => {})

// ...در زمانی دیگر، زمانی که دیگر نیازی نیست
unwatch()


توجه داشته باشید که تنها در موارد بسیار محدود نیاز به ایجاد **Watcher
به‌صورت غیرهم‌زمان وجود دارد، و در هر زمان ممکن، بهتر است از ایجاد هم‌زمان استفاده شود.

اگر نیاز دارید منتظر داده‌ای غیرهم‌زمان بمانید، می‌توانید منطق Watcher خود را مشروط طراحی کنید:

// داده‌ای که به‌صورت غیرهم‌زمان بارگذاری می‌شود
const data = ref(null)

watchEffect(() => {
if (data.value) {
// انجام عملیات زمانی که داده بارگذاری شد
}
})


#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
1👍1