تابعهای
در نسخههای پیشین CSS، نبود ابزارهای داخلی برای تولید مقادیر تصادفی بهوضوح احساس میشد. اما در این ماژول جدید، دو تابع کاربردی معرفی شدهاند:
*
*
این نگارش ساده و در عین حال قدرتمند، به ما امکان میدهد مقادیر تصادفی را مستقیماً در CSS و در دل سلکتورها یا عناصر بهکار ببریم. چنین رویکردی افقهای تازهای در طراحی گرافیکی وب میگشاید و به طراحان اجازه میدهد جزئیاتی پویا، چشمنواز و خلاقانه به صفحات خود بیفزایند. استفاده از این قابلیتها بدون شک تجربهای هیجانانگیز خواهد بود و به خلق طراحیهای منحصربهفرد و جذاب کمک میکند.
مثال:
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
random()
و random-item()
در نسخههای پیشین CSS، نبود ابزارهای داخلی برای تولید مقادیر تصادفی بهوضوح احساس میشد. اما در این ماژول جدید، دو تابع کاربردی معرفی شدهاند:
*
random-item()
که یک مقدار تصادفی از میان یک فهرست برمیگرداند.*
random()
که عددی تصادفی در بازهای مشخص تولید میکند.این نگارش ساده و در عین حال قدرتمند، به ما امکان میدهد مقادیر تصادفی را مستقیماً در CSS و در دل سلکتورها یا عناصر بهکار ببریم. چنین رویکردی افقهای تازهای در طراحی گرافیکی وب میگشاید و به طراحان اجازه میدهد جزئیاتی پویا، چشمنواز و خلاقانه به صفحات خود بیفزایند. استفاده از این قابلیتها بدون شک تجربهای هیجانانگیز خواهد بود و به خلق طراحیهای منحصربهفرد و جذاب کمک میکند.
مثال:
.random-square-۲ {
font-size: ۱۶px;
width: random(۱۶۰px, ۳۲۰px);
height: random(۱۰em, ۲۰em);
}
.random {
/* مقدار تصادفی بین صد تا سیصد پیکسل */
width: random(۱۰۰px, ۳۰۰px);
/* مقدار تصادفی بین صد تا سیصد پیکسل با گام پنجاه پیکسل:
صد پیکسل، صد و پنجاه پیکسل، ... */
height: random(۱۰۰px, ۳۰۰px, by ۵۰px);
/* یکی از سه رنگ تصادفی */
background: random-item(--c, قرمز، سبز، آبی);
}
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
بر سرِ تربتِ ما چون گذری همّت خواه
که زیارتگَهِ رِندانِ جهان خواهد بود
❤️عید سعید قربان
🔗 [+لینک ویدیو]
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
که زیارتگَهِ رِندانِ جهان خواهد بود
❤️عید سعید قربان
🔗 [+لینک ویدیو]
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
❤8👎2
چه اتفاقی میافتد وقتی روی یک لینک کلیک میکنیم؟
در یکی از نوشتههای قبلی، دربارهی چگونگی «رندر» شدن یک صفحهی وب توسط مرورگر توضیح داده بودم؛ از دریافت کد HTML تا نمایش نهایی سایت در پنجرهی مرورگر. امروز قصد دارم بررسی عملکرد مرورگر را ادامه دهم و توضیح دهم که در پسزمینهی این تعامل به ظاهر ساده — کلیک روی یک لینک — چه فرآیندهایی در جریان است.
در نگاه اول، کلیک ماوس کار سادهای بهنظر میرسد، اما در دل مرورگر اتفاقات جالبی رخ میدهد...
یکم: لینک از کجا میآید؟
اگر روی یک لینک کلیک میکنید، این بدان معناست که مرورگر هماکنون در حال نمایش یک صفحهی وب است، حتی اگر آن صفحه، صفحهی آغازین باشد و کد HTML، استایلهای CSS و اسکریپتهای JavaScript آن بهصورت محلی بارگذاری شده باشند.
یادآوری: لینک در کد HTML به این شکل تعریف میشود:
اگر چنین لینکی در صفحه قابل مشاهده است، آن عنصر پیشاپیش وارد درخت DOM شده و بهصورت
وقتی نشانگر ماوس را روی لینک میبریم:
* مرورگر شکل نشانگر را تغییر میدهد (معمولاً به شکل دست)
* آدرس مقصد لینک ممکن است در گوشهی پایین-چپ نمایش داده شود
* ممکن است استایل
* اگر توسعهدهنده آن را پیادهسازی کرده باشد، فرآیند «پیشبارگذاری» (prefetching) آغاز میشود.
برخی مرورگرها حتی ممکن است شروع کنند به بازیابی آدرس IP دامنهی لینکشده (از طریق پرسوجو به DNS) یا بارگذاری بخشی از محتوای مقصد پیش از کلیک کاربر — تا در صورت کلیک، محتوا آمادهی نمایش باشد.
کلیک! و بعد؟
مرورگر زنجیرهای از اقدامات را آغاز میکند:
۱. بررسی رفتار پیشفرض: مثلاً اگر لینک دارای
۲. بررسی اینکه آیا JavaScript، رخداد کلیک را لغو کرده یا نه. بسیاری از اپلیکیشنهای تکصفحهای (SPA) این کلیک را رهگیری میکنند تا از بارگذاری مجدد صفحه جلوگیری کنند.
اگر هیچ مانعی در کار نباشد، مرورگر مراحل زیر را اجرا میکند:
* نوار آدرس (URL) را بهروزرسانی میکند
* محتوای فعلی صفحه را پاک میکند یا صفحه را سفید نمایش میدهد
* یک درخواست HTTP به سرور ارسال میشود. اگر آدرس IP سرور در کش DNS موجود باشد، از آن استفاده میشود، در غیر این صورت ابتدا یک درخواست DNS انجام میشود تا IP دریافت گردد، سپس درخواست HTTP ارسال میشود.
نکته: اگر فونتها از دامنهای مانند
درخواست چگونه است؟
درخواستی که به آدرسی درون ویژگی `href` ارسال میشود، با استفاده از پروتکل HTTP و روش
پاسخ سرور و بارگذاری مجدد
اگر سرور با کد HTML پاسخ دهد، فرآیند رندرینگ آغاز میشود: تجزیهی HTML، بارگیری منابع، و نمایش محتوا.
اگر پاسخ، دانلود فایل، تغییر مسیر (redirect) یا خطا باشد، مرورگر متناسب با آن واکنش نشان میدهد.
اما در اپلیکیشنهای SPA، ممکن است اصلاً بارگذاری جدیدی صورت نگیرد. در عوض JavaScript محتوای صفحه را بدون اینکه کاربر متوجه شود، بهروزرسانی میکند.
مثال: رهگیری کلیک با JavaScript
در این حالت:
* مرورگر درخواست پیشفرض را ارسال نمیکند (JavaScript میتواند خودش در صورت نیاز درخواست ارسال کند).
* تغییر URL توسط JavaScript و از طریق History API (
* محتوا بدون بارگذاری مجدد صفحه تغییر میکند، در حالی که نوار آدرس مرورگر تغییر کرده است.
این روند به توسعهدهندگان کمک میکند تجربهای روانتر و سریعتر برای کاربر فراهم کنند، بیآنکه بار اضافی بر سرور یا مرورگر تحمیل شود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
در یکی از نوشتههای قبلی، دربارهی چگونگی «رندر» شدن یک صفحهی وب توسط مرورگر توضیح داده بودم؛ از دریافت کد HTML تا نمایش نهایی سایت در پنجرهی مرورگر. امروز قصد دارم بررسی عملکرد مرورگر را ادامه دهم و توضیح دهم که در پسزمینهی این تعامل به ظاهر ساده — کلیک روی یک لینک — چه فرآیندهایی در جریان است.
در نگاه اول، کلیک ماوس کار سادهای بهنظر میرسد، اما در دل مرورگر اتفاقات جالبی رخ میدهد...
یکم: لینک از کجا میآید؟
اگر روی یک لینک کلیک میکنید، این بدان معناست که مرورگر هماکنون در حال نمایش یک صفحهی وب است، حتی اگر آن صفحه، صفحهی آغازین باشد و کد HTML، استایلهای CSS و اسکریپتهای JavaScript آن بهصورت محلی بارگذاری شده باشند.
یادآوری: لینک در کد HTML به این شکل تعریف میشود:
<a href="/about">دربارهی ما</a>
اگر چنین لینکی در صفحه قابل مشاهده است، آن عنصر پیشاپیش وارد درخت DOM شده و بهصورت
HTMLAnchorElement
شناخته میشود. این صرفاً یک متن زیرخطدار نیست، بلکه عنصری تعاملی است و مرورگر نیز از این موضوع آگاه است.وقتی نشانگر ماوس را روی لینک میبریم:
* مرورگر شکل نشانگر را تغییر میدهد (معمولاً به شکل دست)
* آدرس مقصد لینک ممکن است در گوشهی پایین-چپ نمایش داده شود
* ممکن است استایل
:hover
از CSS فعال شود* اگر توسعهدهنده آن را پیادهسازی کرده باشد، فرآیند «پیشبارگذاری» (prefetching) آغاز میشود.
برخی مرورگرها حتی ممکن است شروع کنند به بازیابی آدرس IP دامنهی لینکشده (از طریق پرسوجو به DNS) یا بارگذاری بخشی از محتوای مقصد پیش از کلیک کاربر — تا در صورت کلیک، محتوا آمادهی نمایش باشد.
کلیک! و بعد؟
مرورگر زنجیرهای از اقدامات را آغاز میکند:
۱. بررسی رفتار پیشفرض: مثلاً اگر لینک دارای
target="_blank"
باشد، مرورگر آن را در زبانهای جدید باز خواهد کرد.۲. بررسی اینکه آیا JavaScript، رخداد کلیک را لغو کرده یا نه. بسیاری از اپلیکیشنهای تکصفحهای (SPA) این کلیک را رهگیری میکنند تا از بارگذاری مجدد صفحه جلوگیری کنند.
اگر هیچ مانعی در کار نباشد، مرورگر مراحل زیر را اجرا میکند:
* نوار آدرس (URL) را بهروزرسانی میکند
* محتوای فعلی صفحه را پاک میکند یا صفحه را سفید نمایش میدهد
* یک درخواست HTTP به سرور ارسال میشود. اگر آدرس IP سرور در کش DNS موجود باشد، از آن استفاده میشود، در غیر این صورت ابتدا یک درخواست DNS انجام میشود تا IP دریافت گردد، سپس درخواست HTTP ارسال میشود.
نکته: اگر فونتها از دامنهای مانند
fonts.com
بارگیری شوند و فایلهای CSS از دامنهای مثل `bestcss.com`، مرورگر برای هرکدام یک درخواست DNS جداگانه میفرستد — امری که میتواند بر سرعت بارگذاری سایت تأثیر منفی بگذارد.درخواست چگونه است؟
درخواستی که به آدرسی درون ویژگی `href` ارسال میشود، با استفاده از پروتکل HTTP و روش
GET
انجام میشود و شامل مجموعهای از هدرهاست، مانند:Referer
Accept
User-Agent
Cookies (در صورت مجاز بودن توسط سیاستهای امنیتی)
و سایر موارد
پاسخ سرور و بارگذاری مجدد
اگر سرور با کد HTML پاسخ دهد، فرآیند رندرینگ آغاز میشود: تجزیهی HTML، بارگیری منابع، و نمایش محتوا.
اگر پاسخ، دانلود فایل، تغییر مسیر (redirect) یا خطا باشد، مرورگر متناسب با آن واکنش نشان میدهد.
اما در اپلیکیشنهای SPA، ممکن است اصلاً بارگذاری جدیدی صورت نگیرد. در عوض JavaScript محتوای صفحه را بدون اینکه کاربر متوجه شود، بهروزرسانی میکند.
مثال: رهگیری کلیک با JavaScript
<a href="/about" onClick={(e) => {
e.preventDefault(); // جلوگیری از رفتار پیشفرض مرورگر
navigate('/main-about');
}}>
در این حالت:
* مرورگر درخواست پیشفرض را ارسال نمیکند (JavaScript میتواند خودش در صورت نیاز درخواست ارسال کند).
* تغییر URL توسط JavaScript و از طریق History API (
pushState
) انجام میشود.* محتوا بدون بارگذاری مجدد صفحه تغییر میکند، در حالی که نوار آدرس مرورگر تغییر کرده است.
این روند به توسعهدهندگان کمک میکند تجربهای روانتر و سریعتر برای کاربر فراهم کنند، بیآنکه بار اضافی بر سرور یا مرورگر تحمیل شود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
چرا
بهطور پیشفرض، هر دکمهای که با تگ
برای نمونه:
در این مثال، پس از کلیک ابتدا پیام «کلیک!» نمایش داده میشود، اما بلافاصله بعد از آن، فرم بهصورت خودکار ارسال خواهد شد.
علاوه بر این، اگر تنها یک دکمه با نوع
برای جلوگیری از این رفتار و اجرای دقیق منطق دلخواه خودتان، لازم است نوع دکمه را بهصراحت
### مقادیر مجاز برای ویژگی
*
*
*
### نتیجهگیری:
اگر دکمهی شما در فرم قرار دارد ولی وظیفهاش ارسال یا بازنشانی فرم نیست، همیشه بهصورت صریح
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
<button>
و <button type="button">
یکسان نیستند؟بهطور پیشفرض، هر دکمهای که با تگ
<button>
درون یک فرم قرار میگیرد، بهصورت خودکار نوع submit
دریافت میکند. این یعنی با کلیک روی آن، فرم ارسال میشود—حتی اگر هدف شما صرفاً اجرای یک اسکریپت ساده باشد.برای نمونه:
<form onsubmit="alert('فرم ارسال شد!')">
<button onclick="alert('کلیک!')">کلیک کن</button>
</form>
در این مثال، پس از کلیک ابتدا پیام «کلیک!» نمایش داده میشود، اما بلافاصله بعد از آن، فرم بهصورت خودکار ارسال خواهد شد.
علاوه بر این، اگر تنها یک دکمه با نوع
submit
(چه بهصورت صریح یا ضمنی) در فرم وجود داشته باشد، فشردن کلید Enter در یک فیلد متنی ممکن است باعث شود مرورگر این دکمه را بهصورت خودکار کلیک کند — حتی بدون دخالت مستقیم کاربر.برای جلوگیری از این رفتار و اجرای دقیق منطق دلخواه خودتان، لازم است نوع دکمه را بهصراحت
button
تعیین کنید:<button type="button" onclick="alert('کلیک!')">کلیک کن</button>
### مقادیر مجاز برای ویژگی
type
در تگ <button>
:*
submit
(پیشفرض): فرم را ارسال میکند.*
reset
: تمامی فیلدهای فرم را به حالت اولیه بازمیگرداند.*
button
: بدون JavaScript کاری انجام نمیدهد و صرفاً بهعنوان ماشهی اسکریپت استفاده میشود.### نتیجهگیری:
اگر دکمهی شما در فرم قرار دارد ولی وظیفهاش ارسال یا بازنشانی فرم نیست، همیشه بهصورت صریح
type="button"
را تعیین کنید. این کار از ارسالهای ناخواستهی فرم جلوگیری کرده و منطق شما را کاملاً تحت کنترل نگه میدارد.#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍3
زمانی که نیاز به استایلدهی عناصری دارید که به آنها دسترسی مستقیم ندارید
گاهی اوقات لازم است تا عناصر داخلی مرورگر مانند نوار لغزنده
در چنین مواقعی بود که برای نخستین بار متوجه گزینهای با عنوان «نمایش Shadow DOM عامل کاربر» (Show user agent shadow DOM) شدم — قابلیتی که دسترسی به DOM سایه مرورگر را فراهم میکند و به شما اجازه میدهد تغییرات دلخواه خود را روی آن اعمال کنید.
### فعالسازی Shadow DOM در DevTools مرورگر Chrome
برای فعال کردن نمایش Shadow DOM در ابزار توسعه کروم، مراحل زیر را دنبال کنید:
۱. ابزار توسعه (DevTools) را باز کنید.
۲. وارد بخش تنظیمات شوید (با کلیک روی آیکون چرخدنده).
۳. از منوی کناری، گزینه «Elements / عناصر» را انتخاب کنید.
۴. تیک گزینه «نمایش Shadow DOM عامل کاربر» (Show user agent shadow DOM) را بزنید.
با این کار، در درخت عناصر، گرههایی «مخفی» ظاهر میشوند که در واقع همان Shadow DOM هستند و حاوی ساختار بومی HTML و CSS مرورگر هستند.
برخی استایلها به دلیل قرار داشتن در Shadow DOM «نابودنی» به نظر میرسند، اما اکنون با فعالسازی این گزینه، میتوانید به آنها دسترسی یافته و کنترل کامل بر جزییات رابط کاربری خود داشته باشید.
این ویژگی، ابزاری قدرتمند برای توسعهدهندگانی است که میخواهند تجربه کاربری را تا کوچکترین جزئیات شخصیسازی کنند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
گاهی اوقات لازم است تا عناصر داخلی مرورگر مانند نوار لغزنده
<input type="range">
یا شبهعنصر ::placeholder
را بهصورت دقیق استایلدهی کنید. اما بهمحض تلاش برای بررسی این عناصر در ابزار توسعه (DevTools)، با دیواری غیرقابل نفوذ مواجه میشوید: ساختار داخلی و استایلهای آنها در دسترس نیستند.در چنین مواقعی بود که برای نخستین بار متوجه گزینهای با عنوان «نمایش Shadow DOM عامل کاربر» (Show user agent shadow DOM) شدم — قابلیتی که دسترسی به DOM سایه مرورگر را فراهم میکند و به شما اجازه میدهد تغییرات دلخواه خود را روی آن اعمال کنید.
### فعالسازی Shadow DOM در DevTools مرورگر Chrome
برای فعال کردن نمایش Shadow DOM در ابزار توسعه کروم، مراحل زیر را دنبال کنید:
۱. ابزار توسعه (DevTools) را باز کنید.
۲. وارد بخش تنظیمات شوید (با کلیک روی آیکون چرخدنده).
۳. از منوی کناری، گزینه «Elements / عناصر» را انتخاب کنید.
۴. تیک گزینه «نمایش Shadow DOM عامل کاربر» (Show user agent shadow DOM) را بزنید.
با این کار، در درخت عناصر، گرههایی «مخفی» ظاهر میشوند که در واقع همان Shadow DOM هستند و حاوی ساختار بومی HTML و CSS مرورگر هستند.
برخی استایلها به دلیل قرار داشتن در Shadow DOM «نابودنی» به نظر میرسند، اما اکنون با فعالسازی این گزینه، میتوانید به آنها دسترسی یافته و کنترل کامل بر جزییات رابط کاربری خود داشته باشید.
این ویژگی، ابزاری قدرتمند برای توسعهدهندگانی است که میخواهند تجربه کاربری را تا کوچکترین جزئیات شخصیسازی کنند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
متد
مرورگر به درخواست
### کاربردهای عملی
* نهاییسازی دادههای تحلیلی: ارسال اطلاعات آماری جمعآوریشده در طول یک نشست، درست پیش از بسته شدن صفحه
* ذخیرهسازی خودکار: ثبت آخرین وضعیت برنامه در شرایطی که ممکن است کاربر بهصورت دستی آن را ذخیره نکرده باشد
* گزارش خطاها: ارسال تضمینی لاگهای مربوط به خطاهای بحرانی
* ردیابی رفتار کاربر: ثبت آخرین اقدامات کاربر پیش از ترک صفحه
### محدودیتها
* حداکثر اندازه بار داده محدود است (معمولاً تا شصت و چهار کیلوبایت)
* فقط از درخواستهای POST پشتیبانی میکند
* از هدرهای سفارشی پشتیبانی نمیکند
* پاسخ سرور قابل پردازش نیست
این ویژگیها
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
navigator.sendBeacon()
این امکان را فراهم میکند که حجم کمی از دادهها بهصورت تضمینی به سرور ارسال شود، حتی در شرایطی که کاربر صفحه یا مرورگر را ببندد. برخلاف درخواستهای سنتی AJAX که ممکن است هنگام بارگذاری یا بستن صفحه ناتمام بمانند، sendBeacon
در چنین سناریوهایی ارسال داده را تضمین میکند.مرورگر به درخواست
sendBeacon
اولویت اجرای بالا نسبت به فرآیند بسته شدن صفحه میدهد، که این ویژگی، این متد را برای ارسال دادههای حیاتی، ابزاری ایدهآل میسازد.### کاربردهای عملی
* نهاییسازی دادههای تحلیلی: ارسال اطلاعات آماری جمعآوریشده در طول یک نشست، درست پیش از بسته شدن صفحه
* ذخیرهسازی خودکار: ثبت آخرین وضعیت برنامه در شرایطی که ممکن است کاربر بهصورت دستی آن را ذخیره نکرده باشد
* گزارش خطاها: ارسال تضمینی لاگهای مربوط به خطاهای بحرانی
* ردیابی رفتار کاربر: ثبت آخرین اقدامات کاربر پیش از ترک صفحه
const data = JSON.stringify({event: 'page_close', time: Date.now()});
navigator.sendBeacon("/analytics", data);
### محدودیتها
* حداکثر اندازه بار داده محدود است (معمولاً تا شصت و چهار کیلوبایت)
* فقط از درخواستهای POST پشتیبانی میکند
* از هدرهای سفارشی پشتیبانی نمیکند
* پاسخ سرور قابل پردازش نیست
این ویژگیها
sendBeacon
را برای ارسال دادههای ساده، سریع و قابل اعتماد، بهویژه هنگام بستن صفحه، به ابزاری کاربردی تبدیل کردهاند.#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
چگونه یک نشان (Badge) برای برنامه ایجاد کنیم
نشانها (Badge) برای انتقال اطلاعات غیر اضطراری به کاربر استفاده میشوند. برای نمونه، میتوان از آنها برای نمایش وضعیت یک برنامه یا تعداد آیتمهای خواندهنشده بهره گرفت. روش کلاسیک ایجاد نشان برای برنامه، افزودن یک عدد به فاوآیکن (favicon) بود. اما در مرورگرهای مدرن، پس از نصب برنامه، راهکاری داخلی برای افزودن نشان به آیکون برنامه در نوار وظیفه سیستمعامل وجود دارد.
روش نوین
استفاده از متد navigator.setAppBadge()
متد navigator.setAppBadge() امکان افزودن یک نشان به آیکون برنامه نصبشده را فراهم میسازد. این متد یک آرگومان اختیاری دریافت میکند که یک عدد صحیح است و بهعنوان مقدار نشان استفاده میشود.
اگر این عدد صفر تعیین شود، نشان پاک خواهد شد. در صورتی که هیچ مقداری ارائه نشود، یک نشان عمومی (معمولاً بهصورت نقطهای رنگی) نمایش داده میشود.
این روش مدرن و استاندارد، تجربه کاربری بهتری را در برنامههای تحت وب فراهم میکند و بهویژه در برنامههای وب پیشرونده (PWA) نقش مؤثری در اطلاعرسانی ساده و مؤثر دارد.
روش کلاسیک: افزودن عدد به فاوآیکون
اگر برنامه هنوز نصب نشده باشد، میتوانید عددی را به فاوآیکون اضافه کنید. راههای گوناگونی برای انجام این کار وجود دارد؛ برای نمونه، میتوان فاوآیکون را بهصورت پویا بر روی یک عنصر بوم (canvas) ترسیم کرد و اطلاعات مربوط به نشان (badge) را به آن افزود و سپس آن را بهصورت یک نشانی «بلاب» (Blob URL) نمایش داد. یا میتوان تصویری از نوع SVG ساخت که اطلاعات نشان را بهصورت یک نشانی دادهای (data URL) در خود داشته باشد.
🔗https://web.dev/patterns/web-apps/badges
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نشانها (Badge) برای انتقال اطلاعات غیر اضطراری به کاربر استفاده میشوند. برای نمونه، میتوان از آنها برای نمایش وضعیت یک برنامه یا تعداد آیتمهای خواندهنشده بهره گرفت. روش کلاسیک ایجاد نشان برای برنامه، افزودن یک عدد به فاوآیکن (favicon) بود. اما در مرورگرهای مدرن، پس از نصب برنامه، راهکاری داخلی برای افزودن نشان به آیکون برنامه در نوار وظیفه سیستمعامل وجود دارد.
روش نوین
استفاده از متد navigator.setAppBadge()
متد navigator.setAppBadge() امکان افزودن یک نشان به آیکون برنامه نصبشده را فراهم میسازد. این متد یک آرگومان اختیاری دریافت میکند که یک عدد صحیح است و بهعنوان مقدار نشان استفاده میشود.
اگر این عدد صفر تعیین شود، نشان پاک خواهد شد. در صورتی که هیچ مقداری ارائه نشود، یک نشان عمومی (معمولاً بهصورت نقطهای رنگی) نمایش داده میشود.
این روش مدرن و استاندارد، تجربه کاربری بهتری را در برنامههای تحت وب فراهم میکند و بهویژه در برنامههای وب پیشرونده (PWA) نقش مؤثری در اطلاعرسانی ساده و مؤثر دارد.
روش کلاسیک: افزودن عدد به فاوآیکون
اگر برنامه هنوز نصب نشده باشد، میتوانید عددی را به فاوآیکون اضافه کنید. راههای گوناگونی برای انجام این کار وجود دارد؛ برای نمونه، میتوان فاوآیکون را بهصورت پویا بر روی یک عنصر بوم (canvas) ترسیم کرد و اطلاعات مربوط به نشان (badge) را به آن افزود و سپس آن را بهصورت یک نشانی «بلاب» (Blob URL) نمایش داد. یا میتوان تصویری از نوع SVG ساخت که اطلاعات نشان را بهصورت یک نشانی دادهای (data URL) در خود داشته باشد.
🔗https://web.dev/patterns/web-apps/badges
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
در هنگام استفاده از
تنها راهحل مؤثری که تاکنون یافته شده، غیرفعال کردن این حالت (mode) در زمان توسعه است.
نمونهای از کد مربوطه:
در این وضعیت، پیشنهاد میشود برای جلوگیری از بروز مشکل، در محیط توسعه از مقدار پیشفرض
#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
router-view
همراه با transition
و تعیین `mode="out-in"`، در حالت توسعه (dev mode)، هنگام جابهجایی بین مسیرها (routes) اغلب با مشکل نمایش صفحه سفید مواجه میشویم.تنها راهحل مؤثری که تاکنون یافته شده، غیرفعال کردن این حالت (mode) در زمان توسعه است.
نمونهای از کد مربوطه:
<router-view v-slot="{ Component }">
<Transition mode="out-in">
<component :is="Component" />
</Transition>
</router-view>
در این وضعیت، پیشنهاد میشود برای جلوگیری از بروز مشکل، در محیط توسعه از مقدار پیشفرض
mode
یا از حالتهایی مانند "in-out"
یا بدون مشخصکردن mode
استفاده شود و تنها در محیط تولید (production) از حالت out-in
بهره بگیرید، چرا که این حالت در محیط توسعه ممکن است باگهایی مانند نمایش صفحه سفید موقت ایجاد کند.#️⃣#tip #vue
👥@IR_javascript_group
🆔@IR_javascript
👍3❤1
### متا تگها: خطوطی پشتصحنه که سرنوشت وبسایت شما را رقم میزنند
متا تگها مثل پشتصحنهی یک نمایش هستند. کاربر آنها را نمیبیند، اما دقیقاً همین تگها تعیین میکنند که صفحهی وبسایت شما در نتایج جستجو، شبکههای اجتماعی و حتی مرورگر چگونه نمایش داده شود. اگر تاکنون از آنها غافل بودهاید، در واقع خودتان مسیر دریافت ترافیک، افزایش نرخ تبدیل و حتی موفقیت را محدود کردهاید.
---
### بیایید قدم به قدم بررسی کنیم: تگ
تگهای متا، تگهایی در زبان HTML هستند که در بخش
* محتوای صفحه
* قوانین ایندکس شدن در موتورهای جستجو
* نحوهی نمایش در هنگام اشتراکگذاری در شبکههای اجتماعی
* رنگ رابط کاربری در مرورگرهای موبایل
و حتی بیشتر از اینها.
(چند نمونهی کاربردی هم در تصویر بالا توضیح داده شده است.)
---
### اگر میخواهید هنگام اشتراکگذاری لینک صفحه در VK یا تلگرام، عنوان، توضیح و تصویری زیبا نمایش داده شود، بدانید که این هیچگونه جادویی نیست — این قدرت متا تگها و استاندارد Open Graph است.
---
### چند ویژگی جالب و کاربردی:
🔁 ریدایرکت خودکار پس از پنج ثانیه:
🎨 تنظیم رنگ رابط کاربری مرورگر موبایل:
---
### جمعبندی:
متا تگها صرفاً «موارد فرمالی برای رفع تکلیف» نیستند.
بلکه ابزارهایی حیاتی هستند که به شما اجازه میدهند کنترل کاملی روی نحوهی نمایش وبسایت برای کاربران و موتورهای جستجو داشته باشید.
به آنها اهمیت بدهید؛ تا وبسایت شما نهتنها از بیرون، بلکه از درون نیز حرفهای و هوشمندانه عمل کند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
متا تگها مثل پشتصحنهی یک نمایش هستند. کاربر آنها را نمیبیند، اما دقیقاً همین تگها تعیین میکنند که صفحهی وبسایت شما در نتایج جستجو، شبکههای اجتماعی و حتی مرورگر چگونه نمایش داده شود. اگر تاکنون از آنها غافل بودهاید، در واقع خودتان مسیر دریافت ترافیک، افزایش نرخ تبدیل و حتی موفقیت را محدود کردهاید.
---
### بیایید قدم به قدم بررسی کنیم: تگ
<meta>
چیست؟تگهای متا، تگهایی در زبان HTML هستند که در بخش
<head>
صفحه قرار میگیرند و اطلاعات کلی دربارهی خود صفحه را ارائه میدهند:* محتوای صفحه
* قوانین ایندکس شدن در موتورهای جستجو
* نحوهی نمایش در هنگام اشتراکگذاری در شبکههای اجتماعی
* رنگ رابط کاربری در مرورگرهای موبایل
و حتی بیشتر از اینها.
(چند نمونهی کاربردی هم در تصویر بالا توضیح داده شده است.)
---
### اگر میخواهید هنگام اشتراکگذاری لینک صفحه در VK یا تلگرام، عنوان، توضیح و تصویری زیبا نمایش داده شود، بدانید که این هیچگونه جادویی نیست — این قدرت متا تگها و استاندارد Open Graph است.
---
### چند ویژگی جالب و کاربردی:
🔁 ریدایرکت خودکار پس از پنج ثانیه:
<meta http-equiv="refresh" content="5;url=https://example.com">
🎨 تنظیم رنگ رابط کاربری مرورگر موبایل:
<meta name="theme-color" content="#317EFB">
---
### جمعبندی:
متا تگها صرفاً «موارد فرمالی برای رفع تکلیف» نیستند.
بلکه ابزارهایی حیاتی هستند که به شما اجازه میدهند کنترل کاملی روی نحوهی نمایش وبسایت برای کاربران و موتورهای جستجو داشته باشید.
به آنها اهمیت بدهید؛ تا وبسایت شما نهتنها از بیرون، بلکه از درون نیز حرفهای و هوشمندانه عمل کند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤2
در نسخهی جدید مرورگر کروم — کروم شمارهی یکصد و سی و هفت — ویژگی جدیدی برای CSS معرفی شده است که از ساختار شرطی شبیه به
نمونهای از استفادهی این قابلیت به شکل زیر است:
---
### 🆕 توضیح:
ویژگی
---
این قابلیت در حال حاضر تازه معرفی شده و احتمال دارد تنها در نسخههای آزمایشی یا با پرچم فعال باشد. برای استفادهی گستردهتر، بررسی وضعیت پشتیبانی در مرورگرها توصیه میشود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
if
پشتیبانی میکند.نمونهای از استفادهی این قابلیت به شکل زیر است:
div {
color: var(--color);
background-color: if(style(--color: white): black; else: white);
}
@media (prefers-color-scheme: dark) {
--color: black;
}
@media (prefers-color-scheme: light) {
--color: white;
}
---
### 🆕 توضیح:
ویژگی
if()
در CSS امکان میدهد بر اساس وضعیت یا مقدار یک متغیر (مثلاً --color
) تصمیمگیری شود. این ساختار شرطی باعث میشود استایلها واکنشگرا، منعطف و هوشمندانهتر شوند — بدون نیاز به JavaScript یا ساختارهای پیچیدهتر.---
این قابلیت در حال حاضر تازه معرفی شده و احتمال دارد تنها در نسخههای آزمایشی یا با پرچم فعال باشد. برای استفادهی گستردهتر، بررسی وضعیت پشتیبانی در مرورگرها توصیه میشود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
😱1😢1
اگر نیاز دارید در صفحه وب، یک فیلد قابل ویرایش برای وارد کردن متن اضافه کنید، میتوانید از ویژگی
---
### محدودسازی ورودی فقط به متن ساده
برای اینکه کاربر فقط متن ساده وارد کند (بدون HTML، تصویر یا استایل)، میتوانید مقدار
---
### نکتههای تکمیلی
میتوانید با استفاده از رویدادهای
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
contenteditable
استفاده کنید. این ویژگی، در بسیاری از مواقع جایگزین خوشایندتری نسبت به textarea
است (هرچند برای فرمهای بزرگ، جایگزین کاملی محسوب نمیشود).---
### محدودسازی ورودی فقط به متن ساده
برای اینکه کاربر فقط متن ساده وارد کند (بدون HTML، تصویر یا استایل)، میتوانید مقدار
plaintext-only
را به ویژگی contenteditable
اختصاص دهید. این کار از وارد شدن محتوای قالببندیشده جلوگیری میکند.<div
contenteditable="plaintext-only"
data-placeholder="شروع به نوشتن کنید..."
></div>
---
### نکتههای تکمیلی
میتوانید با استفاده از رویدادهای
input
و `paste`، کنترل بیشتری بر محتوای واردشده داشته باشید. مثلاً هنگام paste، با استفاده از قطعهکدی مانند زیر، محتوای HTML را به متن ساده تبدیل کنید:const text = e.clipboardData.getData('text/plain');
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
### CSS Reset
گاهی بهنظر میرسد که مرورگرهای مدرن امروزی بهطور کلی عناصر را تقریباً یکسان نمایش میدهند. اما اخیراً در تیم ما بحثی پیش آمد:
آیا واقعاً به CSS Reset نیاز داریم، وقتی «همهچیز انگار درست کار میکند»؟
این بحث برایم یادآور شد که بسیاری از توسعهدهندگان هنوز اهمیت این موضوع را دستکم میگیرند.
---
### CSS Reset یعنی چه؟
CSS Reset یک ابزار برای «زیباتر شدن کد» یا پیروی از مد نیست. بلکه روشی برای ایجاد پیشبینیپذیری، یکپارچگی و کنترل در طراحی رابط کاربری است.
در نبود CSS Reset، حتی سادهترین عناصر HTML ممکن است در مرورگرهای مختلف ظاهر متفاوتی داشته باشند و همین از همان ابتدا میتواند مشکلات غیرمنتظره ایجاد کند.
---
### چرا به CSS Reset نیاز داریم؟
هر مرورگر، بهشکل پیشفرض، HTML را با استایلهای مخصوص خود نمایش میدهد:
از جمله تعیین فاصلهها، نوع و اندازهی فونتها، نحوه نمایش تیترها و غیره.
در نتیجه، یک صفحهی وب ممکن است در مرورگرهای مختلف ظاهر کاملاً متفاوتی داشته باشد.
CSS Reset این تفاوتها را از بین میبرد و یک بستر تمیز و کنترلشده برای استایلدهی فراهم میکند.
---
### نمونهای از CSS Reset:
این تکهکد ساده، حاشیهها و فاصلههای پیشفرض را حذف کرده و رفتاری قابلپیشبینی برای
---
### رویکردهای رایج در CSS Reset:
🔹 Reset.css یا نسخه اریک مایر (Eric Meyer):
https://meyerweb.com/eric/tools/css/reset/
روشی کلاسیک و بسیار جامع که تقریباً تمام استایلهای پیشفرض را حذف میکند (اما سالهاست بهروزرسانی نشده).
🔹 Normalize.css:
https://necolas.github.io/normalize.css/
رویکردی مدرنتر که بهجای حذف کامل، استایلها را یکسانسازی میکند؛
درعینحال معنای اصلی عناصر HTML را حفظ مینماید.
🔹 Modern CSS Reset:
https://piccalil.li/blog/a-more-modern-css-reset/
https://www.joshwcomeau.com/css/custom-css-reset/
شامل نسخههایی مانند ریست اندی بل (Andy Bell) یا نسخههای سفارشی مانند ریست جاش کومو (Josh Comeau) که با دیدگاهی بهروز طراحی شدهاند.
---
📌 نکته مهم:
Reset و Normalize.css دو رویکرد متفاوتاند:
* Reset همهچیز را به «صفر» میرساند.
* Normalize سعی دارد استایلهای مفید را نگه دارد و فقط تفاوتها را بین مرورگرها همگامسازی کند.
در کاربرد روزمره، این دو گاهی با یکدیگر اشتباه گرفته میشوند، اما هدف نهایی و روش اجرا کاملاً با هم تفاوت دارند.
---
📐 با اعمال CSS Reset، میتوانید از همان ابتدا کنترل کاملتری روی نحوهی نمایش عناصر در مرورگرهای مختلف داشته باشید و از بروز ناسازگاریهای ظاهری جلوگیری کنید.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
گاهی بهنظر میرسد که مرورگرهای مدرن امروزی بهطور کلی عناصر را تقریباً یکسان نمایش میدهند. اما اخیراً در تیم ما بحثی پیش آمد:
آیا واقعاً به CSS Reset نیاز داریم، وقتی «همهچیز انگار درست کار میکند»؟
این بحث برایم یادآور شد که بسیاری از توسعهدهندگان هنوز اهمیت این موضوع را دستکم میگیرند.
---
### CSS Reset یعنی چه؟
CSS Reset یک ابزار برای «زیباتر شدن کد» یا پیروی از مد نیست. بلکه روشی برای ایجاد پیشبینیپذیری، یکپارچگی و کنترل در طراحی رابط کاربری است.
در نبود CSS Reset، حتی سادهترین عناصر HTML ممکن است در مرورگرهای مختلف ظاهر متفاوتی داشته باشند و همین از همان ابتدا میتواند مشکلات غیرمنتظره ایجاد کند.
---
### چرا به CSS Reset نیاز داریم؟
هر مرورگر، بهشکل پیشفرض، HTML را با استایلهای مخصوص خود نمایش میدهد:
از جمله تعیین فاصلهها، نوع و اندازهی فونتها، نحوه نمایش تیترها و غیره.
در نتیجه، یک صفحهی وب ممکن است در مرورگرهای مختلف ظاهر کاملاً متفاوتی داشته باشد.
CSS Reset این تفاوتها را از بین میبرد و یک بستر تمیز و کنترلشده برای استایلدهی فراهم میکند.
---
### نمونهای از CSS Reset:
/* حذف حاشیهها و تنظیم box-sizing */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
این تکهکد ساده، حاشیهها و فاصلههای پیشفرض را حذف کرده و رفتاری قابلپیشبینی برای
box-sizing
ایجاد میکند.---
### رویکردهای رایج در CSS Reset:
🔹 Reset.css یا نسخه اریک مایر (Eric Meyer):
https://meyerweb.com/eric/tools/css/reset/
روشی کلاسیک و بسیار جامع که تقریباً تمام استایلهای پیشفرض را حذف میکند (اما سالهاست بهروزرسانی نشده).
🔹 Normalize.css:
https://necolas.github.io/normalize.css/
رویکردی مدرنتر که بهجای حذف کامل، استایلها را یکسانسازی میکند؛
درعینحال معنای اصلی عناصر HTML را حفظ مینماید.
🔹 Modern CSS Reset:
https://piccalil.li/blog/a-more-modern-css-reset/
https://www.joshwcomeau.com/css/custom-css-reset/
شامل نسخههایی مانند ریست اندی بل (Andy Bell) یا نسخههای سفارشی مانند ریست جاش کومو (Josh Comeau) که با دیدگاهی بهروز طراحی شدهاند.
---
📌 نکته مهم:
Reset و Normalize.css دو رویکرد متفاوتاند:
* Reset همهچیز را به «صفر» میرساند.
* Normalize سعی دارد استایلهای مفید را نگه دارد و فقط تفاوتها را بین مرورگرها همگامسازی کند.
در کاربرد روزمره، این دو گاهی با یکدیگر اشتباه گرفته میشوند، اما هدف نهایی و روش اجرا کاملاً با هم تفاوت دارند.
---
📐 با اعمال CSS Reset، میتوانید از همان ابتدا کنترل کاملتری روی نحوهی نمایش عناصر در مرورگرهای مختلف داشته باشید و از بروز ناسازگاریهای ظاهری جلوگیری کنید.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
برنامهی توسعهی فردی: نقشهی راه اختصاصی تو در دنیای فناوری اطلاعات
همهی ما روزی با یک نقطهی بنبست در مسیر شغلیمان روبهرو شدهایم؛ مقاله میخوانیم، در دورهها شرکت میکنیم، کد میزنیم، اما پیشرفتی دیده نمیشود. پروژههای خانگی و آموزشهای ویدیویی مفیدند، اما چطور میتوان این تلاشها را به نتایج ملموس در محل کار تبدیل کرد؟
🔑 پاسخ ساده است: برنامهی توسعهی فردی (Individual Development Plan یا IDP)
---
### برنامه توسعه فردی چیست؟
IDP صرفاً یک لیست از تکنولوژیها و دورهها نیست. این یک سند راهبردی است که در آن دقیقاً مشخص میکنی چطور میخواهی رشد کنی — نه بهصورت کلی و انتزاعی، بلکه در ارتباط مستقیم با کار واقعی و اهداف محصول.
---
### چرا اینقدر مهم است؟
۱. اهداف را شفاف تعریف میکنی:
بهجای «یادگیری TypeScript»، میگویی:
«ماژول لاگین را به TypeScript منتقل میکنم، برای آن تست مینویسم و در CI ادغامش میکنم».
این مسیر رشد صرفاً برای رشد نیست، بلکه برای اثرگذاری واقعی است.
۲. معیار و ضربالاجل تعیین میکنی:
عباراتی مثل «بهبود عملکرد» کافی نیستند. باید هدف مشخص باشد، مثلاً:
«کاهش زمان بارگذاری قابل تعامل (Time to Interactive) صفحه اصلی به کمتر از دو ثانیه، طی دو اسپرینت».
این سبک هدفگذاری پیگیری پیشرفت و ارائه مستندات را آسان میکند.
۳. ادغام در جریان کاری واقعی:
اهداف این برنامه نباید فقط در نوتها بمانند. آنها باید وارد بکلاگ تیم در ابزارهایی مانند Jira یا Trello شوند، و مدام در جریان کار باشند. در غیر این صورت، همهچیز با جملهی آشنا تمام میشود:
«میخواستم، ولی نشد...»
۴. ارزیابی مستمر:
پیشرفت خود را با تیملید در میان بگذار، بازخورد بگیر و در صورت نیاز جهتگیری را اصلاح کن.
اینجا همان نقطهای است که اهداف شخصی با اهداف محصول و سازمان همراستا میشوند.
---
### چطور یک IDP پنجمرحلهای بسازیم؟
۱. تحلیل سطح فعلی خودت:
صادقانه ارزیابی کن: کجا «عالی» هستی و کجا هنوز «ضعیف»؟
(مثلاً: تستنویسی، DevOps، اصول شیگرایی و غیره)
۲. انتخاب سه تا چهار مسیر کلیدی رشد:
مثلاً: طراحی کامپوننتها (Atomic Design)، بهینهسازی عملکرد وب، تست، سیستمعاملهای یونیکس، شبکه، یا مهارتهای نرم (ارائه، بازبینی کد و غیره)
۳. تعریف اهداف SMART:
اهدافی مشخص، قابل اندازهگیری، دستیافتنی، مرتبط با کار و زمانبندیشده.
۴. ادغام با روند کاری واقعی:
تسکها را در ابزارهای مدیریت پروژه ثبت کن و مدام بهروز نگهدار. بگذار جلوی چشمت بمانند تا تمرکز حفظ شود.
۵. بررسی و بازنگری:
در پایان هر ماه یا اسپرینت، یک مرور کوچک برگزار کن:
چه چیزی پیش رفت؟ چه چیزی عقب افتاد؟ چه عواملی مانع شدند؟ چه چیز باید اصلاح شود؟
---
### مزایا برای سطوح مختلف شغلی
* توسعهدهندهی تازهکار (Junior): مسیر روشن برای ورود به پروژه و تقویت مهارتهای پایه
* میانرده (Middle): توانایی سنجش تأثیرگذاری و طراحی معماری
* ارشد (Senior): گسترش تخصص، پیادهسازی استانداردهای حرفهای و هدایت تیم
---
با یک برنامهی توسعهی فردی دقیق، دیگر فقط «دوره نمیگذرانی»؛
بلکه تغییرات واقعی در دانش و محصولت را مستند میکنی.
🎯 وقت آن است که دست به کار شوی!
پینوشت: در بسیاری از شرکتها، **ارتقا شغلی و افزایش سطح مسئولیت**، دقیقاً به همین برنامههای توسعهی فردی دقیق و اجراشده بستگی دارد.
#️⃣#discussion
👥@IR_javascript_group
🆔@IR_javascript
همهی ما روزی با یک نقطهی بنبست در مسیر شغلیمان روبهرو شدهایم؛ مقاله میخوانیم، در دورهها شرکت میکنیم، کد میزنیم، اما پیشرفتی دیده نمیشود. پروژههای خانگی و آموزشهای ویدیویی مفیدند، اما چطور میتوان این تلاشها را به نتایج ملموس در محل کار تبدیل کرد؟
🔑 پاسخ ساده است: برنامهی توسعهی فردی (Individual Development Plan یا IDP)
---
### برنامه توسعه فردی چیست؟
IDP صرفاً یک لیست از تکنولوژیها و دورهها نیست. این یک سند راهبردی است که در آن دقیقاً مشخص میکنی چطور میخواهی رشد کنی — نه بهصورت کلی و انتزاعی، بلکه در ارتباط مستقیم با کار واقعی و اهداف محصول.
---
### چرا اینقدر مهم است؟
۱. اهداف را شفاف تعریف میکنی:
بهجای «یادگیری TypeScript»، میگویی:
«ماژول لاگین را به TypeScript منتقل میکنم، برای آن تست مینویسم و در CI ادغامش میکنم».
این مسیر رشد صرفاً برای رشد نیست، بلکه برای اثرگذاری واقعی است.
۲. معیار و ضربالاجل تعیین میکنی:
عباراتی مثل «بهبود عملکرد» کافی نیستند. باید هدف مشخص باشد، مثلاً:
«کاهش زمان بارگذاری قابل تعامل (Time to Interactive) صفحه اصلی به کمتر از دو ثانیه، طی دو اسپرینت».
این سبک هدفگذاری پیگیری پیشرفت و ارائه مستندات را آسان میکند.
۳. ادغام در جریان کاری واقعی:
اهداف این برنامه نباید فقط در نوتها بمانند. آنها باید وارد بکلاگ تیم در ابزارهایی مانند Jira یا Trello شوند، و مدام در جریان کار باشند. در غیر این صورت، همهچیز با جملهی آشنا تمام میشود:
«میخواستم، ولی نشد...»
۴. ارزیابی مستمر:
پیشرفت خود را با تیملید در میان بگذار، بازخورد بگیر و در صورت نیاز جهتگیری را اصلاح کن.
اینجا همان نقطهای است که اهداف شخصی با اهداف محصول و سازمان همراستا میشوند.
---
### چطور یک IDP پنجمرحلهای بسازیم؟
۱. تحلیل سطح فعلی خودت:
صادقانه ارزیابی کن: کجا «عالی» هستی و کجا هنوز «ضعیف»؟
(مثلاً: تستنویسی، DevOps، اصول شیگرایی و غیره)
۲. انتخاب سه تا چهار مسیر کلیدی رشد:
مثلاً: طراحی کامپوننتها (Atomic Design)، بهینهسازی عملکرد وب، تست، سیستمعاملهای یونیکس، شبکه، یا مهارتهای نرم (ارائه، بازبینی کد و غیره)
۳. تعریف اهداف SMART:
اهدافی مشخص، قابل اندازهگیری، دستیافتنی، مرتبط با کار و زمانبندیشده.
۴. ادغام با روند کاری واقعی:
تسکها را در ابزارهای مدیریت پروژه ثبت کن و مدام بهروز نگهدار. بگذار جلوی چشمت بمانند تا تمرکز حفظ شود.
۵. بررسی و بازنگری:
در پایان هر ماه یا اسپرینت، یک مرور کوچک برگزار کن:
چه چیزی پیش رفت؟ چه چیزی عقب افتاد؟ چه عواملی مانع شدند؟ چه چیز باید اصلاح شود؟
---
### مزایا برای سطوح مختلف شغلی
* توسعهدهندهی تازهکار (Junior): مسیر روشن برای ورود به پروژه و تقویت مهارتهای پایه
* میانرده (Middle): توانایی سنجش تأثیرگذاری و طراحی معماری
* ارشد (Senior): گسترش تخصص، پیادهسازی استانداردهای حرفهای و هدایت تیم
---
با یک برنامهی توسعهی فردی دقیق، دیگر فقط «دوره نمیگذرانی»؛
بلکه تغییرات واقعی در دانش و محصولت را مستند میکنی.
🎯 وقت آن است که دست به کار شوی!
پینوشت: در بسیاری از شرکتها، **ارتقا شغلی و افزایش سطح مسئولیت**، دقیقاً به همین برنامههای توسعهی فردی دقیق و اجراشده بستگی دارد.
#️⃣#discussion
👥@IR_javascript_group
🆔@IR_javascript
در مواقعی که در یک پروژهی CSS، ترتیب بارگذاری استایلها بههم میریزد و استایلها با یکدیگر تداخل پیدا میکنند، دیرکتیو `@layer` یا همان *لایههای آبشاری CSS (CSS Cascade Layers)* میتواند راهحل مناسبی باشد.
این ویژگی، یک ساختار سلسلهمراتبی شفاف برای استایلها ایجاد میکند — برای مثال، لایههایی مانند
### چطور یک لایه تعریف کنیم؟
خیلی ساده:
### و چطور ترتیب لایهها را مشخص کنیم؟
باز هم خیلی ساده:
---
### اما اولویتبندی چطور عمل میکند؟
* قوانین خارج از `@layer` همیشه بر قوانین عادی (غیر
* اگر ترتیب مشخصی برای لایهها تعیین نشده باشد (یعنی `@layer reset, base;` نیامده باشد)، **ترتیب اولین تعریف هر لایه در فایل CSS تعیینکننده خواهد بود.
* درون یک لایه**، قواعد مانند همیشه عمل میکنند: قانون با **ویژگیمندی (specificity) بالاتر برنده است؛ در صورت برابر بودن ویژگیمندی، قانونی که دیرتر نوشته شده**، اعمال خواهد شد.
* اما برای قوانین `!important`، این منطق **برعکس است؛ یعنی ترتیب تعریف لایهها مهمتر از موقعیت خط یا ویژگیمندی خواهد بود.
---
### جمعبندی
ویژگی `@layer`:
* ترتیب استایلها را قابلپیشبینی میکند؛
* از بروز مشکلات مربوط به ویژگیمندی جلوگیری میکند؛
* و نیاز به
اگر به دنبال کدنویسی CSS حرفهای، ساختیافته و قابل نگهداری هستید، توصیه میشود از
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
این ویژگی، یک ساختار سلسلهمراتبی شفاف برای استایلها ایجاد میکند — برای مثال، لایههایی مانند
core`، `reset`، `base
— و در بسیاری از موارد، شما را از استفادهی بیرویه از !important
بینیاز میسازد.### چطور یک لایه تعریف کنیم؟
خیلی ساده:
@layer reset {
*, ::before, ::after {
box-sizing: border-box;
margin: ۰;
padding: ۰;
}
}
### و چطور ترتیب لایهها را مشخص کنیم؟
باز هم خیلی ساده:
@layer reset, base;
---
### اما اولویتبندی چطور عمل میکند؟
* قوانین خارج از `@layer` همیشه بر قوانین عادی (غیر
!important
) داخل لایهها غلبه دارند**، فارغ از اینکه چه زمانی تعریف شده باشند.* اگر ترتیب مشخصی برای لایهها تعیین نشده باشد (یعنی `@layer reset, base;` نیامده باشد)، **ترتیب اولین تعریف هر لایه در فایل CSS تعیینکننده خواهد بود.
* درون یک لایه**، قواعد مانند همیشه عمل میکنند: قانون با **ویژگیمندی (specificity) بالاتر برنده است؛ در صورت برابر بودن ویژگیمندی، قانونی که دیرتر نوشته شده**، اعمال خواهد شد.
* اما برای قوانین `!important`، این منطق **برعکس است؛ یعنی ترتیب تعریف لایهها مهمتر از موقعیت خط یا ویژگیمندی خواهد بود.
---
### جمعبندی
ویژگی `@layer`:
* ترتیب استایلها را قابلپیشبینی میکند؛
* از بروز مشکلات مربوط به ویژگیمندی جلوگیری میکند؛
* و نیاز به
!important
را تا حد زیادی کاهش میدهد.اگر به دنبال کدنویسی CSS حرفهای، ساختیافته و قابل نگهداری هستید، توصیه میشود از
@layer
در پروژههای مدرن خود استفاده کنید.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🤬1😡1
دامِ جاوااسکریپت: مقایسهی `parseInt("")
گاهی ممکن است فکر کنید که `parseInt("")` و `Number("")` رفتار یکسانی دارند.
اما اینطور نیست، و اگر تفاوت آنها را ندانید، ممکن است باگهای عجیبی در برنامهتان بهوجود بیاید — مخصوصاً هنگام کار با پارامترهای URL.
### بیایید رفتار آنها را بررسی کنیم:
### چه اتفاقی میافتد؟
* `parseInt("")` تلاش میکند رشته را بهصورت عددی، کاراکتر به کاراکتر تجزیه کند.
اما چون رشته خالی است، چیزی برای تجزیه وجود ندارد، در نتیجه: `NaN` (یعنی Not a Number).
* `Number("")` بر اساس قوانین داخلی تبدیل نوع در جاوااسکریپت، رشته را به عدد تبدیل میکند.
رشتهی خالی طبق این قوانین معادل صفر در نظر گرفته میشود، در نتیجه: `۰`.
---
### یک مثال کاربردی: صفحهبندی کالاها
فرض کنید در وبسایتتان صفحهای برای نمایش محصولات دارید و آدرس URL به این صورت است:
پارامترها را اینطور دریافت میکنید:
در اینجا:
* `params.get("page")
* `Number("")` آن را تبدیل به عدد صفر میکند؛
* در نتیجه، صفحهای با شمارهی صفر در منطق برنامه جایگزین میشود، در حالیکه چنین صفحهای اصلاً تعریف نشده!
ممکن است کاربر با صفحهی خالی، خطا یا محتوای نادرست مواجه شود.
---
### راهکار ایمنتر:
در این روش:
* مقدار خام را میگیریم؛
* با `parseInt` آن را تبدیل میکنیم؛
* اگر نتیجه `NaN` یا عددی کمتر از یک بود، مقدار پیشفرض یک را جایگزین میکنیم.
این روش قابلاعتمادتر است، زیرا `parseInt("")` خروجی `NaN` میدهد و بهوضوح نشان میدهد که داده نامعتبر است.
---
### جمعبندی:
* `Number("") → ۰` ممکن است بهظاهر بیدردسر باشد، اما در عمل میتواند منطق برنامه را بیسروصدا خراب کند.
* `parseInt("") → NaN` بهروشنی هشدار میدهد که داده مشکل دارد.
در جاوااسکریپت، همیشه خطاها فریاد نمیزنند!
گاهی با لبخند میگویند: «همهچی خوبه»، و بعد یک صفر بیربط تحویلتان میدهند.
و شما میمانید با این سؤال:
«چرا هیچ کالایی توی صفحه نمایش داده نمیشه؟!» 🤨
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
با `Number("")
گاهی ممکن است فکر کنید که `parseInt("")` و `Number("")` رفتار یکسانی دارند.
اما اینطور نیست، و اگر تفاوت آنها را ندانید، ممکن است باگهای عجیبی در برنامهتان بهوجود بیاید — مخصوصاً هنگام کار با پارامترهای URL.
### بیایید رفتار آنها را بررسی کنیم:
parseInt("") // ← نتیجه: NaN
Number("") // ← نتیجه: ۰
### چه اتفاقی میافتد؟
* `parseInt("")` تلاش میکند رشته را بهصورت عددی، کاراکتر به کاراکتر تجزیه کند.
اما چون رشته خالی است، چیزی برای تجزیه وجود ندارد، در نتیجه: `NaN` (یعنی Not a Number).
* `Number("")` بر اساس قوانین داخلی تبدیل نوع در جاوااسکریپت، رشته را به عدد تبدیل میکند.
رشتهی خالی طبق این قوانین معادل صفر در نظر گرفته میشود، در نتیجه: `۰`.
---
### یک مثال کاربردی: صفحهبندی کالاها
فرض کنید در وبسایتتان صفحهای برای نمایش محصولات دارید و آدرس URL به این صورت است:
https://example.com/products?page=&limit=10
پارامترها را اینطور دریافت میکنید:
const params = new URLSearchParams(location.search);
const page = Number(params.get("page"));
const limit = Number(params.get("limit"));
در اینجا:
* `params.get("page")
مقدار رشتهی خالی (
""`) برمیگرداند؛* `Number("")` آن را تبدیل به عدد صفر میکند؛
* در نتیجه، صفحهای با شمارهی صفر در منطق برنامه جایگزین میشود، در حالیکه چنین صفحهای اصلاً تعریف نشده!
ممکن است کاربر با صفحهی خالی، خطا یا محتوای نادرست مواجه شود.
---
### راهکار ایمنتر:
const pageRaw = params.get("page");
const page = parseInt(pageRaw);
const safePage = Number.isNaN(page) || page < ۱ ? ۱ : page;
در این روش:
* مقدار خام را میگیریم؛
* با `parseInt` آن را تبدیل میکنیم؛
* اگر نتیجه `NaN` یا عددی کمتر از یک بود، مقدار پیشفرض یک را جایگزین میکنیم.
این روش قابلاعتمادتر است، زیرا `parseInt("")` خروجی `NaN` میدهد و بهوضوح نشان میدهد که داده نامعتبر است.
---
### جمعبندی:
* `Number("") → ۰` ممکن است بهظاهر بیدردسر باشد، اما در عمل میتواند منطق برنامه را بیسروصدا خراب کند.
* `parseInt("") → NaN` بهروشنی هشدار میدهد که داده مشکل دارد.
در جاوااسکریپت، همیشه خطاها فریاد نمیزنند!
گاهی با لبخند میگویند: «همهچی خوبه»، و بعد یک صفر بیربط تحویلتان میدهند.
و شما میمانید با این سؤال:
«چرا هیچ کالایی توی صفحه نمایش داده نمیشه؟!» 🤨
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript