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

🆔@IR_javascript
Download Telegram
‏CSS بالاخره امکان انیمیشن دادن به عناصر هنگام اولین نمایش آن‌ها را فراهم کرد
‏@starting-style اکنون بخشی از Baseline محسوب می‌شود و از اوت دو هزار و بیست‌وچهار در دسترس قرار گرفته است. در حال حاضر حدود نود درصد پوشش جهانی دارد!
پیش از این، transition هنگام اولین تغییر استایل یک عنصر اجرا نمی‌شد و مجبور بودیم با ترفندهای مختلف در جاوااسکریپت این مشکل را دور بزنیم.
حالا می‌توان حالت اولیه‌ی عنصر را مستقیماً با CSS خالص تعریف کرد. ساده، قدرتمند و قابلیتی که مدت‌ها جای آن خالی بود 💪‏

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript`
👌2❤1
This media is not supported in your browser
VIEW IN TELEGRAM
با اعمال position: sticky روی سربرگ جدول، می‌توان یک پیاده‌سازی زیبا و قابل‌فهم از هدر چسبان (Sticky Header) داشت.
اما یک مشکل وجود دارد: هنگام اسکرول، آخرین ردیف جدول زیر همین سربرگ مخفی می‌شود و ظاهر چندان خوبی ندارد؛ مخصوصاً زمانی که جدول فقط شامل متن ساده نیست و مواردی مانند شرایط مقایسه، تصاویر و موارد مشابه در آن وجود دارد.
اما راه‌حل ساده است!
کافی است به thead یک margin-bottom به اندازه‌ی ارتفاع کامل یک ردیف اضافه کنیم:
margin-bottom: calc(1lh + 20px);

توجه کنید که 1lh یک واحد اندازه‌گیری واقعی در CSS است که اجازه می‌دهد به مقدار line-height یا همان ارتفاع خط دسترسی داشته باشیم.
البته جمع کردن مار با طوطی را که همیشه بلد بودیم!
بله، شاید در نگاه اول چندان بدیهی نباشد، اما نتیجه این است که جدول حالا ظاهر فوق‌العاده‌ای پیدا می‌کند:


🔗https://codepen.io/alinaki/pen/JojeGMY?editors=0100
#️⃣#tip #css #code
👥@IR_javascript_group
🆔@IR_javascript`
👍3
واژهٔ «مدل» این روزها معمولاً چیزی با هفت تا هفتاد میلیارد پارامتر و ده‌ها گیگابایت وزن را در ذهن تداعی می‌کند. اما مدل اصلاً مجبور نیست چنین ابعادی داشته باشد.
کتابخانه‌ای به نام gpu-lexer ساخته شده است؛ یک کتابخانه برای هایلایت کردن کد که به‌جای مجموعه‌ای از گرامرها، از یک مدل آموزش‌دیده با تنها چهل‌ویک هزار و سیصد و بیست‌ویک پارامتر استفاده می‌کند.
وزن‌های مدل با دقت شش‌بیتی فشرده شده‌اند و کل بستهٔ مورد استفاده در مرورگر، در حالت فشرده، تنها بیست‌وهفت ممیز چهار کیلوبایت حجم دارد.
این کتابخانه از طریق WebGPU اجرا می‌شود.
برای مقایسه، نویسنده حجم تقریبی صد و شصت‌ودو کیلوبایت برای Prism، دویست‌وچهل کیلوبایت برای Highlight.js و نهصد و نودودو کیلوبایت برای مجموعهٔ کامل Shiki را ذکر می‌کند.
البته این رویکرد اساساً مبتنی بر یادگیری ماشین است؛ بنابراین نتیجه مانند روش‌های مبتنی بر قواعد، قطعی و تضمین‌شده نیست. خروجی آن با Shiki در حدود هشتادوهشت تا نود درصد توکن‌ها مطابقت دارد.
🔗https://gpu-lexer.vercel.app/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript`
❤1
مثلاً gitignore. که دیگر کاملاً مشخص است. اما gitattributes. چطور؟
این فایل کمک می‌کند مشخص کنیم با فایل‌های مختلف چه رفتاری داشته باشیم. مثلاً استراتژی ادغام: به Git می‌گوید اگر هنگام merge تعارضی در package-lock.json ایجاد شد، نسخهٔ شاخهٔ فعلی (ours) را نگه دار
package-lock.json merge=ours 

و تمام؛ مسئله به شکل موردنظر حل می‌شود. یا فرض کنید دارید برای چند پلتفرم مختلف توسعه می‌دهید:
*.sh text eol=lf
*.bat text eol=crlf

اهمیت خطوط بالا برای خود Git این است که Git باید بتواند تشخیص دهد تغییرات یک فایل واقعاً تغییر محتوایی بوده یا فقط به‌خاطر تفاوت سیستم‌عامل، پایان خط‌ها عوض شده است.
مثلاً فرض کن روی ویندوز فایل این‌طور باشد:
line 1\r\n
line 2\r\n
line 3\r\n

و روی Linux همان فایل:
line 1\n
line 2\n
line 3\n

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

#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
❤2
فرض کن یک نفر در طول زمان با چند ایمیل مختلف commit زده:
Ali Ahmadi <ali@gmail.com>
Ali Ahmadi <ali@company.com>
A. Ahmadi <ali@old-company.com>

از نظر Git این‌ها سه هویت متفاوت به نظر می‌رسند.
اما می‌خواهی Git همه را به این هویت نسبت بدهد:
Ali Ahmadi <ali@company.com>

در .mailmap می‌توانی بنویسی:
Ali Ahmadi <ali@company.com> <ali@gmail.com>
Ali Ahmadi <ali@company.com> <ali@old-company.com>

یعنی:
هر commit قدیمی که با
ali@gmail.com
ثبت شده، در گزارش‌های Git با
Ali Ahmadi <ali@company.com>
نمایش داده شود.

#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
فرض کن در پروژه‌تان می‌خواهید همهٔ اعضای تیم پیام Commit را یک‌شکل بنویسند.
مثلاً به‌جای اینکه هرکس هر چیزی بنویسد:
fix login
login bug
update
تغییرات لاگین
fix stuff

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

توضیحات:
- چه چیزی تغییر کرد؟
- چرا تغییر کرد؟

اول یک فایل قالب می‌سازی
مثلاً:
.gitmessage

داخلش:
<type>: <short description>

Why:
-

What:
-

بعد به Git می‌گویی از این فایل به‌عنوان قالب Commit استفاده کند:
git config --global commit.template ~/.gitmessage

حالا وقتی بزنی:
git commit

ویرایشگر Git با این قالب باز می‌شود:
feat: <short description>

Why:
-

What:
-

مثلاً آن را کامل می‌کنی:
feat: add inactivity logout

Why:
- Automatically logout inactive users after 15 minutes.

What:
- Added inactivity monitor
- Added activity tracking to API requests
- Added automatic redirect to login

بعد فایل را ذخیره می‌کنی و Commit ساخته می‌شود.

#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👍2👎1
<mermaid-element>

یک کتابخانهٔ کاربردی دیگر. براموس یک عنصر سفارشی (Custom Element) توسعه داده است که می‌توان سینتکس نمودارهای Mermaid را درون آن قرار داد و نمودار به‌صورت خودکار در صفحه رندر می‌شود.
اگر با Mermaid آشنایی ندارید، باید گفت که Mermaid ابزاری است که سینتکس متنی مانند
sequenceDiagram
Alice->>John: Hello John, how are you?
John-->>Alice: Great!
Alice-)John: See you later!

را به یک نمودار توالی (Sequence Diagram) تبدیل می‌کند.
علاوه بر نمودارهای توالی، بیش از سی نوع نمودار مختلف را نیز پشتیبانی می‌کند؛ نمودارهایی که می‌توان از آن‌ها در مستندسازی و فرایندهای کاری مختلف استفاده کرد.



🔗https://www.bram.us/2026/09/10/introducing-mermaid-element-a-custom-element-to-display-mermaid-diagrams/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript`
❤1👍1
MicroLighter


اول اینکه بر پایهٔ TextMate کار می‌کند؛ بنابراین اگر به گرامر خاصی نیاز داشته باشید، اضافه کردن آن نسبتاً ساده است.

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

سوم اینکه در HTML شما «دست‌کاری اضافه» ایجاد نمی‌کند. دلیلش این است که در پشت صحنه از Custom Highlight API استفاده می‌کند؛ یعنی برای نشانه‌گذاری بخش‌های مختلف کد، تعداد زیادی span و div به ساختار HTML اضافه نمی‌کند، بلکه از قابلیت‌های داخلی مرورگر استفاده می‌کند تا بعداً بتواند با ::highlight(token) در CSS، استایل مناسب را روی بخش‌های مختلف اعمال کند.

احتمالاً در اینجا دوباره می‌گویید: «پس حتماً به‌جز Chrome و آن هم پشت یک فلگ، جای دیگری کار نمی‌کند!» من هم تا همین امروز صبح همین تصور را داشتم. اما ظاهراً از مارس سال دو هزار و بیست‌وشش این API در تمام مرورگرهای اصلی به‌طور کامل قابل استفاده است.

بنابراین می‌توانید یک راهکار بارگذاری هوشمند داشته باشید؛ به این صورت که برای مرورگرهای مدرن از MicroLighter استفاده کنید و برای مرورگرهای قدیمی‌تر یک هایلایتر جایگزین در نظر بگیرید. یا اگر هایلایت کردن کد در برنامهٔ شما بیشتر یک قابلیت جانبی و تکمیلی است، می‌توانید فقط MicroLighter را بارگذاری کنید و کار را ساده نگه دارید

🔗https://davatron5000.github.io/microlighter/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript`
‏Uppy شش: آپلودکنندهٔ ماژولار فایل برای جاوااسکریپت

امکان آپلود قابل‌ادامه از دیسک، دراپ‌باکس یا گوگل‌درایو، همراه با بسته‌های سازگار برای React، Vue، Svelte و Angular. تمرکز این نسخه بر ساده‌سازی و پاک‌سازی ساختار است؛ از جمله بازنویسی افزونهٔ S3 و کاهش تعداد بسته‌هایی که باید مدیریت شوند.


🔗https://uppy.io/blog/uppy-6.0/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript`
❤1
دیگر به initial-scale نیازی ندارید

احتمالاً در جایی از کدهای رابط کاربری‌تان، عبارت <meta name="viewport" content="width=device-width,initial-scale=1"> وجود دارد. تقریباً همه این مورد را دارند؛ چون Emmet آن را به‌صورت خودکار اضافه می‌کند و قالب‌های مختلف Bootstrap هم همین کار را انجام می‌دهند.
اما نکته اینجاست که می‌توانید initial-scale را حذف کنید. این ویژگی در گذشته لازم بود تا چرخاندن صفحه در آیفون رفتاری مشابه سایر گوشی‌های هوشمند داشته باشد. اما اپل مدت‌هاست این ناسازگاری را برطرف کرده است.
پس می‌توانیم چند بایت از حجم کد را هم صرفه‌جویی کنیم.


🔗https://quirksmode.org/quirksblog/2026/0902-initial.html
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript`
👍3
‏TanStack کتابخانهٔ Hotkeys را منتشر کرده است؛ کتابخانه‌ای برای مدیریت میانبرهای صفحه‌کلید.

بله، مدت‌هاست کتابخانه‌هایی مثل react-hotkeys-hook، hotkeys-js و Mousetrap وجود دارند و بعضی از آن‌ها قابلیت‌هایی مثل scope، ref، sequence و ضبط ماکرو را هم ارائه می‌کنند.

اما در TanStack Hotkeys همهٔ این قابلیت‌ها از ابتدا به‌عنوان بخشی از یک سیستم فرمان واحد در نظر گرفته شده‌اند.
اسکوپ ها, توالی کلیدها، تشخیص نگه‌داشتن کلید، رویداد keyup، تغییر مجدد میانبرها (rebinding)، مدیریت تداخل میانبرها، استفاده از Mod برای پشتیبانی از Ctrl/Cmd، نمایش ترکیب کلیدها متناسب با پلتفرم، کار با عناصر قابل ویرایش و حتی DevTools.
تقریباً همهٔ این قابلیت‌ها را می‌شد پیش از این، هرکدام در جایی پیدا کرد. سؤال این است که برای اینکه همهٔ این امکانات را یک‌جا داشته باشید، چند کتابخانه و چه مقدار کد اختصاصی باید در اطراف یک keydown ساده جمع می‌کردید.
آه، بله؛ طبیعتاً Framework-agnostic هم هست.

فعلاً در مرحلهٔ Alpha است، اما بد نیست مستنداتش را بخوانید؛ دست‌کم برای اینکه ببینید مدیریت میانبرهای صفحه‌کلید در عمل چه تعداد جزئیات و ظرافت دارد.


🔗https://tanstack.com/hotkeys/latest
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript`
👍2
‏🤩 tinyjs: ساخت برنامه‌های دسکتاپ جاوااسکریپتی با حجمی کمتر از ده مگابایت
با استفاده از این ابزار یک برنامه ساختم و واقعاً تحت تأثیر قرار گرفتم. در اختیار شما یک بک‌اند مبتنی بر txiki.js با دسترسی کامل به سیستم، از جمله FFI (برنامه می‌تواند به قابلیت‌های سطح پایین سیستم‌عامل هم دسترسی داشته باشد)، قرار می‌گیرد؛ در کنار آن، رندرینگ WebView به‌صورت بومی و نسخه‌های بسیار کم‌حجم برای macOS، Linux و Windows ارائه می‌شود. حتی فرایند امضای دیجیتال و نوتاریز کردن (مثلاً وقتی یک برنامه برای macOS می‌سازی، اپل قبل از توزیع عمومی آن می‌تواند برنامه را بررسی کند تا مشخص شود حاوی بدافزار یا موارد مخرب شناخته‌شده نیست. اگر تأیید شود، اپل آن را Notarize می‌کند.) نسخه نهایی برنامه نیز به‌سادگی انجام می‌شود.


#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
❤2
پیش‌نمایش تصاویر

در برخی وب‌سایت‌ها که لازم است تصاویر با کیفیت بالا نمایش داده شوند، برای بهبود تجربه کاربری از تصاویر جایگزین کم‌کیفیت استفاده می‌شود. این تصاویر تا زمانی که نسخه اصلی در حال بارگذاری است، دیدی کلی از برخی جزئیات و رنگ‌های تصویر اصلی به کاربر می‌دهند.
این تکنیک با نام LQIP یا Low Quality Image Placeholder نیز شناخته می‌شود و روش‌های مختلفی برای پیاده‌سازی آن وجود دارد؛ حتی با استفاده از CSS. بااین‌حال، روش رایج‌تر این است که یک تصویر از پیش آماده‌شده را به‌صورت پس‌زمینه و در قالب Data URL مبتنی بر Base64 در صفحه قرار دهیم.
<img
src="high-quality.webp"
style="background-image: url(
data:image/png;base64,...
)"
width="..."
height="..."
alt="..."
>

‌‏
‏<img> یک عنصر جایگزین‌شونده (replaced element) است. هنگام بارگذاری تصویری که در src مشخص شده، این عنصر عملاً مانند یک محفظه معمولی است که می‌توان برای آن در CSS پس‌زمینه تعیین کرد. تصویر کوچک و محوشده نیز به‌صورت Base64 در HTML قرار می‌گیرد تا برای نمایش آن نیازی به یک درخواست شبکه جداگانه نباشد.

در نتیجه، کاربر بلافاصله یک تصویر محوشده می‌بیند که نمایی کلی از تصویر اصلی ارائه می‌دهد؛ در همین زمان، نسخه باکیفیت تصویر در پس‌زمینه در حال بارگذاری است. پس از بارگذاری نسخه اصلی، محتوای <img> با آن جایگزین می‌شود و پس‌زمینه دیگر کاربردی نخواهد داشت.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤2
This media is not supported in your browser
VIEW IN TELEGRAM
یکی پیدا بشه جلوی این دیوانگی رو بگیره! 😄
یک کتابخانه دیگه برای هایلایت سینتکس — twinkleplop. باز هم رکوردهای سرعت و حجم شکسته شده! باز هم API بهتر و بهینه‌تر شده.


🔗https://twinkleplop.pngwn.at/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍2
This media is not supported in your browser
VIEW IN TELEGRAM
نکته‌ای درباره CSS
تابع contrast-color() به مرورگر اجازه می‌دهد رنگ متن مناسب برای دکمه را به‌صورت خودکار انتخاب کند.
.button {
--bg: hsl(55 88% 52%);
background: var(--bg);
color: contrast-color(var(--bg));
}

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

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
❤2👍1
‏Node.js بیست‌وشش ممیز ده — پشتیبانی بومی از throttle و debounce


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
استفاده از border-radius به این شکل:
 border-radius: calc(sign(100lvw - 100%) * 40px).


وقتی یک عنصر کل صفحه را اشغال می‌کند، گرد کردن گوشه‌ها به طور خودکار حذف می‌شود.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤3
‏Chrome ۱۵۴ — تغییر اندازهٔ تطبیقی iframe
از این به بعد <iframe> می‌تواند اندازهٔ خودش را متناسب با ابعاد سندی که داخل آن نمایش داده می‌شود، تغییر دهد.
مگر نه اینکه سازندگان ویجت‌ها و افزونه‌ها سال‌ها منتظر چنین قابلیتی بودند؟ 😆
دیگر نیازی نیست برای این کار از postMessage({resize}) استفاده شود.
https://bram.us/2026/09/23/responsive-iframes/

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
دنبال یک کامپوننت برای نمایش ساعت شهرهای مختلف جهان بودم که به این اسلایدر World Clock از Jon Kantner برخوردم.
سادگی، تعامل روان و طراحی بصری جذاب آن باعث شده کامپوننتی بسیار دلنشین و قابل‌فهم باشد؛ طوری که تقریباً در همان نگاه اول می‌توان نحوهٔ کار با آن را متوجه شد.
قطعاً منبع الهام خیلی خوبی است. :)
https://codepen.io/jkantner/pen/pvjNNVz

#️⃣#code
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
برش متن برای یک خط
وقتی می‌خواهیم متن فقط در یک خط نمایش داده شود، می‌توانیم ویژگی white-space را روی مقدار nowrap تنظیم کنیم. اگر متن طولانی باشد و عرض کانتینر، مثلاً، سیصد پیکسل باشد، متن همچنان در یک خط باقی می‌ماند، اما از محدودهٔ کانتینر خارج می‌شود.
برای برش متن می‌توان از ویژگی‌های زیر استفاده کرد:
.truncated-text {
width: 300px;
overflow: hidden; /* هر چیزی را که از محدودهٔ کانتینر خارج شود، مخفی می‌کند */
text-overflow: ellipsis; /* متن مخفی‌شده را با سه‌نقطه جایگزین می‌کند */
white-space: nowrap; /* متن را در یک خط نگه می‌دارد */
}



#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
‏HTML یک وظیفهٔ دیگر را هم از JavaScript گرفت
ویژگی‌های command و commandfor از دسامبر سال دو هزار و بیست‌وپنج وارد Baseline شده‌اند.
قبلاً برای باز کردن یک پنجرهٔ گفت‌وگو باید از addEventListener + showModal() استفاده می‌کردیم.
حالا می‌توان این کار را به شکل زیر انجام داد:

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript