1408

جزئیات وبلاگ

shape
shape
shape
shape
shape
shape
shape
1394/12/25 - مقالات

نکته‌ها و ترفندها برای برنامه نویسان جی کوئری (بخش اول)

در این نوشته نگاهی به ۱۵ تکنیک جی کوئری که برای استفاده موثر شما از این کتابخانه مفید باشد، خواهیم داشت. با چند نکته در مورد کارایی شروع و با معرفی کوتاه چند ویژگی کمتر شناخته شده کتابخانه جی کوئری ادامه نوشته را پی می‌گیریم. به دلیل طولانی شدن مطلب آن را در دو قسمت آماده کرده‌ام.

۱- از آخرین نسخه جی کوئری استفاده کنید

با همه نوآوری‌های اتفاق افتاده در پروژه جی کوئری یکی از ساده‌ترین راه‌ها برای بهبود عملکرد وب سایت شما این است که از آخرین نسخه جی کوئری استفاده نمایید. هر نسخه جدید از کتابخانه جی کوئری شامل بهینه سازی‌ها و رفع باگ‌هاست و بیشترین زمانی که شما درگیر به روز رسانی می‌شوید تنها شامل تغییر کوچکی در تگ ‎ 

تگ اسکریپت اول یک نسخه خاص از جی کوئری را مشخص می‌کند و دومی آخرین نسخه جی کوئری را. در بعضی از مواقع دسترسی به google code یا بعضی از قسمت‌های دیگر گوگل برای ما ایرانی‌ها مقدور نیست. در این صورت برای آخرین نسخه جی کوئری می‌توانید از لینک زیر استفاده نمایید.

1
http://code.jquery.com/jquery-latest.min.js

۲- انتخابگرها را ساده نگه دارید

قبلاً به دست آوردن (retrieve) عناصر DOM ، یک ترکیب ظریف از تجزیه رشته‌های انتخابگر (selector)، حلقه‌های جاوا اسکریپت و API های داخلی مانند ‎ getElementById() , ‎ getElementsByTagName() و ‎ getElementsByClassName() بودند. اما حالا همه مرورگرهای مهم از متد ‎ querySelectorAll() پشتیبانی می‌کنند که انتخابگرهای CSS را می‌فهمد که این نیز افزایش عملکرد قابل توجه را با خود به ارمغان آورده است.

با این حال شما هنوز باید سعی کنید تا طریقه به دست آوردن (retrieve) عناصر را بهینه سازی کنید. لازم به ذکر است که شماری از کاربران هنوز از مرورگرهای قدیمی استفاده می‌کنند که جی کوئری را مجبور به پیمایش (traverse) درخت DOM می‌کند که این کار کند است.

1
2
3
$('li[data-selected="true"] a') // Fancy, but slow
$('li.selected a')  // Better
$('#elem')  // Best

انتخاب کردن با id از همه سریع‌تر است. اگر نیاز دارید تا بوسیله نام class انتخاب خود را انجام دهید، قبل از آن یک تگ قرار دهید ‎ $('li.selected') . این بهینه سازی‌ها عمدتاً مرورگرهای قدیمی‌تر و دستگاه‌های تلفن همراه را تحت تاثیر قرار می دهد.
در اینجا برای نشان دادن اینکه انتخاب با id سریعتر از انتخاب با class است مثالی آورده می‌شود.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Create our list 
var myList = $('.myList'); 
var myListItems = '
    '; 
for (i = 0; i < 1000; i++) { 
    myListItems += '
  • This is a list item
'; 
myListItems += ''; 
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);

در کد بالا یک لیست شامل ۱۰۰۰ ‎ 

 که هر کدام دارای خصیصه class می‌باشند با یک حلقه for ایجاد نمودیم. سپس در for بعدی با انتخابگر class آنها را مورد دستیابی قرار دادیم. اجرای این کد در مرورگر فایرفاکس ۷ در سیستم من ۴۶۰ میلی ثانیه و در کروم ۱۶، ۹۰۰ میلی ثانیه طول کشید.

حال کد بالا را تغییر می‌دهیم تا در هنگام ایجاد، شامل خصیصه id باشند سپس آنها را با انتخابگر id‌ مورد دستیابی قرار می‌دهیم.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Create our list 
var myList = $('.myList'); 
var myListItems = '
    '; 
for (i = 0; i < 1000; i++) { 
    myListItems += '
  • This is a list item
'; 
}
myListItems += ''; 
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);

اجرای کد دستکاری شده در مرورگر فایرفاکس ۷ در سیستم من ۳۱ میلی ثانیه طول کشید اما با کروم ۱۶، ۱۹ میلی ثانیه. پس در فایرفاکس نزدیک ۱۵ برابر سریع‌تر از کد قبلی و در کروم چیزی حدود ۴۷ برابر سریع‌تر بوده است. البته در هر بار اجرا و با توجه به نوع مرورگر ممکن اعداد متفاوتی به دست آیند. پس توصیه می‌شود تا جایی که امکان دارد از انتخابگر id استفاده نمایید.

چیز دیگری که لازم به ذکر است این است که جی کوئری شمار زیادی از انتخابگرهای اضافه‌تر را برای راحتی به شما می‌دهد مثل ‎ :visible و ‎ :hidden و ‎ :animated و … که جزو انتخابگرهای معتبر CSS3 نیستند. در نتیجه اگر شما آنها را به کار گیرید کتابخانه جی کوئری نمی‌تواند متد‎ querySelectorAll() را مورد استفاده قرار دهد. برای اصلاح این وضعیت شما می‌توانید ابتدا عناصری که می‌خواهید با آنها کار کنید را انتخاب نمایید سپس آنها را فیلتر کنید مانند مثال زیر:

1
2
$('a.button:animated'); // Does not use querySelectorAll()
$('a.button').filter(':animated');  // Uses it

نتیجه هر دو انتخاب بالا یکی است به استثنای این که مثال دوم سریع‌تر است.

۳- کش کردن (cache) نتایج جی کوئری

دسترسی به DOM همیشه کندترین بخش هر برنامه جاوا اسکریپت خواهد بود. بنابراین به حداقل رساندن آن سودمند خواهد بود. یکی از راه‌های انجام این کار، کش کردن (cache) نتایجی است که جی کوئری به شما می‌دهد. متغیری که شما انتخاب می‌کنید یک شی جی کوئری را در خود نگه می‌دارد که بعداً می‌توانید آن را در اسکریپت تان مورد دستیابی قرار دهید.

فرض کنید بخواهیم به یک لیست ۱۰۰۰ عنصر را در یک حلقه اضافه کنیم. این کار را می‌توانیم با تکه کد زیر انجام دهیم.

1
2
3
for (i = 0; i < 1000; i++) { 
    $('.myList').append('This is list item ' + i); 
}

نتایج اجرای این کد روی سیستم من برای فایرفاکس ۴۵۷ میلی ثانیه، کروم ۴۱۸ و IE7 1532 میلی ثانیه بود. برای بهبود این کد انتخاب .myList را کش می‌کنیم بدین صورت که نتیجه انتخاب ‎ $('.myList') را در یک متغیر ذخیره می‌کنیم تا هر بار لازم نباشد دوباره عمل انتخاب را انجام دهیم.

1
2
3
4
var myList = $('.myList'); 
for (i = 0; i < 1000; i++) { 
    myList.append('This is list item ' + i); 

زمان اجرای کد کش شده در فایرفاکس ۱۸۵، در کروم ۱۰۱ و در اینترنت اکسپلورر ۹۸۴ میلی ثانیه بود.

۴- دستکاری کردن (manipulation) با DOM را به حداقل برسانید

ما می‌توانیم کد قبل را با کم کردن زمان‌هایی که از متدهای DOM استفاده می‌کنیم، باز هم سریع‌تر کنیم. عملیات درج به وسیله DOM همانند ‎ append()، ‎ prepend()، ‎ after() یا ‎ wrap() نسبتاً زمان‌بر هستند و می‌توانند اجرای کد را کند کنند.

برای کد قبل می‌توانیم ایجاد لیست را با الحاق رشته‌ها به هم انجام دهیم و سپس با استفاده از یک تابع مانند ‎ html() برای اضافه کردن آنها به ‎ 

 کد را سریع‌تر نماییم.

1
2
3
4
5
6
var myList = $('.myList'); 
var myListItems = ''; 
for (i = 0; i < 1000; i++) { 
    myListItems += '
  • This is list item ' + i + '
'; 
myList.html(myListItems);

زمان اجرای این کد در سیستم من برای فایرفاکس ۸، کروم ۲۸ و اینترنت اکسپلورر ۳۱ میلی ثانیه بود. دقت کنید که این کد نسبت به کد اولیه برای فایرفاکس ۵۷ برابر، برای کروم ۱۵ برابر و برای اینترنت اکسپلورر ۴۹ برابر سریع‌تر شده است.

۵- اشیای جی کوئری به صورت آرایه

نتیجه اجرای یک انتخابگر یک شی جی کوئری است. با این حال جی کوئری آن را طوری نشان می‌دهد که شما در حال کار با آرایه بوسیله تعریف عناصر شاخص (index) و طول (length) هستید.

1
2
3
4
5
6
7
8
9
// 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) تنها راه برای تعیین این است که آیا مجموعه شما شامل هیچ عنصر دیگری هست یا خیر.

1
2
3
4
5
6
7
8
if(buttons){  // This is always true
 
  // Do something
}
 
if(buttons.length){ // True only if buttons contains elements
  // Do something
}

۶- ویژگیِ selector

جی کوئری یک ویژگی (property) را فراهم کرده به نام selector که شامل انتخابگری است که برای شروع زنجیره مورد استفاده واقع شده است.

1
2
$('#container li:first-child').selector    // #container li:first-child
$('#container li').filter(':first-child').selector    // #container li.filter(:first-child)

اگر چه مثال‌های بالا عنصر مشابهی را هدف گرفته‌اند، انتخابگرها کاملاً متفاوت هستند. مثال دوم در واقع نامعتبر است شما نمی‌توانید آن را به عنوان مبنای (basis) یک شی جدید جی کوئری به کار گیرید. این مثال فقط نشان می‌دهد که متد filter برای محدود کردن مجموعه مورد استفاده قرار گرفته است.

۷- به انتخابگرهای خود یک زمینه (context) بدهید

به طور پیش فرض زمانی که شما از انتخابگری مثل ‎ $('.myDiv') استفاده می‌کنید تمام درخت DOM پیمایش (traverse) خواهد شد که بسته به صفحه مورد نظر می‌تواند پر هزینه و زمان‌بر باشد.تابع jQuery در هنگام انجام یک انتخاب می‌تواند یک پارامتر دوم نیز بگیرد

1
jQuery( expression, context )

با فراهم کردن زمینه (context) برای انتخابگر، شما می‌توانید یک عنصر را برای شروع جستجو در داخل آن به تابع بدهید تا دیگر لازم نباشد تمام DOM را پیمایش کند.

ساختار HTML زیر را در نظر بگیرید

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    
       
  • This is the first list item (‎   <li>) in an unordered list (‎   <ul>).
       
  • This is the second list item. It has a link in it.
       
  • This is the third list item. It has a ‎   class of "myclass otherclass"
       
  • This is the fourth list item. It has strong text and emphasized text.
         
           
  • second-level list item 1
           
  • second-level list item 2
           
               
           
         
       

در کد جاوا اسکریپت ابتدا ۱۰۰۰ عنصر ‎ 

 را ایجاد میکنیم و آنها را درون ‎ 

 قرار می‌دهیم. سپس از میان آن ۱۰۰۰ تا فردها را انتخاب کرده و رنگ پس زمینه آنها را عوض می‌کنیم.

1
2
3
4
5
6
7
var myList = $('.myList');
var myListItems = '';
for (i = 0; i < 1000; i++) {
    myListItems += '
  • This is list item ' + i + '
';
}
myList.html(myListItems);
var selectedItem = $('li li li:odd').css("background", "#CCCCFF");

مدت زمان اجرایی که اینجا ذکر می‌شود فقط برای خط آخر کد که انتخاب را انجام می‌دهد، است. اجرای خط آخر در مرورگر فایرفاکس ۲۰۵ میلی ثانیه در کروم ۱۵۳ و در اینترنت اکسپلورر ۶۴۱ میلی ثانیه طول کشید.

حالا خط آخر را به صورت زیر تغییر می‌دهیم

1
var selectedItem = $('li:odd', $('.myList')).css("background", "#CCCCFF");

اکنون زمان اجرای این خط از کد برای فایرفاکس ۶۱، کروم ۴۳ و اینترنت اکسپلورر ۹۳ میلی ثانیه بود.

نکته‌ها و ترفندها برای برنامه نویسان جی کوئری (بخش اول)