اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
پنج دقیقه
Jquery یکی از کتابخانههای قدرتمند JavaScript است که به طور وسیعی مورد استفاده طراحان وب قرار میگیرد. این کتابخانه از سه دیدگاه بسیار سودمند است؛ ابتدا به دلیل مدیریت قدرتمند Dom که دارد و دوم اینکه ارتباط Ajax را بسیار راحت کرده است و هم اینکه بستر پلاگین نویسی را فراهم ساخته است، به طوری که میلیونها کتابخانه ثالث از روی همین کتابخانه ایجاد شده است. زمانیکه شما به مطالعه این کتابخانه رو آورید و نمونه کدهای مختلفی از آن را بر روی شبکه اینترنت ببینید، ممکن است این کتابخانه در عین سادگی که دارد، ابهاماتی را برای شما ایجاد کند که یکی از آنها نحوه استفاده از رویدادهاست. لیست زیر نمونهای از نحوه رویداد نویسی در جی کوئری است:
دو مورد اول در لیست، یکی هستند و در واقع مورد اول یک میانبر برای مورد دوم محسوب میشود و در پشت صحنه در واقع همان خط دوم مورد استفاده قرار میگیرد. از مزایایی که در مورد bind نسبت به استفاده مستقیم از اسم رویداد میتوان گفت این است که میتواند در یک زمان به چند رویداد متصل شود. به عنوان مثال کد زیر نمونهای از آن است:
در خط بالا المانهایی که با کلاس test مزین گشتهاند، به سه رویداد و یک تابع بایند یا متصل گشتهاند. برای غیرفعال سازی این رویدادها میتوان از متد unbind استفاده کرد:
برای استفاده از این دو حالت باید در نظر گرفت که تنها المانهایی به این رویداد متصل یا بایند میگردند که در زمان بررسی DOM، یعنی بارگذاری اولیه سایت وجود داشتهاند و در صورتیکه المان جدیدی به صفحه اضافه شود یا اینکه جایگزین المان دیگری شود، بایند نخواهند شد و تنها المانهای قدیمی کار خواهند کرد و در صورتیکه المانی از روی صفحه حذف شود، این اتصال از بین خواهد رفت.
مورد سوم، متد معروف live است که هم بر روی المانهای قدیمی و هم بر روی المانهای جدید جواب میدهد. ولی نکتهای که در مورد live وجود دارد این است که در نسخههای اخیر به دلیلی که در جلوتر عنوان میشود حذف شده است و دیگر وجود ندارد. دلیل این حذف هم این میباشد که در واقع متد live برای اینکه افزوده شدن المانهای جدید را زیر نظر بگیرد، به خود المان متصل نمیشود؛ بلکه به به کل سند HTML یا بدنه وب سایت متصل میشد و کل ناحیه را مورد بررسی قرار میداد تا اگر المان جدیدی اضافه شد، بتواند رویداد مرتبطی را بر روی آن اجرا کند. همچنین در این حالت رویدادیهایی از این نوع، در اجداد این المان نیز اجرا میگردند. یعنی رویداد، از المان آغاز شده، سپس به سمت اجدادش انتقال خواهد یافت (به این حالت Bubbling up گفته میشود). پس برای اینکه این ناحیه کوچکتر و جزئیتر شود، متد دیگری جایگزین آن شد؛ به نام delegate:
این حالت که جایگزین حالت قبلی شده است بدین صورت است که ناحیهای با آی دی area وجود دارد که المانهایی با کلاس test در آن قرار میگیرند. پس، از این به بعد، بجای اینکه کل سند بررسی شود، فقط همین بخش مورد بررسی قرار میگیرد و رویداد کلیک، بر روی المانی با کلاس test اجرا میشود و bubbling up کمتری خواهیم داشت و میتوان آن را کنترل کرد. برای حذف رویدادهای live از المانهای مربوطه، میتوان از die و برای delegate از undelegate همانند unbind استفاده کرد. همچنین حالت استفاده از زنجیرهای از متدها در متد live در نظر نگرفته شده، ولی بعد از دلیگیت میتوان از متدهای دیگر، به صورت زنجیرهای استفاده کرد.
از نسخه 1.7 به بعد توصیه شدهاست به جای تمامی متدهای بالا، از on استفاده شود که به مراتب کارآایی بهتری دارد و اکثر این متدهای بالا، حذف یا منسوخ شده اعلام گشتهاند و احتمال حذف آنها در نسخه آتی وجود دارد. به عنوان مثال delegate از نسخه 3 به بعد منسوخ اعلام شدهاست. نحوه صدا زدن on بجای دلیگیت به شکل زیر خواهد بود:
نکته مهم : بعضیها برای راحتی کار بدین شکل کار میکنند ولی این شیوه فرقی با متد live ندارد.
در حالت Bubbling up این گونه است که اگر کدی به شکل زیر باشد و رویداد کلیک روی text هدف ما باشد، رویداد کلیک به سمت اجداد آن حرکت میکند. یعنی ابتدا رویداد کلیک b اجرا میشود، سپس a و سپس رویداد کلیک div اجرا میشود و الی آخر:
برای حل این مسئله و جلوگیری از این اتفاق میتوان از متد stopPropagation استفاده کرد که در حالت استفاده از متد on جواب میدهد؛ ولی در متد live، استفاده از آن بی فایده است. کد زیر را میتوانید با حالتهای مختلف بررسی کرده و نتیجه این متد را در کنسول مرورگر خود ببینید:
نکته تکمیلی اینکه در استفاده از دلیگیت و on میتوان رویدادها را به شکل زیر هم مورد استفاده قرار داد:
$().click(fn) $().bind('click',fn) $().live('click',fn) $().delegate(selector, 'click', fn) $().on('click',fn); $().on('click', selector ,fn);
$(".test").bind( "click mouseover mouseout", function() { console.log('fired!') } );
$(".test").unbind( "click");
مورد سوم، متد معروف live است که هم بر روی المانهای قدیمی و هم بر روی المانهای جدید جواب میدهد. ولی نکتهای که در مورد live وجود دارد این است که در نسخههای اخیر به دلیلی که در جلوتر عنوان میشود حذف شده است و دیگر وجود ندارد. دلیل این حذف هم این میباشد که در واقع متد live برای اینکه افزوده شدن المانهای جدید را زیر نظر بگیرد، به خود المان متصل نمیشود؛ بلکه به به کل سند HTML یا بدنه وب سایت متصل میشد و کل ناحیه را مورد بررسی قرار میداد تا اگر المان جدیدی اضافه شد، بتواند رویداد مرتبطی را بر روی آن اجرا کند. همچنین در این حالت رویدادیهایی از این نوع، در اجداد این المان نیز اجرا میگردند. یعنی رویداد، از المان آغاز شده، سپس به سمت اجدادش انتقال خواهد یافت (به این حالت Bubbling up گفته میشود). پس برای اینکه این ناحیه کوچکتر و جزئیتر شود، متد دیگری جایگزین آن شد؛ به نام delegate:
$("#area").delegate('.test','click',function(e){...}); ---------------------------------------- <div id="area"> <span>Span1</span> <span>Span2</span> </div>
از نسخه 1.7 به بعد توصیه شدهاست به جای تمامی متدهای بالا، از on استفاده شود که به مراتب کارآایی بهتری دارد و اکثر این متدهای بالا، حذف یا منسوخ شده اعلام گشتهاند و احتمال حذف آنها در نسخه آتی وجود دارد. به عنوان مثال delegate از نسخه 3 به بعد منسوخ اعلام شدهاست. نحوه صدا زدن on بجای دلیگیت به شکل زیر خواهد بود:
$("#area").on('click','.test',function(e){...});
نکته مهم : بعضیها برای راحتی کار بدین شکل کار میکنند ولی این شیوه فرقی با متد live ندارد.
$("body").on('click','.test',function(e){...});
در حالت Bubbling up این گونه است که اگر کدی به شکل زیر باشد و رویداد کلیک روی text هدف ما باشد، رویداد کلیک به سمت اجداد آن حرکت میکند. یعنی ابتدا رویداد کلیک b اجرا میشود، سپس a و سپس رویداد کلیک div اجرا میشود و الی آخر:
<div> <a> <b>text</b> </a> </div>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script> <script src="http://code.jquery.com/jquery-migrate-1.4.1.js"></script> <script> $(document).ready(function(){ $(".myspan").on( "click",".test", function(e) { e.stopPropagation(); console.log('test fired!') } ); $(".myspan").on( "click", function() { console.log(' myspan fired!') } ); $(".mydiv").on( "click", function() { console.log(' mydiv fired!') } ); }); </script> </head> <body> <div class="mydiv"> <span class="myspan"> <button type="button" class="test">Ok</button> </span> </div> </body> </html>
نکته تکمیلی اینکه در استفاده از دلیگیت و on میتوان رویدادها را به شکل زیر هم مورد استفاده قرار داد:
$().on({ 'click': function (e) { // function }, 'hover': function (e) { // function } });