[{"data":1,"prerenderedAt":283},["ShallowReactive",2],{"lesson:t7-s08-fetch-data":3,"course:taropood":56},{"meta":4,"prev":11,"next":14,"sections":18},{"free_preview":5,"order":6,"slug":7,"source":8,"term":9,"title_fa":10},true,8,"t7-s08-fetch-data","book",7,"فصل ۰۸ — گرفتن داده از اینترنت",{"free_preview":5,"order":9,"slug":12,"source":8,"term":9,"title_fa":13},"t7-s07-lists-loops","فصل ۰۷ — فهرست و حلقه",{"free_preview":5,"order":15,"slug":16,"source":8,"term":9,"title_fa":17},9,"t7-s09-js-capstone","فصل ۰۹ — پروژهٔ نهایی: یک صفحهٔ قدیمی را تعاملی کن",[19,23,26,31,34,37,40,43,46,49,53],{"kind":20,"heading":21,"html":22},"normal","در این فصل چه می‌سازی","\u003Ch2 id=\"در-این-فصل-چه-می‌سازی\">در این فصل چه می‌سازی\u003Ca class=\"head-anchor\" href=\"#%D8%AF%D8%B1-%D8%A7%DB%8C%D9%86-%D9%81%D8%B5%D9%84-%DA%86%D9%87-%D9%85%DB%8C%E2%80%8C%D8%B3%D8%A7%D8%B2%DB%8C\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>هر چیزی که تا امروز روی صفحه‌هایت بود، از داخل فایل‌های خودت می‌آمد؛ این فصل صفحه‌ات برای اولین بار دست دراز می‌کند و از اینترنت دادهٔ \u003Cstrong>زنده\u003C\u002Fstrong> می‌گیرد. یک کارتِ آب‌وهوا می‌سازی که با یک کلیک، دمای همین لحظه را از یک سرویسِ واقعی می‌گیرد و نشان می‌دهد. و نیمهٔ مهم‌ترِ فصل: کاری می‌کنیم که اگر اینترنت قطع بود، صفحه به‌جای شکستن یک پیامِ دوستانه نشان بدهد — صفحهٔ خوب صفحه‌ای است که روزِ بدِ شبکه هم سرِ پا بماند.\u003C\u002Fp>\n\u003Cp>\u003Cpicture>\u003Csource type=\"image\u002Fwebp\" srcset=\"\u002F_img\u002F01-image-fetch-cloud.3893cff0d9.160.webp 160w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.320.webp 320w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.640.webp 640w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.1280.webp 1280w\" sizes=\"(max-width: 900px) 100vw, 800px\">\u003Cimg src=\"\u002F_img\u002F01-image-fetch-cloud.3893cff0d9.1280.jpg\" srcset=\"\u002F_img\u002F01-image-fetch-cloud.3893cff0d9.160.jpg 160w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.320.jpg 320w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.640.jpg 640w, \u002F_img\u002F01-image-fetch-cloud.3893cff0d9.1280.jpg 1280w\" sizes=\"(max-width: 900px) 100vw, 800px\" alt=\"یک کارت وب که با بازویی کابلی بسته‌ای از داده را از یک ابر سرور می‌گیرد\" width=\"1376\" height=\"768\" loading=\"lazy\" decoding=\"async\">\u003C\u002Fpicture>\u003C\u002Fp>\n\u003Cp>آخر این فصل می‌توانی:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>با \u003Ccode>fetch\u003C\u002Fcode> از یک API داده بگیری\u003C\u002Fli>\n\u003Cli>توضیح بدهی promise چیست و \u003Ccode>async\u003C\u002Fcode>\u002F\u003Ccode>await\u003C\u002Fcode> چه می‌کنند\u003C\u002Fli>\n\u003Cli>جوابِ سرور را با \u003Ccode>res.ok\u003C\u002Fcode> بسنجی و JSON اش را بخوانی\u003C\u002Fli>\n\u003Cli>با \u003Ccode>try\u003C\u002Fcode>\u002F\u003Ccode>catch\u003C\u002Fcode> برای قطعیِ شبکه یک مسیرِ نجاتِ دوستانه بسازی\u003C\u002Fli>\n\u003C\u002Ful>\n",{"kind":20,"heading":24,"html":25},"قبل از شروع","\u003Ch2 id=\"قبل-از-شروع\">قبل از شروع\u003Ca class=\"head-anchor\" href=\"#%D9%82%D8%A8%D9%84-%D8%A7%D8%B2-%D8%B4%D8%B1%D9%88%D8%B9\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>از فصل ۴:\u003C\u002Fstrong> \u003Ccode>addEventListener\u003C\u002Fcode> و رویداد \u003Ccode>click\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>از فصل ۳:\u003C\u002Fstrong> \u003Ccode>querySelector\u003C\u002Fcode> و \u003Ccode>textContent\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>از فصل ۲:\u003C\u002Fstrong> template literal.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.\u003C\u002Fp>\n",{"kind":27,"heading":28,"html":29,"embed":30},"lab","","— کارتِ آب‌وهوا با دکمه‌اش آماده است و آدرسِ API هم در پنجرهٔ JS نوشته شده. گرفتنِ داده، نمایشش، و مهارکردنِ خرابی با توست","\u002Flab\u002Fembed\u002Ftaropood\u002Fterm-7-javascript\u002Fsession-08-fetch-data",{"kind":20,"heading":32,"html":33},"۱. fetch: درخواستی که کدِ تو می‌فرستد","\u003Ch2 id=\"۱-fetch-درخواستی-که-کدِ-تو-می‌فرستد\">۱. fetch: درخواستی که کدِ تو می‌فرستد\u003Ca class=\"head-anchor\" href=\"#%DB%B1-fetch-%D8%AF%D8%B1%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%DB%8C-%DA%A9%D9%87-%DA%A9%D8%AF%D9%90-%D8%AA%D9%88-%D9%85%DB%8C%E2%80%8C%D9%81%D8%B1%D8%B3%D8%AA%D8%AF\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>تا حالا مرورگر فقط وقتی درخواست می‌فرستاد که تو آدرسی را باز می‌کردی. \u003Ccode>fetch\u003C\u002Fcode> همان کار را از داخلِ کد می‌کند: به یک آدرس درخواست بفرست و جواب را بگیر. آدرس‌هایی که به‌جای صفحهٔ HTML دادهٔ خام پس می‌دهند \u003Cstrong>API\u003C\u002Fstrong> نام دارند، و قالبِ رایجِ این داده \u003Cstrong>JSON\u003C\u002Fstrong> است — متنی ساخت‌یافته که تبدیل می‌شود به همان جنس چیزهایی که می‌شناسی: مقدارها، آرایه‌ها، و شیءهایی که با نقطه می‌خوانی‌شان، مثل \u003Ccode>event\u003C\u002Fcode> که از فصل ۴ با نقطه می‌خواندی.\u003C\u002Fp>\n\u003Cp>یک تفاوتِ بزرگ با همهٔ کدهای قبلی‌ات: جوابِ اینترنت \u003Cstrong>فوری نیست\u003C\u002Fstrong>. برای همین \u003Ccode>fetch\u003C\u002Fcode> به‌جای جواب، بلافاصله یک \u003Cstrong>promise\u003C\u002Fstrong> می‌دهد — یک رسید که می‌گوید «جوابت در راه است». کلمهٔ \u003Ccode>await\u003C\u002Fcode> یعنی «همین‌جا بایست تا این رسید به جوابِ واقعی تبدیل شود»، و هر function ی که تویش \u003Ccode>await\u003C\u002Fcode> می‌نویسی باید جلویش \u003Ccode>async\u003C\u002Fcode> داشته باشد.\u003C\u002Fp>\n",{"kind":20,"heading":35,"html":36},"۲. اولین درخواست — و اولین undefined","\u003Ch2 id=\"۲-اولین-درخواست-—-و-اولین-undefined\">۲. اولین درخواست — و اولین \u003Ccode>undefined\u003C\u002Fcode>\u003Ca class=\"head-anchor\" href=\"#%DB%B2-%D8%A7%D9%88%D9%84%DB%8C%D9%86-%D8%AF%D8%B1%D8%AE%D9%88%D8%A7%D8%B3%D8%AA-%E2%80%94-%D9%88-%D8%A7%D9%88%D9%84%DB%8C%D9%86-undefined\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>listener دکمه را بنویس؛ به \u003Ccode>async\u003C\u002Fcode> که قبل از \u003Ccode>function\u003C\u002Fcode> نشسته دقت کن:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>const updateBtn = document.querySelector('#update-btn');\nconst weatherLine = document.querySelector('#weather-line');\n\nconst url = 'https:\u002F\u002Fapi.open-meteo.com\u002Fv1\u002Fforecast?latitude=35.69&amp;longitude=51.39&amp;current_weather=true';\n\nupdateBtn.addEventListener('click', async function () {\n  const res = await fetch(url);\n  const data = await res.json();\n  console.log(data);\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>این آدرس سرویسِ آب‌وهوای Open-Meteo است — بدونِ ثبت‌نام و کلید — و آن دو عدد، عرض و طولِ جغرافیایی تهران‌اند. \u003Ccode>res\u003C\u002Fcode> جوابِ خام است؛ \u003Ccode>res.json()\u003C\u002Fcode> متنِ JSON را به دادهٔ قابلِ استفاده تبدیل می‌کند — و چون این کار هم زمان‌بر است، خودش هم promise می‌دهد؛ برای همین \u003Ccode>await\u003C\u002Fcode> دوم.\u003C\u002Fp>\n\u003Cp>✅ \u003Cstrong>چک کن:\u003C\u002Fstrong> دکمه را بزن و console را نگاه کن: یک شیءِ داده می‌بینی که تویش \u003Ccode>current_weather\u003C\u002Fcode> هست، با دما و سرعتِ باد.\u003C\u002Fp>\n\u003Cp>حالا خرابیِ این فصل. \u003Ccode>await\u003C\u002Fcode> دوم را عمداً بردار — بنویس \u003Ccode>const data = res.json();\u003C\u002Fcode> — و دکمه را بزن. در console به‌جای داده این را می‌بینی:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>Promise {&lt;pending&gt;}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>نه دما، نه خطا — فقط یک قولِ هنوز عملی‌نشده. و اگر از دلش چیزی بخوانی، \u003Ccode>undefined\u003C\u002Fcode> می‌گیری: داده‌ای که هنوز نرسیده.\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>🔧 \u003Cstrong>اگر کار نکرد:\u003C\u002Fstrong> هر جا انتظارِ داده داشتی و \u003Ccode>Promise\u003C\u002Fcode> یا \u003Ccode>undefined\u003C\u002Fcode> دیدی، اولین مظنون همیشه یکی است: یک \u003Ccode>await\u003C\u002Fcode> جا افتاده. \u003Ccode>await\u003C\u002Fcode> را برگردان و دوباره امتحان کن.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>\u003Cstrong>Checkpoint.\u003C\u002Fstrong> قبل از ادامه، جواب بده: چرا جلوی functionِ این listener کلمهٔ \u003Ccode>async\u003C\u002Fcode> نشسته؟ (جواب: چون داخلش \u003Ccode>await\u003C\u002Fcode> نوشته‌ایم — قانون همین بود: هر functionی که تویش \u003Ccode>await\u003C\u002Fcode> باشد، جلویش \u003Ccode>async\u003C\u002Fcode> می‌خواهد. و \u003Ccode>await\u003C\u002Fcode> یعنی «بایست تا این promise به جوابِ واقعی برسد».)\u003C\u002Fp>\n",{"kind":20,"heading":38,"html":39},"۳. نمایش روی صفحه — و چکِ res.ok","\u003Ch2 id=\"۳-نمایش-روی-صفحه-—-و-چکِ-resok\">۳. نمایش روی صفحه — و چکِ \u003Ccode>res.ok\u003C\u002Fcode>\u003Ca class=\"head-anchor\" href=\"#%DB%B3-%D9%86%D9%85%D8%A7%DB%8C%D8%B4-%D8%B1%D9%88%DB%8C-%D8%B5%D9%81%D8%AD%D9%87-%E2%80%94-%D9%88-%DA%86%DA%A9%D9%90-resok\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Ccode>console.log\u003C\u002Fcode> فقط برای چشمِ توست؛ نمایش برای کاربر همان \u003Ccode>textContent\u003C\u002Fcode> همیشگی است. دادهٔ برگشتی را با نقطه بخوان و با template literal جمله بساز:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>const data = await res.json();\nconst weather = data.current_weather;\nweatherLine.textContent = `دمای الان: ${weather.temperature} درجه — باد: ${weather.windspeed} کیلومتر بر ساعت`;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>✅ \u003Cstrong>چک کن:\u003C\u002Fstrong> با یک کلیک، دمای واقعیِ همین لحظه روی کارت می‌نشیند.\u003C\u002Fp>\n\u003Cp>ولی یک تلهٔ بی‌صدا اینجاست. آدرس را عمداً خراب کن — \u003Ccode>forecast\u003C\u002Fcode> را بکن \u003Ccode>forecas\u003C\u002Fcode> — و دکمه را بزن. \u003Ccode>fetch\u003C\u002Fcode> خطا نمی‌دهد! سرور جواب داده، فقط جوابش «چنین چیزی ندارم» است. آن‌وقت \u003Ccode>data.current_weather\u003C\u002Fcode> وجود ندارد و console این خطای واقعی را می‌دهد:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'temperature')\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\n\u003Cp>🔧 \u003Cstrong>اگر کار نکرد:\u003C\u002Fstrong> پیام \u003Ccode>Cannot read properties of undefined\u003C\u002Fcode> تقریباً همیشه یعنی «داده‌ای که فکر می‌کردی هست، نیست». قبل از خواندن، سالم‌بودنِ جواب را بپرس: \u003Ccode>res.ok\u003C\u002Fcode> فقط وقتی \u003Ccode>true\u003C\u002Fcode> است که سرور جوابِ سالم داده باشد.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>if (res.ok) {\n  const data = await res.json();\n  const weather = data.current_weather;\n  weatherLine.textContent = `دمای الان: ${weather.temperature} درجه — باد: ${weather.windspeed} کیلومتر بر ساعت`;\n} else {\n  weatherLine.textContent = 'سرور جواب داد، ولی نه جوابی که می‌خواستیم. بعداً دوباره امتحان کن.';\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n",{"kind":20,"heading":41,"html":42},"۴. وقتی اینترنت قطع است: try\u002Fcatch","\u003Ch2 id=\"۴-وقتی-اینترنت-قطع-است-trycatch\">۴. وقتی اینترنت قطع است: try\u002Fcatch\u003Ca class=\"head-anchor\" href=\"#%DB%B4-%D9%88%D9%82%D8%AA%DB%8C-%D8%A7%DB%8C%D9%86%D8%AA%D8%B1%D9%86%D8%AA-%D9%82%D8%B7%D8%B9-%D8%A7%D8%B3%D8%AA-trycatch\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>جوابِ بد یک حالت بود؛ حالتِ بدتر این است که اصلاً جوابی نیاید — اینترنت قطع باشد یا سرور خاموش. آن‌وقت خودِ \u003Ccode>fetch\u003C\u002Fcode> شکست می‌خورد و کدت وسطِ راه می‌ترکد؛ در console چیزی شبیه \u003Ccode>TypeError: Failed to fetch\u003C\u002Fcode> می‌بینی. مهارش با یک جفت‌کلمهٔ ساده است: \u003Ccode>try\u003C\u002Fcode> یعنی «این‌ها را امتحان کن» و \u003Ccode>catch\u003C\u002Fcode> یعنی «اگر هر کدام شکست، به‌جای ترکیدن بیا اینجا». کدِ نهایی با هر دو مسیرِ نجات:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>\u002F\u002F script.js\nconst updateBtn = document.querySelector('#update-btn');\nconst weatherLine = document.querySelector('#weather-line');\n\nconst url = 'https:\u002F\u002Fapi.open-meteo.com\u002Fv1\u002Fforecast?latitude=35.69&amp;longitude=51.39&amp;current_weather=true';\n\nupdateBtn.addEventListener('click', async function () {\n  try {\n    const res = await fetch(url);\n\n    if (res.ok) {\n      const data = await res.json();\n      const weather = data.current_weather;\n      weatherLine.textContent = `دمای الان: ${weather.temperature} درجه — باد: ${weather.windspeed} کیلومتر بر ساعت`;\n    } else {\n      weatherLine.textContent = 'سرور جواب داد، ولی نه جوابی که می‌خواستیم. بعداً دوباره امتحان کن.';\n    }\n  } catch (error) {\n    console.log(error);\n    weatherLine.textContent = 'دسترسی به اینترنت نیست یا سرور در دسترس نیست — صفحه سرِ جایش است، بعداً دوباره امتحان کن.';\n  }\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>حالا آزمایشِ نهایی: آدرس را با یک دامنهٔ ناموجود عوض کن — مثلاً \u003Ccode>https:\u002F\u002Fno-such-server.example\u003C\u002Fcode> — و دکمه را بزن.\u003C\u002Fp>\n\u003Cp>✅ \u003Cstrong>چک کن:\u003C\u002Fstrong> به‌جای صفحهٔ شکسته یا سکوت، پیامِ دوستانهٔ خودت را می‌بینی — و بقیهٔ کارت، تیتر و متنش، سرِ جایش است. صفحه بدونِ داده هم هنوز یک صفحهٔ سالم و مفید است؛ به این می‌گویند \u003Cstrong>progressive\u003C\u002Fstrong>: داده تزئینِ صفحه است، نه ستونش.\u003C\u002Fp>\n\u003Cp>\u003Cpicture>\u003Csource type=\"image\u002Fwebp\" srcset=\"\u002F_img\u002F02-image-fallback-path.1400c1bf99.160.webp 160w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.320.webp 320w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.640.webp 640w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.1280.webp 1280w\" sizes=\"(max-width: 900px) 100vw, 800px\">\u003Cimg src=\"\u002F_img\u002F02-image-fallback-path.1400c1bf99.1280.jpg\" srcset=\"\u002F_img\u002F02-image-fallback-path.1400c1bf99.160.jpg 160w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.320.jpg 320w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.640.jpg 640w, \u002F_img\u002F02-image-fallback-path.1400c1bf99.1280.jpg 1280w\" sizes=\"(max-width: 900px) 100vw, 800px\" alt=\"دو مسیر از یک ابر سرور به یک کارت وب: مسیر سالم که بسته‌ای از داده را می‌رساند، و مسیر بریده‌شده که به یک پیام نرم و امن روی همان کارت ختم می‌شود\" width=\"1376\" height=\"768\" loading=\"lazy\" decoding=\"async\">\u003C\u002Fpicture>\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>💡 \u003Cstrong>نکته:\u003C\u002Fstrong> آدرس‌ها عوض می‌شوند و سرویس‌ها روزی خاموش می‌شوند — قول نمی‌دهیم این API همیشه باشد. چیزی که می‌ماند \u003Cstrong>الگو\u003C\u002Fstrong>ست: \u003Ccode>fetch\u003C\u002Fcode> ← چکِ \u003Ccode>res.ok\u003C\u002Fcode> ← خواندنِ JSON ← نمایش، و همیشه یک \u003Ccode>catch\u003C\u002Fcode> با پیامِ آبرومند. اگر این سرویس روزی نبود، صفحه‌ات نمی‌شکند؛ همان پیامِ catch را نشان می‌دهد. الگو را که داشته باشی، هر API دیگری همین است.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>و برای خطاهایی که هنوز نمی‌شناسی، یک همراه داری:\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>🤖 \u003Cstrong>با AI:\u003C\u002Fstrong> خطای قرمزِ console را کپی کن و به دستیار AI ات بده: «این خطا یعنی چه؟ مشکل از آدرس است، از اینترنت، یا از کدِ من؟» بعد جوابش را در آزمایشگاه محک بزن — اگر گفت آدرس خراب است، آدرسِ سالم را برگردان و ببین واقعاً درست می‌شود. پیام‌های شبکه بهترین تمرینِ «AI هم اشتباه می‌کند» هستند، چون AI کد و اینترنتِ تو را ندیده و فقط حدس می‌زند.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n",{"kind":20,"heading":44,"html":45},"کدِ کاملِ این فصل","\u003Ch2 id=\"کدِ-کاملِ-این-فصل\">کدِ کاملِ این فصل\u003Ca class=\"head-anchor\" href=\"#%DA%A9%D8%AF%D9%90-%DA%A9%D8%A7%D9%85%D9%84%D9%90-%D8%A7%DB%8C%D9%86-%D9%81%D8%B5%D9%84\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Ccode>script.js\u003C\u002Fcode> را بالا دیدی؛ این هم \u003Ccode>index.html\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre class=\"code-block\" dir=\"ltr\">\u003Ccode>&lt;!-- index.html --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;fa&quot; dir=&quot;rtl&quot;&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;\n    &lt;title&gt;کارت آب‌وهوا&lt;\u002Ftitle&gt;\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;styles.css&quot;&gt;\n  &lt;\u002Fhead&gt;\n  &lt;body&gt;\n    &lt;main class=&quot;card&quot;&gt;\n      &lt;h1&gt;آب‌وهوای تهران&lt;\u002Fh1&gt;\n      &lt;p&gt;این کارت با یک کلیک، دادهٔ زندهٔ آب‌وهوا را از اینترنت می‌گیرد.&lt;\u002Fp&gt;\n      &lt;p id=&quot;weather-line&quot;&gt;هنوز داده‌ای نگرفته‌ایم — دکمه را بزن.&lt;\u002Fp&gt;\n      &lt;button id=&quot;update-btn&quot; type=&quot;button&quot;&gt;به‌روزرسانی آب‌وهوا&lt;\u002Fbutton&gt;\n    &lt;\u002Fmain&gt;\n    &lt;script src=&quot;script.js&quot;&gt;&lt;\u002Fscript&gt;\n  &lt;\u002Fbody&gt;\n&lt;\u002Fhtml&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n",{"kind":20,"heading":47,"html":48},"واژه‌های تازهٔ این فصل","\u003Ch2 id=\"واژه‌های-تازهٔ-این-فصل\">واژه‌های تازهٔ این فصل\u003Ca class=\"head-anchor\" href=\"#%D9%88%D8%A7%DA%98%D9%87%E2%80%8C%D9%87%D8%A7%DB%8C-%D8%AA%D8%A7%D8%B2%D9%87%D9%94-%D8%A7%DB%8C%D9%86-%D9%81%D8%B5%D9%84\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cdiv class=\"table-wrap\">\u003Ctable>\u003Cthead>\n\u003Ctr>\n\u003Cth>کلمه\u003C\u002Fth>\n\u003Cth>تلفظ به حروف فارسی\u003C\u002Fth>\n\u003Cth>یعنی چه\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>fetch\u003C\u002Ftd>\n\u003Ctd>فِچ\u003C\u002Ftd>\n\u003Ctd>فرستادنِ درخواست به یک آدرس، از داخلِ کد\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>API\u003C\u002Ftd>\n\u003Ctd>اِی‌پی‌آی\u003C\u002Ftd>\n\u003Ctd>آدرسی که به‌جای صفحه، دادهٔ خام پس می‌دهد\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>JSON\u003C\u002Ftd>\n\u003Ctd>جِی‌سان\u003C\u002Ftd>\n\u003Ctd>قالبِ متنیِ داده که به مقدار و آرایه و شیء تبدیل می‌شود\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>promise\u003C\u002Ftd>\n\u003Ctd>پرامیس\u003C\u002Ftd>\n\u003Ctd>رسیدِ جوابی که هنوز نرسیده\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>async\u003C\u002Fcode> \u002F \u003Ccode>await\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>اِی‌سینک \u002F اِوِیت\u003C\u002Ftd>\n\u003Ctd>علامتِ functionِ منتظر \u002F «بایست تا جواب برسد»\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>res.ok\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>رِس دات اُکِی\u003C\u002Ftd>\n\u003Ctd>آیا جوابِ سرور سالم است؟\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>try\u003C\u002Fcode> \u002F \u003Ccode>catch\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>ترای \u002F کَچ\u003C\u002Ftd>\n\u003Ctd>امتحان کن؛ اگر شکست، مسیرِ نجات\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>",{"kind":50,"heading":51,"html":52},"checkpoint","تمرین‌ها","\u003Ch2 id=\"تمرین‌ها\">تمرین‌ها\u003Ca class=\"head-anchor\" href=\"#%D8%AA%D9%85%D8%B1%DB%8C%D9%86%E2%80%8C%D9%87%D8%A7\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Checkpoint.\u003C\u002Fstrong> قبل از تمرین، بدون نگاه‌کردن به بالا جواب بده: فرقِ «سرور جوابِ بد داد» با «سرور اصلاً جواب نداد» چیست — و هرکدام با کدام ابزار مهار می‌شود؟ (اولی با \u003Ccode>res.ok\u003C\u002Fcode>، دومی با \u003Ccode>try\u003C\u002Fcode>\u002F\u003Ccode>catch\u003C\u002Fcode>.)\u003C\u002Fp>\n\u003Cp>\u003Cstrong>تمرین اجباری:\u003C\u002Fstrong> عرض و طولِ جغرافیاییِ شهرِ خودت — یا هر شهری که دوستش داری — را پیدا کن (در هر سرویسِ نقشه با یک کلیکِ راست به دست می‌آید) و در \u003Ccode>url\u003C\u002Fcode> بگذار؛ تیترِ کارت را هم به اسمِ همان شهر عوض کن.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>تمرین ستاره‌دار ⭐:\u003C\u002Fstrong> بینِ کلیک و رسیدنِ جواب یک لحظهٔ خالی هست. اولِ listener — قبل از \u003Ccode>fetch\u003C\u002Fcode> — بنویس \u003Ccode>weatherLine.textContent = 'در حال گرفتنِ داده…';\u003C\u002Fcode> تا کاربر بداند اتفاقی در جریان است. اگر اینترنتت آن‌قدر سریع است که پیام را نمی‌بینی، اتصال را قطع کن تا هم پیامِ انتظار و هم مسیرِ \u003Ccode>catch\u003C\u002Fcode> را واقعی ببینی.\u003C\u002Fp>\n",{"kind":20,"heading":54,"html":55},"در فصل بعد","\u003Ch2 id=\"در-فصل-بعد\">در فصل بعد\u003Ca class=\"head-anchor\" href=\"#%D8%AF%D8%B1-%D9%81%D8%B5%D9%84-%D8%A8%D8%B9%D8%AF\" aria-label=\"پیوند به این بخش\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>جعبه‌ابزارت کامل شد: صفحه می‌سازی، استایل می‌دهی، رویداد می‌گیری، از داده فهرست می‌سازی و حالا از اینترنت داده می‌گیری. فصل بعد — آخرین فصلِ تاروپود — هیچ چیزِ تازه‌ای یاد نمی‌گیری؛ همه‌چیز را کنارِ هم می‌گذاری: یک صفحهٔ آشنا را برمی‌داری و با همین ابزارها جانش می‌دهی.\u003C\u002Fp>\n",{"course":57,"entitled":65,"lessons":66,"payments_enabled":65,"terms":282,"live":5},{"active_window":58,"effective_price_toman":59,"free":5,"lesson_count":60,"price_toman":61,"slug":62,"summary_fa":63,"title_fa":64},null,0,71,1500000,"taropood","از صفر تا ساختن سایت واقعی با HTML و CSS. متن‌محور، با آزمایشگاه زندهٔ داخل مرورگر و اصطلاح‌های اصیل.","تاروپود — خودآموز HTML و CSS",false,[67,71,75,79,83,87,91,94,97,100,104,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,280,281],{"free_preview":5,"order":68,"slug":69,"source":8,"term":68,"title_fa":70},1,"t1-s01-first-page","فصل ۰۱ — اولین صفحهٔ وب تو",{"free_preview":5,"order":72,"slug":73,"source":8,"term":68,"title_fa":74},2,"t1-s02-text","فصل ۰۲ — متن: عنوان و پاراگراف",{"free_preview":5,"order":76,"slug":77,"source":8,"term":68,"title_fa":78},3,"t1-s03-links","فصل ۰۳ — پیوند: چیزی که وب را وب کرد",{"free_preview":5,"order":80,"slug":81,"source":8,"term":68,"title_fa":82},4,"t1-s04-images","فصل ۰۴ — تصویر",{"free_preview":5,"order":84,"slug":85,"source":8,"term":68,"title_fa":86},5,"t1-s05-lists","فصل ۰۵ — فهرست",{"free_preview":5,"order":88,"slug":89,"source":8,"term":68,"title_fa":90},6,"t1-s06-semantic","فصل ۰۶ — اسکلت معنادار صفحه",{"free_preview":5,"order":9,"slug":92,"source":8,"term":68,"title_fa":93},"t1-s07-tables","فصل ۰۷ — جدول، فقط برای داده",{"free_preview":5,"order":6,"slug":95,"source":8,"term":68,"title_fa":96},"t1-s08-forms","فصل ۰۸ — فرم: گرفتن ورودی",{"free_preview":5,"order":15,"slug":98,"source":8,"term":68,"title_fa":99},"t1-s09-accessibility","فصل ۰۹ — دسترس‌پذیری از همان HTML",{"free_preview":5,"order":101,"slug":102,"source":8,"term":68,"title_fa":103},10,"t1-s10-media","فصل ۱۰ — ویدیو و صدا",{"free_preview":5,"order":105,"slug":106,"source":8,"term":68,"title_fa":107},11,"t1-s11-first-project","فصل ۱۱ — پروژه: صفحهٔ معرفی خودت",{"free_preview":5,"order":68,"slug":109,"source":8,"term":72,"title_fa":110},"t2-s01-first-css","فصل ۰۱ — اولین CSS",{"free_preview":5,"order":72,"slug":112,"source":8,"term":72,"title_fa":113},"t2-s02-selectors","فصل ۰۲ — selector ها",{"free_preview":5,"order":76,"slug":115,"source":8,"term":72,"title_fa":116},"t2-s03-cascade","فصل ۰۳ — cascade، specificity و inheritance",{"free_preview":5,"order":80,"slug":118,"source":8,"term":72,"title_fa":119},"t2-s04-box-model","فصل ۰۴ — جعبه‌ها: box model",{"free_preview":5,"order":84,"slug":121,"source":8,"term":72,"title_fa":122},"t2-s05-units-colors","فصل ۰۵ — واحد و رنگ",{"free_preview":5,"order":88,"slug":124,"source":8,"term":72,"title_fa":125},"t2-s06-typography","فصل ۰۶ — تایپوگرافی و فونت فارسی",{"free_preview":5,"order":9,"slug":127,"source":8,"term":72,"title_fa":128},"t2-s07-flow","فصل ۰۷ — جریان عادی صفحه",{"free_preview":5,"order":6,"slug":130,"source":8,"term":72,"title_fa":131},"t2-s08-decoration","فصل ۰۸ — پس‌زمینه، حاشیه، سایه",{"free_preview":5,"order":15,"slug":133,"source":8,"term":72,"title_fa":134},"t2-s09-custom-props","فصل ۰۹ — متغیرهای خودت در CSS",{"free_preview":5,"order":101,"slug":136,"source":8,"term":72,"title_fa":137},"t2-s10-devtools","فصل ۱۰ — DevTools: ابزار واقعی",{"free_preview":5,"order":105,"slug":139,"source":8,"term":72,"title_fa":140},"t2-s11-styled-project","فصل ۱۱ — صفحهٔ ترم ۱ را زنده کن",{"free_preview":5,"order":68,"slug":142,"source":8,"term":76,"title_fa":143},"t3-s01-layout-intro","فصل ۰۱ — چیدمان: از جریان عادی شروع کن",{"free_preview":5,"order":72,"slug":145,"source":8,"term":76,"title_fa":146},"t3-s02-flex-basics","فصل ۰۲ — flexbox: یک محور",{"free_preview":5,"order":76,"slug":148,"source":8,"term":76,"title_fa":149},"t3-s03-flex-align","فصل ۰۳ — چیدن و وسط‌چین کردن",{"free_preview":5,"order":80,"slug":151,"source":8,"term":76,"title_fa":152},"t3-s04-flex-grow","فصل ۰۴ — انعطاف واقعی",{"free_preview":5,"order":84,"slug":154,"source":8,"term":76,"title_fa":155},"t3-s05-grid-basics","فصل ۰۵ — grid: دو محور",{"free_preview":5,"order":88,"slug":157,"source":8,"term":76,"title_fa":158},"t3-s06-grid-placement","فصل ۰۶ — جای‌گذاری در grid",{"free_preview":5,"order":9,"slug":160,"source":8,"term":76,"title_fa":161},"t3-s07-grid-areas","فصل ۰۷ — layout کامل صفحه با grid",{"free_preview":5,"order":6,"slug":163,"source":8,"term":76,"title_fa":164},"t3-s08-position","فصل ۰۸ — position",{"free_preview":5,"order":15,"slug":166,"source":8,"term":76,"title_fa":167},"t3-s09-stacking","فصل ۰۹ — z-index و stacking context",{"free_preview":5,"order":101,"slug":169,"source":8,"term":76,"title_fa":170},"t3-s10-logical","فصل ۱۰ — logical properties",{"free_preview":5,"order":105,"slug":172,"source":8,"term":76,"title_fa":173},"t3-s11-layout-project","فصل ۱۱ — پروژه: layout یک سایت کامل",{"free_preview":5,"order":68,"slug":175,"source":8,"term":80,"title_fa":176},"t4-s01-responsive-intro","فصل ۰۱ — responsive یعنی چه",{"free_preview":5,"order":72,"slug":178,"source":8,"term":80,"title_fa":179},"t4-s02-media-queries","فصل ۰۲ — media query",{"free_preview":5,"order":76,"slug":181,"source":8,"term":80,"title_fa":182},"t4-s03-responsive-images","فصل ۰۳ — تصویر responsive",{"free_preview":5,"order":80,"slug":184,"source":8,"term":80,"title_fa":185},"t4-s04-fluid-type","فصل ۰۴ — تایپوگرافی سیال و ریاضی در CSS",{"free_preview":5,"order":84,"slug":187,"source":8,"term":80,"title_fa":188},"t4-s05-container-queries","فصل ۰۵ — container query",{"free_preview":5,"order":88,"slug":190,"source":8,"term":80,"title_fa":191},"t4-s06-responsive-nav","فصل ۰۶ — ناوبری responsive",{"free_preview":5,"order":9,"slug":193,"source":8,"term":80,"title_fa":194},"t4-s07-dark-mode","فصل ۰۷ — dark mode",{"free_preview":5,"order":6,"slug":196,"source":8,"term":80,"title_fa":197},"t4-s08-responsive-project","فصل ۰۸ — پروژه: سایت کاملاً responsive",{"free_preview":5,"order":68,"slug":199,"source":8,"term":84,"title_fa":200},"t5-s01-states","فصل ۰۱ — حالت‌ها: pseudo-class تعاملی",{"free_preview":5,"order":72,"slug":202,"source":8,"term":84,"title_fa":203},"t5-s02-structural-selectors","فصل ۰۲ — selector های ساختاری و combinator ها",{"free_preview":5,"order":76,"slug":205,"source":8,"term":84,"title_fa":206},"t5-s03-pseudo-elements","فصل ۰۳ — pseudo-element ها",{"free_preview":5,"order":80,"slug":208,"source":8,"term":84,"title_fa":209},"t5-s04-forms-styling","فصل ۰۴ — استایل فرم",{"free_preview":5,"order":84,"slug":211,"source":8,"term":84,"title_fa":212},"t5-s05-forms-validation","فصل ۰۵ — اعتبارسنجی فرم",{"free_preview":5,"order":88,"slug":214,"source":8,"term":84,"title_fa":215},"t5-s06-transforms","فصل ۰۶ — transform",{"free_preview":5,"order":9,"slug":217,"source":8,"term":84,"title_fa":218},"t5-s07-transitions","فصل ۰۷ — transition",{"free_preview":5,"order":6,"slug":220,"source":8,"term":84,"title_fa":221},"t5-s08-animation","فصل ۰۸ — animation و احترام به کاربر",{"free_preview":5,"order":15,"slug":223,"source":8,"term":84,"title_fa":224},"t5-s09-has-selector","فصل ۰۹ — :has() و تعامل بدون JavaScript",{"free_preview":5,"order":101,"slug":226,"source":8,"term":84,"title_fa":227},"t5-s10-interaction-project","فصل ۱۰ — پروژه: یک component تعاملی بدون JS",{"free_preview":5,"order":68,"slug":229,"source":8,"term":88,"title_fa":230},"t6-s01-organizing","فصل ۰۱ — CSS را سازماندهی کن",{"free_preview":5,"order":72,"slug":232,"source":8,"term":88,"title_fa":233},"t6-s02-layers-nesting","فصل ۰۲ — `@layer` و nesting",{"free_preview":5,"order":76,"slug":235,"source":8,"term":88,"title_fa":236},"t6-s03-components","فصل ۰۳ — مثل component فکر کن",{"free_preview":5,"order":80,"slug":238,"source":8,"term":88,"title_fa":239},"t6-s04-design-system","فصل ۰۴ — design system کوچک خودت",{"free_preview":5,"order":84,"slug":241,"source":8,"term":88,"title_fa":242},"t6-s05-svg-icons","فصل ۰۵ — SVG و آیکون",{"free_preview":5,"order":88,"slug":244,"source":8,"term":88,"title_fa":245},"t6-s06-accessibility-deep","فصل ۰۶ — دسترس‌پذیری عمیق",{"free_preview":5,"order":9,"slug":247,"source":8,"term":88,"title_fa":248},"t6-s07-performance","فصل ۰۷ — سرعت",{"free_preview":5,"order":6,"slug":250,"source":8,"term":88,"title_fa":251},"t6-s08-architecture","فصل ۰۸ — معماری CSS در مقیاس بزرگ",{"free_preview":5,"order":15,"slug":253,"source":8,"term":88,"title_fa":254},"t6-s09-debugging","فصل ۰۹ — اشکال‌زدایی مثل حرفه‌ای‌ها",{"free_preview":5,"order":101,"slug":256,"source":8,"term":88,"title_fa":257},"t6-s10-capstone-build","فصل ۱۰ — پروژهٔ نهایی: ساخت سایت چندصفحه‌ای",{"free_preview":5,"order":105,"slug":259,"source":8,"term":88,"title_fa":260},"t6-s11-capstone-ship","فصل ۱۱ — پروژهٔ نهایی: انتشار زنده",{"free_preview":5,"order":68,"slug":262,"source":8,"term":9,"title_fa":263},"t7-s01-why-js","فصل ۰۱ — چرا JavaScript؟ اولین اسکریپت",{"free_preview":5,"order":72,"slug":265,"source":8,"term":9,"title_fa":266},"t7-s02-variables","فصل ۰۲ — متغیر و مقدار",{"free_preview":5,"order":76,"slug":268,"source":8,"term":9,"title_fa":269},"t7-s03-select-change","فصل ۰۳ — پیدا کردن و تغییرِ عنصر",{"free_preview":5,"order":80,"slug":271,"source":8,"term":9,"title_fa":272},"t7-s04-events","فصل ۰۴ — رویداد",{"free_preview":5,"order":84,"slug":274,"source":8,"term":9,"title_fa":275},"t7-s05-toggle-class","فصل ۰۵ — روشن\u002Fخاموش‌کردنِ یک class: پلِ CSS و JS",{"free_preview":5,"order":88,"slug":277,"source":8,"term":9,"title_fa":278},"t7-s06-forms-js","فصل ۰۶ — کار با فرم در JavaScript",{"free_preview":5,"order":9,"slug":12,"source":8,"term":9,"title_fa":13},{"free_preview":5,"order":6,"slug":7,"source":8,"term":9,"title_fa":10},{"free_preview":5,"order":15,"slug":16,"source":8,"term":9,"title_fa":17},[],1784860314229]