Faragiri

همهٔ زبان‌ها

آموزش کار با DOM جاوااسکریپت

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

۴بخش
۳دقیقه خواندن
۴عمق

صفحه، از دید انتخابگرها

چه چیزی داخل چه چیزی است، و هر متد از کجا شروع می‌کند

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

سند

  • ul#istgahجایی که یک شنونده مشترک باید بنشیند
    • li.dock با کد D1متنش از خود گره و از span داخلش می‌آید
      • span.bikesاز اینجا closest به همان فهرست می‌رسد
    • li.dock با کد D2
    • li.dock.out با کد D3matches برای این یکی درست است و برای بقیه نه
    • li.dock با کد D4پس از اجرای هر دو انتخابگر اضافه شد و فقط فهرست زنده می‌شمردش
  • button#refreshبیرون از فهرست است، پس شنونده مشترک هرگز نمی‌بیندش

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

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

  • document.getElementsByClassName("dock") یک HTMLCollection زنده می‌دهد، یعنی پرسشی که همچنان تطبیق می‌دهد
  • document.querySelectorAll(".dock") یک NodeList ایستا می‌دهد، یعنی عکسی از همان لحظه

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

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

سه متدی که کد را کوتاه می‌کنند

closest("ul") از یک عنصر رو به بالا می‌رود تا اولین نیای منطبق را پیدا کند، و همان است که رسیدگی به رویداد را ساده می‌کند. matches(".out") می‌گوید یک عنصر با انتخابگر می‌خواند یا نه و جواب بولین می‌دهد. و dataset.kod مقدار صفت data-kod را می‌دهد، بدون نوشتن نام کامل صفت.

این سه با هم یک الگو می‌سازند: به‌جای گذاشتن یک شنونده روی هر ردیف، یک شنونده روی فهرست بگذارید و داخلش با closest بفهمید کدام ردیف کلیک شده. مزیتش این نیست که کد کمتر است؛ این است که ردیف‌هایی که بعدا اضافه می‌شوند هم بدون هیچ کاری کار می‌کنند، و همان مسئله فهرست زنده و ایستا را از ریشه حذف می‌کند.

خواندن و نوشتن، و مرزی که نباید رد شود

برای متن همیشه textContent بنویسید. innerHTML رشته را به‌عنوان کد تفسیر می‌کند، پس هر متنی که از کاربر یا از یک رابط برنامه‌نویسی آمده باشد می‌تواند اسکریپت اجرا کند، که موضوع ورودی نامطمئنی که به‌جای متن، کد اجرا می‌شود است.

و هر بار که چیزی به صفحه اضافه می‌کنید مرورگر ممکن است دوباره چیدمان را حساب کند. برای افزودن چند عنصر، یکی‌یکی اضافه نکنید؛ همه را در یک DocumentFragment بسازید و یک بار وصل کنید. روی ده ردیف فرقی ندارد و روی هزار ردیف تفاوتش دیده می‌شود.

جایی که کار گیر می‌کند، عادت jQuery است

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

ابزار، و سالی که این حرف درست است

در سال ۲۰۲۶ ابزار اصلی همان بازرس مرورگر است و رایگان؛ برگه عناصر درخت را همان‌طور که اسکریپت می‌بیند نشان می‌دهد و نه همان‌طور که در فایل نوشته شده، و همین تفاوت است که بیشتر سردرگمی‌ها را حل می‌کند. برای دیدن اینکه کدام کد چه چیزی را عوض می‌کند، نقطه توقف روی تغییر گره در همان بازرس تنظیم می‌شود و جای گذاشتن console.log در چند جا را می‌گیرد. هر دو محلی‌اند و به شبکه نیازی ندارند.

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

کنار این

بالای این