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

🆔@IR_javascript
Download Telegram
Dragscroll

اسکرول محتوا با موس اغلب محدود به استفاده از نوارهای اسکرول استاندارد است. کتابخانه dragscroll رفتار اسکرول با کشیدن (drag) را به رابط‌های دسکتاپ اضافه می‌کند، رفتاری که کاربران در دستگاه‌های لمسی به آن عادت دارند.

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

🔗http://asvd.github.io/dragscroll/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
آیا می‌دانستید که واژه‌ی روزمره‌ی «جاوااسکریپت» در واقع به‌عنوان یک علامت تجاری در مالکیت شرکت Oracle است؟

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

اوراکل این علامت تجاری را از شرکت Sun Microsystems به ارث برد؛ یادگاری از یک تلاش شکست‌خورده برای هم‌برندسازی با «جاوا». اما اکنون، پس از گذشت بیست‌وپنج سال، «جاوااسکریپت» دیگر یک برند نیست، بلکه نام عمومی محبوب‌ترین زبان برنامه‌نویسی جهان است که در سراسر وب استفاده می‌شود. اوراکل نه آن را ساخته، نه نگهداری می‌کند و نه حتی از آن استفاده دارد، اما همچنان نامش را تصاحب کرده، گویی محصول خود اوست.
🔗https://javascript.tm/
👥@IR_javascript_group
🆔@IR_javascript
1
آلودگی پروتوتایپ (Prototype Pollution)

تعریف:
آلودگی پروتوتایپ یک حمله تزریقی است که محیط‌های اجرای JavaScript را هدف می‌گیرد. در این نوع حمله، مهاجم می‌تواند مقادیر پیش‌فرض ویژگی‌های یک شیء را کنترل کند. این امکان به مهاجم اجازه می‌دهد منطق برنامه را دستکاری کند و در موارد شدید منجر به انکار سرویس (DoS) یا حتی اجرای کد از راه دور شود.

فرض کنید یک شرکت به نام startup.io API خود را برای مدیریت داده‌های کاربران ارائه کرده است. به دلیل محدودیت زمان و فشار سهامداران، تیم توسعه امنیت API را جدی نگرفته است و بسیاری از مشکلات گزارش شده توسط اسکنرهای امنیتی نادیده گرفته شده‌اند. یکی از آسیب‌پذیری‌های موجود، آلودگی پروتوتایپ است.

دو نقطه انتهایی API که اهمیت دارند:

POST https://api.startup.io/users/:userId برای به‌روزرسانی داده‌های کاربر

GET https://api.startup.io/users/:userId/role برای دریافت نقش امنیتی کاربر (admin یا user)

نمونه حمله: ارتقای دسترسی با آلودگی پروتوتایپ

ابتدا سعی می‌کنیم نقش خود را به admin تغییر دهیم:
curl -H "Content-Type: application/json" -X POST -d '{"role": "admin"}' https://api.startup.io/users/1337 && curl -X GET https://api.startup.io/users/1337/role


نتیجه:

{ "role": "user" }


روش ساده کار نکرد، نقش همچنان user باقی ماند.

با استفاده از آلودگی پروتوتایپ و پیشوند جادویی proto می‌توانیم به موفقیت برسیم:
curl -H "Content-Type: application/json" -X POST -d '{"about": {"__proto__": {"role": "admin"}}}' https://api.startup.io/users/1337 && curl -X GET https://api.startup.io/users/1337/role


نتیجه:

{ "role": "admin" }


BOOM! موفق شدیم با ارسال payload جادویی، نقش خود را به admin تغییر دهیم.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
# بارگذاری تنبل تصاویر پس‌زمینه با API IntersectionObserver


وقتی تصاویر خارج از صفحه (offscreen) را با ویژگی HTML loading بارگذاری تنبل (lazy) می‌کنیم، کار ساده‌ای است. اما برای تصاویر پس‌زمینه که با CSS اضافه شده‌اند، کمی پیچیده‌تر است. در این حالت باید با JavaScript تشخیص دهیم که چه زمانی این تصاویر به دید کاربر نزدیک می‌شوند تا بارگذاری آن‌ها آغاز شود.


---

‏## API IntersectionObserver چیست؟

IntersectionObserver یک API بومی وب است که در مرورگرهای مدرن پشتیبانی می‌شود. این API به شما امکان می‌دهد تا به صورت غیرهمزمان (asynchronously) بررسی کنید که آیا یک عنصر HTML با یکی از والدینش، مانند viewport، در حال تقاطع (intersect) است یا خیر.

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

---

## مزایای استفاده از IntersectionObserver برای عملکرد وب

* این API به صورت غیرهمزمان خارج از thread اصلی اجرا می‌شود و بنابراین بار پردازشی کمتری نسبت به event listenerهای سنتی scroll دارد.
* قبل از آن، توسعه‌دهندگان برای lazy load مجبور بودند event listenerهای scroll، resize و غیره را به صورت دستی اضافه کنند که باعث افزایش بار پردازشی و کندی مرورگر می‌شد.
* IntersectionObserver از thread ترکیب (compositor thread) مرورگر استفاده می‌کند و تغییرات تقاطع نزدیک به هم را در یک callback گروه‌بندی می‌کند، بنابراین از محاسبات تکراری DOM جلوگیری می‌شود.

نتیجه: مصرف CPU کمتر، اسکرول روان‌تر و تجربه کاربری بهتر.

---

## مراحل پیاده‌سازی بارگذاری تنبل پس‌زمینه

### ۱. علامت‌گذاری عناصر خارج از صفحه با کلاس deferred

<div class="bg-1"><p>CTA Area 01</p></div>
<div class="bg-2"><p>CTA Area 02</p></div>
<div class="bg-3"><p>CTA Area 03</p></div>
<div class="bg-4 deferred"><p>CTA Area 04</p></div>
<div class="bg-5 deferred"><p>CTA Area 05</p></div>
<!-- و به همین ترتیب -->


* عناصر با کلاس deferred از تصویر پس‌زمینه خالی استفاده می‌کنند و هنگام نزدیک شدن به viewport، تصاویر بارگذاری می‌شوند.
* تصاویر اولیه (مثلاً دو تصویر اول) با <link rel="preload"> از قبل بارگذاری می‌شوند تا LCP سریع‌تر شود.

---

### ۲. جایگزینی تصویر پس‌زمینه با رنگ پیش‌فرض در CSS

.bg-1 {
background: #d6d6d6 url("images/flowers-01.jpg") no-repeat;
}
.deferred {
background-image: none;
}


* رنگ خاکستری به عنوان placeholder استفاده می‌شود.
* با حذف کلاس deferred توسط JavaScript، تصاویر پس‌زمینه واقعی بارگذاری و نمایش داده می‌شوند.
* ویژگی aspect-ratio برای حفظ اندازه مشابه تصاویر استفاده می‌شود.

---

### ۳. مشاهده تقاطع عناصر با viewport در JavaScript

document.addEventListener("DOMContentLoaded", () => {
const deferredElements = document.querySelectorAll(".deferred");

const elementObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.remove("deferred");
observer.unobserve(entry.target);
}
});
},
{
root: null,
rootMargin: "200px 0px",
threshold: 0,
}
);

deferredElements.forEach(el => elementObserver.observe(el));
});


* root: null → viewport به عنوان ریشه
* rootMargin: "200px 0px" → شروع بارگذاری ۲۰۰px قبل از رسیدن عنصر به viewport
* threshold: 0 → شروع بارگذاری به محض ورود جزئی عنصر

---

### ۴. پشتیبانی از کاربران بدون JavaScript

<noscript>
<style>
.bg-4 { background-image: url(images/flowers-04.jpg); }
.bg-5 { background-image: url(images/flowers-05.jpg); }
.bg-6 { background-image: url(images/flowers-06.jpg); }
</style>
</noscript>


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

---

## جمع‌بندی
*‏ IntersectionObserver یک روش مدرن و بهینه برای lazy load تصاویر پس‌زمینه است.
* کاهش حجم اولیه صفحه، افزایش سرعت بارگذاری و بهبود Core Web Vitals از مزایای آن است.
* این روش با استفاده از thread ترکیب مرورگر و اجرای غیرهمزمان، از بلاک شدن thread اصلی جلوگیری می‌کند و تجربه کاربری روان‌تری ایجاد می‌کند.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
راه‌های متعددی برای ریفرش یا بارگذاری مجدد صفحه وجود دارد و هر کدام می‌توانند در موقعیت‌های مختلف مفید باشند. برای مثال، اخیراً با یک منبع اینترنتی برخورد کردم که لیستی کامل از روش‌های مختلف ریفرش صفحه با JavaScript ارائه کرده است: phpied.com
👀

به جای اینکه در صدها روش غرق شویم، بهتر است روی سه روش اصلی و پرکاربرد تمرکز کنیم که بیشترین کنترل را روی ناوبری و به‌روزرسانی صفحه ارائه می‌دهند:

# ریفرش صفحه در JavaScript

### ۱. location.assign(url) — رفتن به URL جدید

متد assign() برای ناوبری به یک URL جدید استفاده می‌شود و صفحه جاری را در تاریخچه مرورگر نگه می‌دارد. یعنی بعد از رفتن به URL جدید، کاربر می‌تواند با دکمه «بازگشت» به صفحه قبلی برگردد.

location.assign('https://example.com');


---

### ۲. location.replace(url) — رفتن بدون ذخیره در تاریخچه

متد replace() شبیه assign() است، اما صفحه فعلی را در تاریخچه مرورگر ذخیره نمی‌کند. بنابراین بعد از رفتن به URL جدید، با دکمه «بازگشت» نمی‌توان به صفحه قبلی بازگشت.

location.replace('https://example.com');


---

### ۳. location.reload() — بارگذاری مجدد صفحه جاری

متد reload() برای ریفرش یا بارگذاری مجدد صفحه جاری استفاده می‌شود.

* بدون پارامتر: صفحه با توجه به کش مرورگر بارگذاری می‌شود
* با پارامتر true: کش نادیده گرفته شده و صفحه دوباره از سرور بارگذاری می‌شود

location.reload();      // بارگذاری مجدد با کش
location.reload(true); // بارگذاری مجدد بدون کش




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1👍1
# استفاده از Custom Highlight API در مرورگرها

اخیراً متوجه شدم که Firefox 140 (ژوئن ۲۰۲۵) از Custom Highlight API پشتیبانی می‌کند، و حالا این ویژگی روی تمام مرورگرهای اصلی در دسترس است. با این API می‌توان به متن‌هایی که در JavaScript با کلاس Range() به دست می‌آوریم، استایل دلخواه اعمال کرد.

برای درک ساده، مراحل اصلی به این صورت است:

1. یک textNode انتخاب کنید.


   const textNode = document.querySelector("p").firstChild;

2. یک Range بسازید و محدوده‌ی شروع و پایان آن را مشخص کنید:


   const range = new Range();
range.setStart(textNode, startIndex);
range.setEnd(textNode, endIndex);

3. با `CSS.highlights.set()`، این Range را به یک نام هایلایت متصل کنید:


   const highlight = new Highlight(range);
CSS.highlights.set("our-highlight", highlight);

4. در CSS با ::highlight(name) آن را استایل دهید:


   ::highlight(our-highlight) {
background-color: yellow;
}


---

## مثال عملی: هایلایت یک کلمه

const WORD_TO_HIGHLIGHT = "wisdom";
const NAME_OF_HIGHLIGHT = "our-highlight";

const textNode = document.querySelector("p").firstChild;
const textContent = textNode.textContent;

const startIndex = textContent.indexOf(WORD_TO_HIGHLIGHT);
const endIndex = startIndex + WORD_TO_HIGHLIGHT.length;

const range = new Range();
range.setStart(textNode, startIndex);
range.setEnd(textNode, endIndex);

const highlight = new Highlight(range);
CSS.highlights.set(NAME_OF_HIGHLIGHT, highlight);


در DevTools می‌توان دید که کلمه "wisdom" با CSS استایل داده شده، بدون اینکه هیچ المنتی در اطراف آن اضافه شود.

---

## چرا مفید است؟

* استایل بدون دستکاری DOM: نیازی به اضافه کردن <span> یا عناصر دیگر نیست، که باعث کاهش وزن DOM و بهبود عملکرد می‌شود.
* کاهش هزینه‌های محاسباتی: اضافه کردن و حذف <span> می‌تواند باعث Reflow و Repaint شود و عملکرد UX را کند کند.
* قابلیت هایلایت چند محدوده‌ای: یک Highlight می‌تواند چند Range را پوشش دهد، که برای مثال می‌توان برای ایجاد یک سیستم جستجو روی متن کاربرد دارد.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
This media is not supported in your browser
VIEW IN TELEGRAM
🌸میلاد رسول مهربانی‌ها پیامبر اعظم (ص)💚
و امام جعفر صادق (ع)💚
این نصیحت را استاد در کتاب آزادی معنوی (ص۲۰۵) از قول امام صادق علیه السلام نقل می‌کنند که البته این استناد در این کلیپ نیامده است.

🔗https://t.me/motahari_ir/4489
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
8👎2
آیا شما هم هنوز برای استفاده از بک‌اسلش در رشته‌های قالب‌بندی‌شده، آن را دو بار تکرار می‌کنید؟ 🔍

چند روز پیش دیدم که شخصی در رشته‌های قالب‌بندی‌شده (template strings) برای کاراکترهای اِسکیپ‌شده مثل \n (خط جدید) یا \t (تب)، بک‌اسلش‌ها (\\) را تکرار می‌کرد. اما راه‌حل بسیار ساده‌تری وجود دارد و آن استفاده از `String.raw` است. 😁

-----

### `String.raw` چیست؟

این متد به شما اجازه می‌دهد تا با رشته‌های قالب‌بندی‌شده به گونه‌ای کار کنید که دنباله‌های اِسکیپ (مانند \n`، `\t`، `\\ و دیگر موارد) به‌صورت «خام» باقی بمانند. یعنی اگر نیاز به نوشتن یک رشته با مسیر فایل یا کاراکترهای خط جدید و تب دارید، `String.raw` بدون نیاز به اِسکیپ‌کردن‌های اضافی، تمام کار را برای شما انجام می‌دهد. 👍

مثال:

const path = `C:\Users\Name\Documents\file.txt`;
console.log(path); // C:UsersNameDocuments ile.txt

const path = String.raw`C:\Users\Name\Documents\file.txt`;
console.log(path); // C:\Users\Name\Documents\file.txt


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


const path = `C:\\Users\\Name\\Documents\\file.txt`;
console.log(path); // C:\Users\Name\Documents\file.txt


-----

### مزایای `String.raw`

➡️ با استفاده از `String.raw`**، کد شما تمیزتر و خواناتر می‌شود، زیرا نیازی به اِسکیپ‌کردن دوباره کاراکترهایی مانند `\`، `n` یا `t` ندارید.

**این قابلیت در کجا مفید است؟


* مسیرهای فایل: اگر با مسیرهای ویندوز کار می‌کنید که شامل بک‌اسلش‌های زیادی است، `String.raw` شما را از نوشتن \\ بی‌نیاز می‌کند.
* عبارات باقاعده (Regular Expressions): اگر در الگوهای خود بک‌اسلش یا کاراکترهای خاص زیادی دارید، `String.raw` به جلوگیری از تفسیر این کاراکترها کمک کرده و آن‌ها را به شکل اصلی‌شان حفظ می‌کند.
* رشته‌های چندخطی: زمانی که لازم است کاراکترهای خط جدید یا تب را به‌صورت متن ذخیره کنید، نه اینکه واقعاً خط را بشکنید یا تب ایجاد کنید.

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

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1🔥1
🤔 چطور بین iframe و صفحه اصلی ارتباط برقرار کنیم؟

ارتباط بین iframe و صفحه والد می‌تواند از طریق روش‌های زیر انجام شود:

* متد `postMessage` (بهترین روش)
* دسترسی به window.frames یا window.parent (اگر در همان دامنه باشند)
* انتقال داده‌ها از طریق localStorage یا cookies

---

🟠 `postMessage` – روشی امن برای دامنه‌های مختلف
متد window.postMessage() امکان ارسال پیام بین پنجره‌های مختلف (iframe، popup، تب‌های دیگر) را حتی در صورت قرار داشتن در دامنه‌های مختلف فراهم می‌کند.

---

🚩 ارسال داده از `iframe` به صفحه والد

*کد در iframe (child.html):*

// ارسال پیام به پنجره والد
window.parent.postMessage({ type: "hello", data: "سلام والد!" }, "*");


*کد در صفحه والد (index.html):*

window.addEventListener("message", (event) => {
console.log("پیام دریافت شده از iframe:", event.data);
});


> علامت * در postMessage به این معناست که پیام به هر دامنه‌ای ارسال می‌شود. بهتر است دامنه مشخصی را تعیین کنید، مثلاً:

window.parent.postMessage({ type: "hello" }, "https://example.com");


---

🚩 ارسال داده از والد به `iframe`

*کد در صفحه والد (index.html):*

const iframe = document.getElementById("myIframe");

// منتظر می‌مانیم iframe بارگذاری شود
iframe.onload = () => {
iframe.contentWindow.postMessage({ type: "greeting", data: "سلام iframe!" }, "*");
};


*کد در iframe (child.html):*

window.addEventListener("message", (event) => {
console.log("پیام دریافت شده از والد:", event.data);
});


---

🚩 دسترسی به `window.frames` و `window.parent` *(فقط اگر در همان دامنه باشند)*

اگر iframe و صفحه اصلی در یک دامنه قرار داشته باشند، می‌توان مستقیماً به آبجکت‌های window دسترسی داشت.

صفحه والد → iframe:

const iframe = document.getElementById("myIframe");

// دسترسی به window داخل iframe
iframe.contentWindow.document.body.style.backgroundColor = "lightblue";


iframe → صفحه والد:

console.log(window.parent.document.title); // دسترسی به عنوان صفحه


---

🚩 استفاده از `localStorage` یا `cookies` *(اگر هر دو پنجره در یک دامنه باشند)*

می‌توان داده‌ها را در localStorage یا cookies ذخیره کرد و طرف دیگر آن‌ها را خواند.

نوشتن در localStorage از iframe:

localStorage.setItem("message", "سلام از iframe!");


خواندن localStorage در صفحه والد:

console.log(localStorage.getItem("message")); // "سلام از iframe!"




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
آشنایی با <meta name="viewport"> 🤓

تگ <meta name="viewport"> یک مِتا تگ است که به مرورگرهای موبایل می‌گوید چگونه ابعاد پنجرهٔ دید مجازی (viewport) را تنظیم کنند و صفحه را چگونه مقیاس‌بندی کنند.

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

📚 سینتکس پایه‌ای:

<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>


این حالت در اکثر موارد استفاده می‌شود:

* عرض viewport برابر با عرض واقعی صفحه نمایش دستگاه است.
* مقیاس اولیه برابر با صد درصد است.

مقدارهای content را می‌توانید در تصویر بالا مشاهده کنید 😁

👀 تگ <meta name="viewport"> به تنهایی سایت را واکنش‌گرا نمی‌کند**؛ فقط یک «بوم» برای رندر فراهم می‌کند.

**چند نکته کاربردی:


1️⃣ تگ را در `<head>` و تا حد امکان زود قرار دهید.
مرورگر باید قبل از رندر کردن صفحه آن را ببیند.

2️⃣ از `width=device-width, initial-scale=1.0` به‌عنوان پیش‌فرض استفاده کنید.

3️⃣ چند تگ viewport وارد نکنید.
مرورگرها معمولاً تنها یکی را اعمال می‌کنند یا رفتار صفحه غیرقابل پیش‌بینی می‌شود.

و فراموش نکنید که طراحی و مقیاس‌بندی را روی دستگاه‌های واقعی و شبیه‌سازها بررسی کنید 🥰


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥2
🚀 AV1؛ آینده‌ی ویدیو روی وب
این نمودار عملکرد چند کُدِک ویدیویی مختلف رو از نظر کیفیت تصویر (VMAF Rating) در برابر نرخ داده (Data Rate) نشون می‌ده.
محور افقی (Data Rate) → نشون‌دهنده‌ی بیت‌ریت یا حجم داده است
محور عمودی (VMAF Rating) → شاخص کیفیت تصویریه که توسط نتفلیکس توسعه داده شده

این نمودار خیلی واضح نشون می‌ده که AV1 کارآمدترین کُدِک فعلیه،

🔹 فرمت جدید AV1 توسط کروم، سافاری و فایرفاکس پشتیبانی می‌شه و می‌تونه حجم فایل‌های ویدیویی رو تا پنجاه درصد کمتر کنه، بدون افت کیفیت.

⚡️ چرا مهمه؟

* بارگذاری سریع‌تر و مصرف کمتر CPU و باتری
* جایگزین عالی برای GIFها (بیست تا چهل برابر سبک‌تر)
* مناسب برای پروژه‌های وب مدرن

🛠 ابزار کار: با چند دستور ساده‌ی FFmpeg می‌شه ویدیوها رو به AV1 تبدیل کرد. برای سازگاری بیشتر، پیشنهاد می‌شه سه نسخه داشته باشید:

1. AV1 برای مرورگرهای مدرن
2. H.264 برای دستگاه‌های قدیمی
3. (اختیاری) HEVC برای برخی آیفون‌ها و مک‌ها

🎯 اگر دنبال کیفیت بالا با حجم کم هستید، وقتشه به AV1 مهاجرت کنید.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
چه اتفاقی می‌افتد اگر به JSON.parse() داده‌ای غیرمعمول بدهیم؟ 🧐

همهٔ ما به پارس کردن رشته‌ها با JSON.parse() عادت کرده‌ایم، اما اگر داده‌ای غیرمعمول مانند null`، `undefined یا یک رشتهٔ خالی به آن بدهیم، چه رخ می‌دهد؟ بیایید بررسی کنیم! 🤔

۱️⃣ JSON.parse(null)

وقتی مقدار null را به JSON.parse می‌دهیم، به سادگی همان null بازگردانده می‌شود:

console.log(JSON.parse(null));  // null


چرا؟ چون null در زمینهٔ JSON به‌عنوان یک مقدار تهی یا خالی در نظر گرفته می‌شود و متد آن را بدون تغییر بازمی‌گرداند. کمی عجیب به نظر می‌رسد، اما کار می‌کند! 🙃

۲️⃣ JSON.parse(undefined)

اما در مورد undefined داستان فرق دارد. این نوع داده JSON معتبر نیست، بنابراین JSON.parse خطا می‌دهد:

console.log(JSON.parse(undefined));  // Uncaught SyntaxError: Unexpected token u in JSON at position 0


نمی‌توان undefined را به JSON معتبر تبدیل کرد و متد بلافاصله خطای نحوی (Syntax Error) را گزارش می‌کند.

۳️⃣ JSON.parse('')

رشتهٔ خالی هم قابل قبول نیست. تلاش برای پارس کردن آن نیز منجر به خطا می‌شود:

console.log(JSON.parse(''));  // Uncaught SyntaxError: Unexpected end of JSON input


دلیل آن این است که رشتهٔ خالی یک مقدار JSON معتبر نیست. JSON.parse انتظار دارد که رشته شامل نوع معتبری از داده‌های JSON باشد. 😁

نتیجه‌گیری:
اگر رشتهٔ ورودی ممکن است خالی باشد یا مقدار undefined داشته باشد، همیشه قبل از استفاده از JSON.parse() آن را بررسی کنید تا از بروز خطاهای ناخوشایند جلوگیری شود. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
Media is too big
VIEW IN TELEGRAM
ویدیو دوبله شده در مورد چگونگی مدیریت صف‌ها و حلقهٔ رویداد (event loop)

مسئول مدیریت ترتیب اجرای کد در جاوااسکریپت با Event Loop است. این حلقه صف‌های مختلفی دارد که کدهای مختلف را در آن‌ها قرار می‌دهد تا به ترتیب اجرا شوند.

#️⃣#tip #dub
👥@IR_javascript_group
🆔@IR_javascript
3
بیایید با یک ویژگی جالب در CSS آشنا شویم: content-visibility 🤨

---

### content-visibility چیست؟

ویژگی content-visibility در CSS به مرورگر اعلام می‌کند که آیا محتوای یک عنصر باید در هنگام بارگذاری اولیه صفحه رندر شود یا خیر. به این ترتیب، زمانی که مرورگر در حال بارگذاری محتوا و نمایش آن بر روی صفحه است، این ویژگی به ما امکان می‌دهد مشخص کنیم که محتوای یک عنصر تنها در صورت نیاز بارگذاری شود. می‌توانید آن را مشابه بارگذاری تنبل (lazy loading) تصور کنید؛ به این معنا که محتوای فرزندان یک عنصر خارج از محدوده دید کاربر، تا زمانی که وارد ناحیه دید (viewport) نشوند، رندر نخواهند شد.

---

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

وقتی یک عنصر مقدار content-visibility: auto داشته باشد، تا زمانی که وارد ناحیهٔ دید کاربر نشود رندر نمی‌شود. این کار باعث می‌شود مرورگر منابع را برای عناصر نامرئی هدر ندهد.

.element {
content-visibility: auto | hidden | visible;
}


‏hidden: عنصر محتوای خود را نادیده می‌گیرد (مشابه اعمال display: none; روی محتوا).
‏visible: بدون اثر خاص، و عنصر به‌طور معمول رندر می‌شود.
‏auto: عنصر شامل containment در لایه‌بندی، سبک (style) و رنگ‌آمیزی است. مرورگر تصمیم می‌گیرد که آیا این محتوا برای کاربر ضروری است یا نه؛ و در صورتی که ضروری نباشد، آن را نادیده می‌گیرد. با این حال، عنصر همچنان قابل فوکوس، انتخاب و دسترسی از طریق ابزارهایی مانند جابه‌جایی با کلید Tab یا جست‌وجو در صفحه خواهد بود.


اما تفاوت اینجاست که در content-visibility: hidden;، مرورگر وضعیت رندرشده عنصر را کش می‌کند. بنابراین زمانی که این قانون حذف شود، مرورگر نیازی به رندر مجدد از ابتدا ندارد. این ویژگی برای عناصری مناسب است که به‌طور پیش‌فرض پنهان هستند، اما احتمال بالایی وجود دارد که در طول چرخه حیات صفحه نمایش داده شوند (مانند یک مودال پرکاربرد). در این حالت، هنگام نمایش، عنصر بسیار سریع‌تر بارگذاری می‌شود.

در content-visibility: auto می‌توانید این مقدار را مشابه بارگذاری تنبل برای بخش‌های کامل DOM تصور کنید.
اگر عنصری خارج از دید کاربر (زیر خط fold) باشد و مقدار auto داشته باشد، مرورگر هیچ‌یک از محتوای آن را در نظر نمی‌گیرد و رندر آن را به تعویق می‌اندازد. هنگامی که کاربر به آن اسکرول کند، مرورگر محتوا را نقاشی می‌کند. زمان دقیق رندر به تصمیم مرورگر بستگی دارد.
---

### ارتباط با contain-intrinsic-size

این ویژگی معمولاً همراه با contain-intrinsic-size استفاده می‌شود.

🔹 مشکل: وقتی از content-visibility استفاده می‌کنیم، مرورگر ممکن است اندازهٔ دقیق عناصر پنهان را نداند و این می‌تواند موجب به‌هم‌ریختگی چیدمان شود.

🔹 راه‌حل: استفاده از contain-intrinsic-size که یک اندازهٔ حداقلی برای عنصر تعیین می‌کند؛ حتی اگر عنصر دیده نشود. این کار به مرورگر کمک می‌کند تا جای مناسب برای عنصر در چیدمان صفحه از پیش در نظر بگیرد.

مثال:

.image-gallery img {
content-visibility: auto;
contain-intrinsic-size: 200px; /* تعیین اندازهٔ حداقلی */
}


---

### مزایا

بارگذاری صفحه سریع‌تر انجام می‌شود.
فشار کمتری بر پردازنده و حافظه وارد می‌شود.
هنگام دیده شدن عناصر، رندر آن‌ها سریع‌تر انجام می‌شود، بدون اینکه قبلاً منابع برای عناصر نامرئی مصرف شده باشد.

---

### موارد استفاده

🔘 صفحات بلند با محتوای زیاد (مانند فیدهای خبری یا کاتالوگ محصولات).
🔘 محتوای پویا که در حین پیمایش ظاهر می‌شود.

---

### جمع‌بندی

استفاده از content-visibility روشی ساده برای سرعت بخشیدن به رندر صفحه است. همچنین اگر همراه با contain-intrinsic-size به‌کار رود، می‌توان از مشکلات چیدمان در هنگام پنهان بودن عناصر جلوگیری کرد. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍5
Cornerstone3D ساخت اپلیکیشن‌های تحت وب برای تصویربرداری پزشکی

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

🔗cornerstonejs.org
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👎1🤯1
‏**Mediabunny** یک کتابخانهٔ جاوااسکریپت برای خواندن، نوشتن و تبدیل فایل‌های رسانه‌ای مانند MP4، WebM و MP3 است، مستقیماً در مرورگر اجرا می‌شود. هدف آن ارائهٔ یک مجموعهٔ کامل برای عملیات رسانه‌ای با کارایی بالا روی وب است.

این کتابخانه از صفر و با TypeScript خالص نوشته شده، هیچ وابستگی‌ای ندارد، بسیار سریع است و از قابلیت tree-shaking پشتیبانی کامل می‌کند؛ به این معنا که فقط کدهایی که استفاده می‌کنید وارد پروژه می‌شوند. می‌توان آن را شبیه FFmpeg تصور کرد، اما به‌طور کامل برای وب از پایه ساخته شده است.


🔗https://mediabunny.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
2🔥1
‍‏**Peaks.js نسخهٔ چهار: کامپوننت رابط کاربری برای تعامل با نمودار موج صدا**

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


🔗https://codeberg.org/chrisn/peaks.js
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍2
یک سرور HTTP نمی‌تواند به صورت خودکار یک اتصال به مرورگر برقرار کند؛ بنابراین همیشه مرورگر آغازگر ارتباط است. حالا برای دریافت به‌روزرسانی‌های لحظه‌ای از سرور HTTP چه باید کرد؟

دو رویکرد اصلی وجود دارد:

🔹 مرورگر بار اصلی را بر دوش می‌کشد:

* Polling کوتاه‌مدت (Short Polling): مرورگر به‌طور مکرر درخواست می‌فرستد تا زمانی که داده‌ی جدید را دریافت کند.
* Polling بلندمدت (Long Polling): سرور درخواست را باز نگه می‌دارد و تنها زمانی پاسخ می‌دهد که داده‌ی تازه آماده شود.

🔹 همکاری مرورگر و سرور:

* WebSocket: یک اتصال دائمی و دوسویه برقرار می‌شود. پس از آن، سرور می‌تواند هر زمان داده‌ی جدید را ارسال کند و مرورگر نیز می‌تواند درخواست‌های تازه بفرستد.
* SSE (Server-Sent Events): یک اتصال یک‌طرفه ایجاد می‌شود که در آن فقط سرور می‌تواند داده‌های جدید را برای مرورگر ارسال کند. مرورگر نمی‌تواند درخواست تازه‌ای از همان کانال به سرور بفرستد.

👉 در نتیجه، انتخاب میان این روش‌ها بستگی به نیاز برنامه دارد: اگر ارتباط دوطرفه نیاز باشد، WebSocket بهترین گزینه است؛ اگر کافی است فقط سرور داده‌ها را به‌طور خودکار به مرورگر بفرستد، SSE ساده‌تر و سبک‌تر است.




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
🔹 مقایسه toString() و String() 🤨

یکی از نیازهای رایج در برنامه‌نویسی، تبدیل داده‌ها به رشته است. برای این کار دو رویکرد اصلی وجود دارد: toString() و String(). هرچند عملکرد آن‌ها شبیه به هم است، اما یک تفاوت کلیدی میانشان وجود دارد. بیایید بررسی کنیم! 😁

---

### ۱️⃣ toString() — متد شیء

این متد یک شیء را به رشته تبدیل می‌کند، اما:

✔️ برای انواع اولیه (مانند عدد یا رشته) نمایش متنی آن‌ها را برمی‌گرداند؛
✔️ برای اشیاء (مثل آرایه یا تابع) خروجی به نوع آن وابسته است؛
✔️ در صورت فراخوانی روی null یا undefined خطا تولید می‌کند.

const num = 42;
console.log(num.toString()); // "42"

const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"

// خطا در null یا undefined
null.toString(); // TypeError


---

### ۲️⃣ String() — تابع سراسری

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

✔️ با تمام مقادیر (حتی null و undefined) کار می‌کند؛
✔️ به جای خطا، عبارت "null" یا "undefined" برمی‌گرداند.

console.log(String(42));        // "42"
console.log(String([1, 2])); // "1,2"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"


---

### چند نکته تکمیلی

✔️ برای اشیاء و آرایه‌هایی که متد toString را بازنویسی نکرده‌اند، خروجی پیش‌فرض خواهد بود (مانند "[object Object]" یا "1,2,3"). برای نمایش متفاوت باید متد toString بازنویسی شود؛
✔️ اگر نیاز به سریال‌سازی شیء به JSON دارید، از JSON.stringify() استفاده کنید؛
✔️ در بیشتر مواقع، متد toString() اندکی سریع‌تر از String() است، چون بررسی‌های اضافه ندارد. با این حال، این تفاوت معمولاً ناچیز است و در عملکرد روزمره کد تأثیر محسوسی ندارد.

---

به‌طور معمول، من از toString() استفاده می‌کنم چون ساده و مستقیم است. اما اگر نیاز باشد مقدار null یا undefined را هم پردازش کنم، سراغ String() می‌روم، زیرا بدون ایجاد خطا، به‌خوبی از عهده این کار برمی‌آید. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2