استفاده صحیح از addEventListener و querySelector

اکثرا با selector های jQuery آشنا هستیم که چقدر راحت می تونستیم به المان های موجود در صفحه یک event رو add کنیم و با کمک اون ها توابع مختلف رو در زمان اجرای event به کار بگیریم. شاید تو خیلی از پروژه ها و کاربردهای کوچیک لازم نباشه از jQuery استفاده کنیم و بشه با امکانات خود Pure JavaScript همون سناریو رو جلو ببریم و باهاش functionality های خاص صفحه رو اجرا کنیم ...

استفاده صحیح از addEventListener و querySelector
استفاده صحیح از addEventListener و querySelector

استفاده از querySelector و querySelectorAll در جاوااسکریپت

خوب اگر به معنی کلمه هم توجه کنیم query یعنی به نوعی پرس و جو و یا تحقیق و selector هم یعنی انتخاب و گزینش ... ولی خوب قراره این قابلیت برامون چیکار کنه ؟!

اکثر شما با document.getElementById آشنایی دارید و خیلی راحت مثل آب خوردن المان مورد نظر رو با آیدی مشخص انتخاب می کردید و بعنوان یک سورس در متغیر مثلا Var ذخیره می کردید. ولی با دو قبلیت خوب و کاربردی querySelector و querySelectorAll میشه با الگو و شروط متنوع تری المان هارو انتخاب کرد و بهشون دسترسی داشت , مثلا با کمک className یا children و غیره

استفاده از querySelector در جاوااسکریپت

مثلا می خوایم یک تگ عنوان رو با اسم کلاس CSS انتخاب کنیم:

<div class="content">
    <h1 class="title">Content Title</h1>
</div>
<script type="text/javascript">
    var title = document.querySelector('.content .title');
    console.log(title);

خوب تو کد بالا یک تگ h1 داریم که کلاس title داره و تو کد جاوااسکریپت اومدیم اون رو با Selector انتخاب کردیم که گفتیم داخل یک المان content. یک المان با کلاس title. هستش که برامون h1 رو بر میگردونه.

نکته: در نظر داشته باشید که querySelector اولین المان که match میشه برامون بر می گردونه و اگر دو المان با همون اسم کلاس داشته باشید دومی رو براتون انتخاب نمی کنه !!!

خوب برای حل این مشکل چه کنیم ؟!

استفاده از querySelectorAll در جاوااسکریپت

در مثال قبل فهمیدیم که اگر چند المان با اون شرایط در selector باشن برامون فقط اولین المان رو بر می گردونه و تو بعضی از use case ها برامون اصلا کاربردی نداره. با کمک querySelectorAll میشه همه المان هارو دسترسی داشت. خوب حالا به مثال زیر توجه کنید:

<div class="content">
    <h1 class="title">First Title</h1>
    <h4 class="title">Second Title</h4>
</div>
<script type="text/javascript">
    var titles = document.querySelectorAll('.content .title');
    console.log(titles.length);

خوب حالا اگر کد بالا رو اجرا کنید خواهید دید که با اجرای اون log براتون عدد 2 بر می گرده و تمام المان هایی که کلاس title داشتن رو انتخاب کرده.

استفاده از addEventListener در جاوااسکریپت

اگر مثل قبل معنی کلمه رو توجه کنیم داره یک شنونده به اون المان اضافه می کنه که event هاش رو گوش بده و در زمان مشخص یک تابع خاص رو اجرا کنه. یعنی مثلا در زمان click, focus یا حتی blur و غیره ...

این متد در حال کلی چنین ساختار و ورودی هایی رو داره:

element.addEventListener('EventName', function(e) { ... });

مثلا در نظر داشته باشید که جای اون EventName میشه click, focus و ... رو نوشت و داره به این شرط گوش میده و به محض اجرای اون Event بر روی المان تابع بعدی رو اجرا می کنه. البته داخل تابع یک وروده e رو دادیم که البته این اسم دلبخواه هستش !!! با کمک این ورودی می تونیم به المانی که event روی اون صورت گرفته دسترسی داشته باشیم.

خوب حالا بیایم کدهای اول تا الان رو ادغام کنیم و یک کار جالب انجام بدیم. میخوام در زمان کلیک روی همون title هامون یک alert نمایش داده بشه و text اون تیتر رو نمایش بدیم:

<div class="content">
    <h1 class="title">First Title</h1>
    <h4 class="title">Second Title</h4>
</div>
<script type="text/javascript">
    var titles = document.querySelectorAll('.content .title');
    titles.forEach((item) => {
        item.addEventListener('click', (e) => {
            alert(e.currentTarget.innerText);
        });
    });

از اونجایی که titles یک آرایه هستش باید روی آیتم ها اون حلقه ای رو اجرا می کردم و از forEach استفاده کردم و به هر item که عناوین ما میشن یک listener اضافه کردم و قراره زمان click برامون مقدار innerText رو بصورت alert نمایش بده.

شاید براتون سوال پیش بیاد که چرا بجای target از currentTarget استفاده کردم ؟!

فرض کنید یک المان به شکل زیر دارید و قراره روش event کلیک رو اضافه کنید:

<div class="menu-links" data-target="dashboard">
    <i class="fa fa-user"></i>
    <span>Mohammad Esmaeilzadeh</span>
</div>

تو کد بالا یک div داریم که داخلش یک متن و یک icon داره. قراره با کلیک بر روی menu-links مقدار target رو بگیریم و صفحه رو مثلا redirect کنیم !!! ولی زمانیکه بخوایم به Attribute مورد نظر در data-target دسترسی داشته باشیم و از event.target استفاده کنیم اگر کاربر روی تگ های i یا span هم کلیک کنه اون Event اجرا میشه و مقدار data-target بصورت undefined بر میگرده و کد به خطا میخوره !!!

برای اینکه تو این Case فقط کلیک روی div رو کنترل کنیم باید از event.currentTarget استفاده کنیم که مقدار div برامون برگرده و child های اون این تابع رو نداشته باشند.

امیدوارم این مقاله کاربردی براتون مفید بوده باشه

تا آموزش های بعدی خدانگهدار