نكتهها و ترفندها براي برنامه نويسان جی کوئری (بخش اول)
در اين نوشته نگاهي به 15 تكنيك جی کوئری كه براي استفاده موثر شما از اين كتابخانه مفيد باشد، خواهيم داشت. با چند نكته در مورد كارايي شروع و با معرفي كوتاه چند ويژگي كمتر شناخته شده كتابخانه جی کوئری ادامه نوشته را پي ميگيريم. به دليل طولاني شدن مطلب آن را در دو قسمت آماده كردهام.
1- از آخرين نسخه جی کوئری استفاده كنيد
با همه نوآوريهاي اتفاق افتاده در پروژه جی کوئری يكي از سادهترين راهها براي بهبود عملكرد وب سايت شما اين است كه از آخرين نسخه جی کوئری استفاده نماييد. هر نسخه جديد از كتابخانه جی کوئری شامل بهينه سازيها و رفع باگهاست و بيشترين زماني كه شما درگير به روز رساني ميشويد تنها شامل تغيير كوچكي در تگ <script>
است.
شما حتي ميتوانيد به طور مستقيم از سرورهاي گوگل براي شماري از كتابخانههاي جاوا اسكريپت از جمله جی کوئری استفاده كنيد.
<!-- Include a specific version of jQuery --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> <!-- Include the latest version in the 1.7.1 branch --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/latest/jquery.min.js"></script>
تگ اسكريپت اول يك نسخه خاص از جی کوئری را مشخص ميكند و دومي آخرين نسخه جی کوئری را. در بعضي از مواقع دسترسي به google code يا بعضي از قسمتهاي ديگر گوگل براي ما ايرانيها مقدور نيست. در اين صورت براي آخرين نسخه جی کوئری ميتوانيد از لينك زير استفاده نماييد.
http://code.jquery.com/jquery-latest.min.js
2- انتخابگرها را ساده نگه دارید
قبلاً به دست آوردن (retrieve) عناصر DOM ، يك تركيب ظريف از تجزيه رشتههاي انتخابگر (selector)، حلقههاي جاوا اسكريپت و API های داخلی مانند getElementById()
, getElementsByTagName()
و getElementsByClassName()
بودند. اما حالا همه مرورگرهاي مهم از متد querySelectorAll()
پشتيباني ميكنند كه انتخابگرهاي CSS را ميفهمد كه اين نيز افزایش عملکرد قابل توجه را با خود به ارمغان آورده است.
با اين حال شما هنوز بايد سعي كنيد تا طريقه به دست آوردن (retrieve) عناصر را بهينه سازي كنيد. لازم به ذكر است كه شماري از كاربران هنوز از مرورگرهاي قديمي استفاده ميكنند كه جی کوئری را مجبور به پيمايش (traverse) درخت DOM ميكند كه اين كار كند است.
$('li[data-selected="true"] a') // Fancy, but slow $('li.selected a') // Better $('#elem') // Best
انتخاب كردن با id از همه سريعتر است. اگر نياز داريد تا بوسيله نام class انتخاب خود را انجام دهيد، قبل از آن يك تگ قرار دهيد $('li.selected')
. اين بهینه سازیها عمدتاً مرورگرهای قدیمیتر و دستگاههای تلفن همراه را تحت تاثیر قرار می دهد.
در اينجا براي نشان دادن اينكه انتخاب با id سريعتر از انتخاب با class است مثالي آورده ميشود.
// Create our list var myList = $('.myList'); var myListItems = '<ul>'; for (i = 0; i < 1000; i++) { myListItems += '<li class="listItem' + i + '">This is a list item</li>'; } myListItems += '</ul>'; myList.html(myListItems); var start = new Date().getTime(); // Select each item once for (i = 0; i < 1000; i++) { var selectedItem = $('.listItem' + i); } var end = new Date().getTime(); var time = end - start; alert('Execution time: ' + time);
در كد بالا يك ليست شامل 1000 <li>
كه هر كدام داراي خصيصه class ميباشند با يك حلقه for ايجاد نموديم. سپس در for بعدي با انتخابگر class آنها را مورد دستيابي قرار داديم. اجراي اين كد در مرورگر فايرفاكس 7 در سيستم من 460 ميلي ثانيه و در كروم 16، 900 ميلي ثانيه طول كشيد.
حال كد بالا را تغيير ميدهيم تا در هنگام ايجاد، شامل خصيصه id باشند سپس آنها را با انتخابگر id مورد دستيابي قرار ميدهيم.
// Create our list var myList = $('.myList'); var myListItems = '<ul>'; for (i = 0; i < 1000; i++) { myListItems += '<li id="listItem' + i + '">This is a list item</li>'; } myListItems += '</ul>'; myList.html(myListItems); var start = new Date().getTime(); // Select each item once for (i = 0; i < 1000; i++) { var selectedItem = $('#listItem' + i); } var end = new Date().getTime(); var time = end - start; alert('Execution time: ' + time);
اجراي كد دستكاري شده در مرورگر فايرفاكس 7 در سيستم من 31 ميلي ثانيه طول كشيد اما با كروم 16، 19 ميلي ثانيه. پس در فايرفاكس نزديك 15 برابر سريعتر از كد قبلي و در كروم چيزي حدود 47 برابر سريعتر بوده است. البته در هر بار اجرا و با توجه به نوع مرورگر ممكن اعداد متفاوتي به دست آيند. پس توصيه ميشود تا جايي كه امكان دارد از انتخابگر id استفاده نماييد.
چيز ديگري كه لازم به ذكر است اين است كه جی کوئری شمار زيادي از انتخابگرهاي اضافهتر را براي راحتي به شما ميدهد مثل :visible
و :hidden
و :animated
و … كه جزو انتخابگرهاي معتبر CSS3 نيستند. در نتيجه اگر شما آنها را به كار گيريد كتابخانه جی کوئری نميتواند متد querySelectorAll()
را مورد استفاده قرار دهد. براي اصلاح اين وضعيت شما ميتوانيد ابتدا عناصري كه ميخواهيد با آنها كار كنيد را انتخاب نماييد سپس آنها را فيلتر كنيد مانند مثال زير:
$('a.button:animated'); // Does not use querySelectorAll() $('a.button').filter(':animated'); // Uses it
نتيجه هر دو انتخاب بالا يكي است به استثناي اين كه مثال دوم سريعتر است.
3- كش كردن (cache) نتايج جی کوئری
دسترسي به DOM هميشه كندترين بخش هر برنامه جاوا اسكريپت خواهد بود. بنابراين به حداقل رساندن آن سودمند خواهد بود. يكي از راههاي انجام اين كار، كش كردن (cache) نتايجي است كه جی کوئری به شما ميدهد. متغيري كه شما انتخاب ميكنيد يك شي جی کوئری را در خود نگه ميدارد كه بعداً ميتوانيد آن را در اسكريپت تان مورد دستيابي قرار دهيد.
فرض كنيد بخواهيم به يك ليست 1000 عنصر را در يك حلقه اضافه كنيم. اين كار را ميتوانيم با تكه كد زير انجام دهيم.
for (i = 0; i < 1000; i++) { $('.myList').append('This is list item ' + i); }
نتايج اجراي اين كد روي سيستم من براي فايرفاكس 457 ميلي ثانيه، كروم 418 و IE7 1532 ميلي ثانيه بود. براي بهبود اين كد انتخاب .myList را كش ميكنيم بدين صورت كه نتيجه انتخاب $('.myList')
را در يك متغير ذخيره ميكنيم تا هر بار لازم نباشد دوباره عمل انتخاب را انجام دهيم.
var myList = $('.myList'); for (i = 0; i < 1000; i++) { myList.append('This is list item ' + i); }
زمان اجراي كد كش شده در فايرفاكس 185، در كروم 101 و در اينترنت اكسپلورر 984 ميلي ثانيه بود.
4- دستكاري كردن (manipulation) با DOM را به حداقل برسانيد
ما ميتوانيم كد قبل را با كم كردن زمانهايي كه از متدهاي DOM استفاده ميكنيم، باز هم سريعتر كنيم. عمليات درج به وسيله DOM همانند append()
، prepend()
، after()
يا wrap()
نسبتاً زمانبر هستند و ميتوانند اجراي كد را كند كنند.
براي كد قبل ميتوانيم ايجاد ليست را با الحاق رشتهها به هم انجام دهيم و سپس با استفاده از يك تابع مانند html()
براي اضافه كردن آنها به <ul>
كد را سريعتر نماييم.
var myList = $('.myList'); var myListItems = ''; for (i = 0; i < 1000; i++) { myListItems += '<li>This is list item ' + i + '</li>'; } myList.html(myListItems);
زمان اجراي اين كد در سيستم من براي فايرفاكس 8، كروم 28 و اينترنت اكسپلورر 31 ميلي ثانيه بود. دقت كنيد كه اين كد نسبت به كد اوليه براي فايرفاكس 57 برابر، براي كروم 15 برابر و براي اينترنت اكسپلورر 49 برابر سريعتر شده است.
5- اشياي جی کوئری به صورت آرايه
نتيجه اجراي يك انتخابگر يك شي جی کوئری است. با اين حال جی کوئری آن را طوري نشان ميدهد كه شما در حال كار با آرايه بوسيله تعريف عناصر شاخص (index) و طول (length) هستيد.
// Selecting all the navigation buttons: var buttons = $('#navigation a.button'); // We can loop though the collection: for(var i=0;i<buttons.length;i++){ console.log(buttons[i]); // A DOM element, not a jQuery object } // We can even slice it: var firstFour = buttons.slice(0,4);
اگر به دنبال كارايي هستيد استفاده از يك حلقه for
يا while
ساده به جاي $.each()
ميتواند كد شما چندين برار سريعتر نمايد.چك كردن طول (length) تنها راه براي تعيين اين است كه آيا مجموعه شما شامل هيچ عنصر ديگري هست يا خير.
if(buttons){ // This is always true // Do something } if(buttons.length){ // True only if buttons contains elements // Do something }
6- ويژگيِ selector
جی کوئری يك ويژگي (property) را فراهم كرده به نام selector كه شامل انتخابگري است كه براي شروع زنجيره مورد استفاده واقع شده است.
$('#container li:first-child').selector // #container li:first-child $('#container li').filter(':first-child').selector // #container li.filter(:first-child)
اگر چه مثالهاي بالا عنصر مشابهي را هدف گرفتهاند، انتخابگرها كاملاً متفاوت هستند. مثال دوم در واقع نامعتبر است شما نميتوانيد آن را به عنوان مبناي (basis) يك شي جديد جی کوئری به كار گيريد. اين مثال فقط نشان ميدهد كه متد filter براي محدود كردن مجموعه مورد استفاده قرار گرفته است.
7- به انتخابگرهاي خود يك زمينه (context) بدهيد
به طور پيش فرض زماني كه شما از انتخابگري مثل $('.myDiv')
استفاده ميكنيد تمام درخت DOM پيمايش (traverse) خواهد شد كه بسته به صفحه مورد نظر ميتواند پر هزينه و زمانبر باشد.تابع jQuery در هنگام انجام يك انتخاب ميتواند يك پارامتر دوم نيز بگيرد
jQuery( expression, context )
با فراهم كردن زمينه (context) براي انتخابگر، شما ميتوانيد يك عنصر را براي شروع جستجو در داخل آن به تابع بدهيد تا ديگر لازم نباشد تمام DOM را پيمايش كند.
ساختار HTML زير را در نظر بگيريد
<ul> <li>This is the first list item (‎ <code> <li></code>) in an unordered list (‎ <code> <ul></code>). </li> <li>This is the second list item. It has a <a rel="self" title="Learning jQuery blog" href="/archives/jquery-links.htm">link</a> in it.</li> <li class="myclass otherclass">This is the third list item. It has a ‎ <code> class</code> of "myclass otherclass"</li> <li>This is the fourth list item. It has <strong>strong</strong> text and <em>em</em>phasized <em>text</em>. <ul> <li>second-level list item 1</li> <li>second-level list item 2</li> <li> <ul class="myList"></ul> </li> </ul> </li> </ul>
در كد جاوا اسكريپت ابتدا 1000 عنصر <li>
را ايجاد ميكنيم و آنها را درون <ul class="myList"> </ul>
قرار ميدهيم. سپس از ميان آن 1000 تا فردها را انتخاب كرده و رنگ پس زمينه آنها را عوض ميكنيم.
var myList = $('.myList'); var myListItems = ''; for (i = 0; i < 1000; i++) { myListItems += '<li id="listItem' + i + '">This is list item ' + i + '</li>'; } myList.html(myListItems); var selectedItem = $('li li li:odd').css("background", "#CCCCFF");
مدت زمان اجرايي كه اينجا ذكر ميشود فقط براي خط آخر كد كه انتخاب را انجام ميدهد، است. اجراي خط آخر در مرورگر فايرفاكس 205 ميلي ثانيه در كروم 153 و در اينترنت اكسپلورر 641 ميلي ثانيه طول كشيد.
حالا خط آخر را به صورت زير تغيير ميدهيم
var selectedItem = $('li:odd', $('.myList')).css("background", "#CCCCFF");
اكنون زمان اجراي اين خط از كد براي فايرفاكس 61، كروم 43 و اينترنت اكسپلورر 93 ميلي ثانيه بود.
این مطلب توسط جناب آقای سوران خضری برای وب تارگت آماده شده است
محسن شهبازی
22 October 2012
بسیار خلاصه مفید و کارامد، ممنون بابت زحماتتون
سوران خضري
27 October 2012
خوشحالم كه براتون مفيد بوده
ميتونيد قسمت دوم اون رو هم در همين سايت بخونيد
مهدی مرجانی مقدم
12 March 2013
مطالب بسیار مفید بود . حتما توی سایتهای جدیدم ازین روش استفاده می کنم.
رجبی
17 August 2013
خوب بود
milad
22 August 2013
خیلی مفید بود ممنون
سوران خضري
24 August 2013
خواهش ميكنم ميلاد عزيز
رضا
3 September 2013
ممنون جالب بود
میثم
27 March 2014
ممنون
طراحی سایت
23 October 2014
با سلام. خسته نباشید عرض می کنم و کمال تشکر را از شما دارم
فاطمه
18 June 2017
واقعا عالی بود مشکلم حل شد
zarin
11 August 2017
واقعا مرسی کاش بتونم یاد بگیرم جی کوئری رو …
سام
12 August 2018
بسیار عالی
ممنونم از شما
علی
28 August 2018
عالی بود ممنون از لطفتون