Поради по jQuery

53

Програмування Asp.net
Попередній

Наступний

Тут наведено кілька дуже простих правил, дотримуючись яких, ваша співпраця з jQuery не буде затьмарене скреготом напрягшегося браузера. Звичайно, не так часто трапляється, що швидкість роботи javascript’а виявляється критичною, однак таке все ж може відбутися, статися в самий невідповідний момент. Тому, краще тримати ці правила в голові і не нехтувати ними.

1. Ефективний пошук елементів

Швидше за все відбувається пошук елементів за номером: $(‘#someId’), другим по швидкодії, є пошук по імені тега: $(‘tagName’). Висока швидкість їх виконання пов’язана з тим, що для їх реалізації використовуються внутрішні функції javascript: getElementById() і getElementsByTagName(). У зв’язку з цим, з’являються кілька правил.

(Для більшої наочності, вкажу текст сторінки, до якого буде застосовано JS-код з прикладів)

Обери колір

  • Червоний
  • Жовтий
  • Зелений


1. Якщо ви шукаєте один елемент, використовуйте пошук за номером:
$(‘#color_button’) – буде виконаний максимально швидко
$(‘#content .button’) – буде повільніше
$(‘.button:first’) – ще повільніше

2. Якщо ви шукаєте групу елементів, вказуйте найближчого спільного родича, що володіє ідентифікатором:
$(‘#content input’) буде ефективніше, ніж просто $(‘input’).

3. Якщо ви шукаєте елементи по класу, вказуйте ім’я тега:
$(‘input.button’) виконає пошук швидше, ніж $(‘.button’). У першому випадку, jQuery спочатку знайде всі елементи input, і вже серед них буде шукати елементи з класом button. А в другому випадку, для цього буде проведений перебір всіх елементів сторінки.

З усього сказаного можна вивести два основних правила:
1) Для пошуку одного елемента, використовуйте пошук по id: $(‘#someId’)
2) При пошуку групи елементів, намагайтеся дотримуватися наступної формули: $(‘#someId tagName.someClass’)

І ще, не намагайтеся покращити пошук по id з допомогою наступних комбінацій:
$(‘tagName#someId’)
$(‘#wrapId #someId’)
Це тільки уповільнить виконання пошуку.

2. Використовуйте результат пошуку елементів повторно

Не слід проводити пошук одних і тих же елементів знову і знову, це досить дорога процедура, навіть якщо ви використовуєте найшвидший селектор:

$(‘#myElement’).bind(‘click’, function(){…});
. . .
$(‘#myElement’).css(‘border’, ‘3px dashed yellow’);
. . .
$(‘#myElement’).fadeIn(‘slow’);

У цьому випадку, jQuery кожен раз буде здійснювати пошук елемента з ідентифікатором myElement. Набагато розумніше буде знайти елемент один раз, зберегти його, а потім застосовувати до нього необхідні операції:

var myElement = $(‘#myElement’);
. . .
myElement.bind(‘click’, function(){…});
. . .
myElement.css(‘border’, ‘3px dashed yellow’);
. . .
myElement.fadeIn(‘slow’);

Якщо протягом роботи вашого скрипта часто використовуються одні і ті ж елементи, то буде розумно знайти ці елементи тільки один раз і зберегти результат до глобальної змінної:

window.elements;
function init()
{
elements = $(‘#someId tagName.someClass’);
}

Правда, іноді, необхідно здійснювати маніпуляції з різними групами елементів, які, однак, є пов’язаними. Наприклад, це можуть бути елементи форми, з якими необхідно здійснювати багато маніпуляцій. В такому випадку, нам доведеться постійно шукати потрібні елементи:

$(‘#myForm input:checkbox’) // всі прапорці
$(‘#myForm input:text’) // усі текстові поля
$(‘#myForm input:text[value != “”]’) // всі непорожні текстові поля
. . .

Замість цього, можна знайти всі елементи форми один раз, і при необхідності діставати звідти необхідні:

var inputs = $(‘#myForm input’);
inputs.filter(‘:checkbox’) // знайдемо всі прапорці
inputs.filter(‘:text’) //знайдемо всі текстові поля
inputs.filter(‘:text[value != “”]’) // знайдемо всі непорожні текстові поля
. . .

Або, вам може знадобитися робити багато маніпуляцій з елементами списку, в тому числі видаляти і додавати їх. В такому випадку, «кешувати» елементи списку не буде гарною ідеєю, оскільки їх склад буде постійно змінюватися, а «кеш» опинятися неактуальним. Однак, можна зберегти об’єкт самого списку у глобальної змінної, що теж значно скоротить обчислювальні витрати:

myList = $(‘#myList’);
. . .
myList.find(‘li:first’).remove(); // знайдемо і видалимо перший елемент списку
myList.find(‘li.showed’).hide(); // приховаємо всі елементи списку з класом showed

3. Уникайте зайвих маніпуляцій c DOM

Основною ідеєю тут є те, що якщо ви хочете внести ряд змін на сторінці (додати/змінити елем), проробляйте ці маніпуляції локально і тільки після цього вносите зміни в DOM. Наприклад, якщо ви хочете додати в список сто нових елементів, то хибним буде робити це поелементно:

var top_100_list = […]; // вміст нових елементів
$mylist = $(‘#mylist’); // необхідний список

for (var i=0; i< top_100_list.length; i++)
$mylist.append(‘

  • ‘+ top_100_list[i] + ‘
  • ‘);

    набагато ефективніше буде вставити відразу всі елементи:

    var top_100_list = […]; // вміст нових елементів
    var li_items = “”; // вставити html-текст
    $mylist = $(‘#mylist’); // необхідний список

    for (var i=0; i< top_100_list.length; i++)
    li_items += ‘

  • ‘+ top_100_list[i] + ‘
  • ‘;
    $mylist.append(li_items);

    Ще більший виграш можна отримати, якщо група вставлених елементів виявиться «оберненої» одним елементом. Тому, якщо б у нас було завдання замінити вміст списку сотнею нових елементів, то самим оптимальним, був би такий варіант:

    var top_100_list = […]; // вміст нових елементів
    var new_ul = “

      “; // вставити html-текст
      $mylist = $(‘#mylist’); // необхідний список

      for (var i=0; i< top_100_list.length; i++)
      new_ul += ‘

    • ‘+ top_100_list[i] + ‘
    • ‘;
      new_ul += “

    “;
    $mylist.replaceWith(new_ul);

    Змінювати елементи локально, допоможе метод clone(), який створює копії елементів, разом з усім їхнім змістом. Зробивши всі необхідні зміни з копіями, можна вставити їх назад в DOM, замість старих версій (це можна зробити за допомогою методу replaceWith()).

    4. Використовуйте делегування подій

    Іноді, доводиться встановлювати однакові обробники подій на велику групу елементів. Наприклад, може знадобитися встановити обробники натискання мишею, елементів списку. У таких випадках, замість того, щоб встановлювати обробники на кожен елемент списку, можна встановити один обробник на сам список. Як відомо, стандартні події javascript, викликані на якому-небудь елементі, потім викликаються на всіх його предків (батьківському елементі, потім прародительском і. т. д). Тому, після того, як подія відбудеться на конкретному елементі списку, воно буде викликано на об’єкті самого списку. Зрозуміти, у кого саме сталася подія, допоможе передається в обробник об’єкт event, а точніше, його властивість event.target. Воно завжди містить DOM-об’єкт первинного джерела події:

    $(‘#myList’).click(function(event){
    $(event.target).addClass(‘clicked’); // додамо нажатому елементу клас clicked
    });

    5. Використовуйте ООП

    Одна з проблем розробки на джава скрипті, це те що все, як зазвичай пишуть в окремому набір якихось функцій у глобальному контексті і коли таких файлів стає декілька функції можуть перекрити один одного по випадковості. Вихід з даної ситуації це створювати об’єкт по імені файлу або ж іншим зрозумілим ім’ям. Ті файли (об’єкти), що багато разів перевикористовуються краще назвати якимись більш абстрактними речами (наприклад ARRAY_UTILS.js), файли в яких є індивідуальний для сторінки функціонал краще назвати по назві самої сторінки, тобто якщо у нас сторінки називається Report.aspx то логічно до неї створити js файл з об’єктом

    var REPORT_PAGE_CLASS = function() {
    var scope = this;

    this.someFunction = function() {


    }

    $(function() {

    scope.деяка функція();

    });
    };

    var REPORT_PAGE = new REPORT_PAGE_CLASS();

    Все що внутрик оголошується як через var недоступне поза, а все що через this.fg доступно як властивості чи функції

    І далі, якщо ми використовуємо в розмітці HTML вставки з коду, то будемо звертатися до об’єкта REPORT_PAGE.