<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Zahra Mirkazemi</title>
        <link>https://virgool.io/feed/@zahramirkazemi</link>
        <description>من زهرا میرکاظمی هستم.توسعه‌دهنده‌ی فرانت‌اند با تمرکز بر طراحی رابط کاربری بهینه و کدنویسی تمیز. در این‌جا تجربیات و آموخته‌های فنی‌ام را با هدف یادگیری و اشتراک دانش منتشر می‌کنم.</description>
        <language>fa</language>
        <pubDate>2026-06-16 07:47:10</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2011946/avatar/Hftw8f.jpg?height=120&amp;width=120</url>
            <title>Zahra Mirkazemi</title>
            <link>https://virgool.io/@zahramirkazemi</link>
        </image>

                    <item>
                <title>مستندات دسترسی پذیری</title>
                <link>https://virgool.io/@zahramirkazemi/%D9%85%D8%B3%D8%AA%D9%86%D8%AF%D8%A7%D8%AA-%D8%AF%D8%B3%D8%AA%D8%B1%D8%B3%DB%8C-%D9%BE%D8%B0%DB%8C%D8%B1%DB%8C-aoq4xcpofgap</link>
                <description>دسترسی پذیری (A11y) توی توسعه‌ی فرانت‌اند از اون موضوعاتیه که همه قبول داریم مهمه… ولی همیشه عقب میندازیمش.من توی ریفکتور کامل دسترسی‌پذیری محصول بزرگ و در حال توسعه در پرس‌لاین، با الگوها و مشکلاتی روبه‌رو شدم که قبل از اون اصلاً دیده نمی‌شدند.وقتی با اسکرین‌ریدر روشن و فقط با کیبورد سراغ محصول خودت می‌روی، چیزهایی رو می‌بینی که قبلاً اصلاً متوجهشون نبودی.عناصر تعاملی که بی‌صدا از کار می‌افتن.مودال‌هایی که باز می‌شن اما هیچ اعلامی ندارن.دکمه‌هایی که ظاهر بی‌نقصی دارند اما اسکرین ریدر حتی متوجه دکمه‌ها نمیشه.این ریفکتور شد نقطه‌ی عطف ما.برای همین بعد از تموم شدنش، تصمیم گرفتم تمام نکات رو تبدیل کنم به یک راهنمای ساده و عملی برای توسعه‌دهنده‌های فرانت‌اند.لینک داک: https://github.com/zahramirkazemi/Documentations/tree/main/accessibility(این ریپو پایانی نداره و احتمالا مداوم به‌روزرسانی می‌شه. اگر برات مفید بود، خوشحال می‌شم یک ⭐ بدی!)🗺️ داخل این داکیومنت چه خبره؟ — یک نقشه‌ی کاربردی برای توسعه‌دهنده‌هااگر فولدر accessibility رو توی ریپوی نگاه کنید، می‌بینید ساختارش کاملاً مطابق با شکل واقعی برخورد ما با مسأله طراحی شده: منطقی، مرحله‌ای و مقیاس‌پذیر.داخلش بخش‌های زیر رو پیدا می‌کنید:ساختار Semantic و HTML درست: از تگ‌های درست و هدینگ‌های منظم تا لندمارک‌هایی مثل header،‌ nav و main که فهم DOM رو برای اسکرین‌ریدر ممکن می‌کنن.ناوبری با کیبورد و مدیریت فوکوس: همه‌ی کنترل‌ها باید با کیبورد قابل دسترسی باشن: ترتیب تب، فوکوس واضح، skip link‌ها و…ARIA و ویژگی‌های دسترسی: در جاهایی که Semantic HTML کافی نیست(مثلاً کامپوننت‌های داینامیک) روش صحیح استفاده از role و state و propertyهای ARIA. (فقط «به اندازه‌ی لازم»، نه به‌عنوان چسب موقت.)رنگ، کنتراست و دسترسی بصری: نسبت کنتراست، تایپوگرافی خوانا، تم‌های قابل‌دسترس و کمک به کاربران کوررنگ.فرم‌ها، لیبل‌ها و مدیریت ارورها: ورودی‌ها با لیبل درست، پیام‌های خطا قابل درک برای اسکرین‌ریدر، و ترتیب تب منطقی.تست و اتوماسیون: ادغام تست‌های A11y توی بیلد یا PRها: با ابزارهایی مثل axe و Lighthouse، به‌علاوه تست‌های دستی با کیبورد و Screen Reader.در یک جمله: این ساختار نشون می‌ده ما دسترسی رو یک «فیچر اضافه» نمی‌بینیم، بلکه بخشی از هویت یک کدبیس سالمه.♿ چرا دسترسی‌پذیری مهمه؟علاوه بر اینکه «درستش اینه»، فواید عملی زیادی هم داره:شمولیت و برابری: کاربرانی با محدودیت بینایی، اختلالات حرکتی، یا وابسته به کیبورد/اسکرین‌ریدر باید بتونن مثل همه از پورسلاین استفاده کنن.تجربه‌ی کاربری بهتر برای همه: کنتراست بهتر، ساختار معنایی درست، فوکوس واضح و ناوبری استاندارد حتی برای کاربران عادی هم تجربه‌ی بهتری ایجاد می‌کنه.نگهداشت طولانی‌مدت: وقتی کد تمیز و معنایی نوشته شده باشه، پایدارتره، کمتر هک نیاز داره، و توسعه‌دهنده‌های بعدی هم راحت‌تر باهاش کار می‌کنن.مسئولیت حرفه‌ای و استانداردها: با افزایش آگاهی و قوانین، رعایت WCAG دیگه یک انتخاب نیست — یه استاندارده.✨ جمع‌بندی — فراتر از کد، تغییر نگرشنوشتن UI فقط چیدن پیکسل‌ها کنار هم نیست، ساختن یک تجربه‌ی انسانی‌ه.برای مدت‌ها، دسترسی‌پذیری یک «اپشن کاربردی» بود.اما تجربه‌ی من توی پورسلاین یک چیز رو روشن کرد:دسترسی‌پذیری یک ویژگی نیست، یک مسئولیت است.انتشار این داک‌ها تلاشی کوچک برای کمک به یک حرکت بزرگ‌تره. اینکه وب برای همه قابل استفاده باشه.اگر به کیفیت، تجربه‌ی کاربری و فراگیر بودن اعتقاد داری، امیدوارم این ریپو رو مطالعه کنی.اگر این مطلب برات مفید بود، لطفا لایک کن—تا توسعه‌دهنده‌های بیشتری به محتوای دسترسی‌پذیری برسن.و خوشحال می‌شم تجربه‌ها یا چالش‌های شما رو بشنوم؛ کامنت بذارید تا از هم یاد بگیریم. 💬💛</description>
                <category>Zahra Mirkazemi</category>
                <author>Zahra Mirkazemi</author>
                <pubDate>Wed, 03 Dec 2025 21:49:30 +0330</pubDate>
            </item>
                    <item>
                <title>چطور به یه فایل جاوااسکریپت استاتیک اطلاعات بفرستیم؟</title>
                <link>https://virgool.io/@zahramirkazemi/%DA%86%D8%B7%D9%88%D8%B1-%D8%A8%D9%87-%DB%8C%D9%87-%D9%81%D8%A7%DB%8C%D9%84-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A7%D8%B3%D8%AA%D8%A7%D8%AA%DB%8C%DA%A9-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA-%D8%A8%D9%81%D8%B1%D8%B3%D8%AA%DB%8C%D9%85-iuhjyf3wscwi</link>
                <description>این روش برای وقتی خوبه که دیتا ساختاریافتهتره یا از قبل توی JavaScript قراره آماده بشه. ولی مشکلش اینه که از متغیرهای global استفاده میکنه که ممکنه توی پروژههای بزرگ باعث تداخل بشه.۲. گرفتن داده از query string یا URLمثلاً:&lt;script src=&quot;cdn-address/widget.js?theme=dark&amp;lang=fa&quot;&gt;و توی فایل JS با location.currentScript.src یا document.currentScript پارامترها رو بخونی. این روش برای مقادیر ساده خوبه، ولی برای دادههای پیچیده یهکم شکننده میشه.🏁 جمعبندیاگه قراره اسکریپت قابل استفاده برای سایتهای دیگه بنویسی (یه چیزی که فقط با یه بشه استفاده کرد)، استفاده از data-* واقعاً یه روش عالیه. هم سادهست، هم قابل انعطاف، هم خیلی راحت قابل توسعهست.به جای پیچوندن یا سراغ روشهای عجیبغریب رفتن، همین تکنیک ساده میتونه کلی از نیازها رو پوشش بده.💬 تو چی فکر میکنی؟اگه تجربهای داری یا راهحل دیگهای به ذهنت میرسه (مثلاً استفاده از &lt;script type=&quot;application/json&quot;&gt; یا حتی Web Component)، خوشحال میشم بدونم کدوم روش رو بیشتر میپسندی و چرا.بنویس برام. گفتوگو همیشه باعث یاد گرفتن چیزای بهتر میشه 🌱🗣 اگه تجربهای توی این زمینه داشتی یا سوالی برات پیش اومده، خوشحال میشم توی بخش نظرات بشنوم.🧡 اگه این مقاله برات مفید بود، با دوستات یا همتیمیهات به اشتراک بذار!</description>
                <category>Zahra Mirkazemi</category>
                <author>Zahra Mirkazemi</author>
                <pubDate>Sat, 24 May 2025 12:30:25 +0330</pubDate>
            </item>
                    <item>
                <title>پشت پرده‌ی تفاوت Query string و Hash fragment در URL</title>
                <link>https://virgool.io/@zahramirkazemi/%D9%BE%D8%B4%D8%AA-%D9%BE%D8%B1%D8%AF%D9%87-%DB%8C-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-query-string-%D9%88-hash-fragment-%D8%AF%D8%B1-url-iu9zbzyzltla</link>
                <description>چند وقت پیش یه اتفاق ساده ولی جالب برام افتاد. داشتم یه لینکی رو بررسی میکردم و دیدم دوتا URL هستن که ظاهرشون یکیه، ولی یه کوچولو فرق دارن:https://example.com/page?panel_view=trueوhttps://example.com/page#/?panel_view=trueظاهرشون خیلی شبیه به همه، ولی وقتی دقیقتر نگاه میکنی، متوجه میشی قضیه یه کم عمیقتره. بیاید با هم ببینیم این تفاوت ریز چه تاثیری میتونه توی دنیای فرانتاند داشته باشه.فرق بین Query String و Hash Fragment چیه واقعاً؟وقتی یه URL رو باز میکنی، فقط بخشی از اون واقعاً به سرور فرستاده میشه.اینجاست که فرق اصلی مشخص میشه:✨ خلاصهش اینه:هر چی قبل از # باشه → میره سمت سرور.هر چی بعد از # باشه → فقط توی مرورگر خونده میشه، سرور هیچخبری ازش نداره.مثلاً اگه یه اپلیکیشن تکصفحهای (SPA) مثل React یا Vue داشته باشی، این بخش # میتونه خیلی مهم بشه. چون اونجاست که فرانتاند تصمیم میگیره کاربر چی ببینه.چرا اصلاً از # استفاده میکنن؟قبلاً از # برای اسکرول کردن به یه بخش خاص توی صفحه استفاده میکردیم (مثلاً #about-us).ولی الان توی اپلیکیشنهای مدرن، ازش برای مدیریت مسیر (routing) استفاده میکنیم، بدون اینکه صفحه دوباره لود بشه. مثلاً توی یه اپ تکصفحهای ممکنه #/login یا #/profile داشته باشی که فقط ظاهر صفحه رو تغییر میده، نه خود URL اصلی رو.کدوم یکی بهتره؟ آیا فرقی دارن؟واقعیت اینه که بستگی داره اپلیکیشنت چطور ساخته شده باشه:اگه اپ با # کار میکنه (یعنی مسیرهاش با هش تنظیم شدن)، اون نسخهی هشدار لازمه.ولی اگه سرور با query string کار داره، پس اون یکی نسخه باید استفاده بشه.گاهی اوقات اشتباه در انتخاب بین این دوتا باعث میشه یه صفحه درست باز نشه یا حتی اطلاعات تحلیلی (analytics) ناقص بشن. پس حتی همین تفاوت کوچیک میتونه کلی دردسر درست کنه.وقتی کش وارد ماجرا میشه…بذار یه ذره فنیتر بشیم:🧠 مرورگرها و CDNها (مثل Cloudflare) به این دوتا بخش URL رفتارهای مختلفی دارن:Query string (?panel_view=true) باعث میشه URL متفاوت به نظر برسه. یعنی اگه panel_view=true عوض بشه، مرورگر اون رو یه URL جدید میدونه و ممکنه دوباره از سرور درخواست بفرسته.Hash fragment (#something) اصلاً تاثیری روی کش نداره. یعنی چه #about باشه، چه #hello، مرورگر فکر میکنه هنوز همون صفحهست.💡 اگه میخوای از کش عبور کنی یا محتوای متفاوتی رو از سرور بگیری، query string رو انتخاب کن.اگه فقط یه رفتاری سمت کلاینت بخوای، هش کارت رو راه میندازه.چطوری این مقادیر رو توی Next.js بخونیم؟حالا برسیم به قسمت کاربردی ماجرا؛ توی پروژههای Next.js معمولاً با هردوش طرفیم:👉 گرفتن query string خیلی سادهست:import { useRouter } from &#039;next/router&#039;;

const Page = () =&gt; {
  const router = useRouter();
  const { panel_view } = router.query;

  return &lt;p&gt;panel_view: {panel_view}&lt;/p&gt;;
};Next خودش اینا رو میفهمه و لازم نیست کار خاصی بکنی.👉 گرفتن hash fragment یه کوچولو فرق داره:چون این بخش اصلاً به سرور نمیرسه، باید از .hash استفاده کنیم:import { useEffect, useState } from &#039;react&#039;;

const Page = () =&gt; {
  const [hash, setHash] = useState(&#039;&#039;);

  useEffect(() =&gt; {
    setHash.hash);
  }, []);

  return &lt;p&gt;مقدار هش: {hash}&lt;/p&gt;;
};نکته: چون window فقط سمت کلاینت وجود داره، این کد حتماً باید داخل useEffect باشه.جمعبندی: گاهی جزئیات کوچیک، فرق بزرگی میسازنما معمولاً عادت داریم URLها رو فقط به چشم یه لینک ببینیم. ولی حقیقت اینه که همین جزئیات کوچیک مثل ? یا # میتونن مسیر اجرا، کش شدن، نمایش محتوا یا حتی تجربه کاربر رو تغییر بدن.دفعه بعدی که خواستی یه لینک بسازی، حتماً بهش دقت کن. شاید همون # کوچیک، یه اتفاق بزرگ پشتش باشه. 😉تا حالا شده به خاطر همین تفاوتهای ریز، یه باگی بخوره توی پروژهت؟بیایید تو کامنتا با هم در موردش گپ بزنیم، خوشحال میشم تجربههاتون رو بشنوم!</description>
                <category>Zahra Mirkazemi</category>
                <author>Zahra Mirkazemi</author>
                <pubDate>Fri, 23 May 2025 22:43:59 +0330</pubDate>
            </item>
            </channel>
</rss>