Предложения за решения в jQuery, които трябва да чуете Awesome

Колекция от кратки съвети, които ще ви дадат предимство в надпреварата с jQuery.

За още повече страхотни колекции, посетете избраните списъци awesome lists на [@sindresorhus](https://github.com/sindresorhus/).

Съдържание

Съвети

  1. Употребата на noConflict()
  2. Проверка за успешно зареждане на jQuery
  3. Проверка за наличност на даден елемент
  4. Използвайте .on() вместо .click()
  5. Бутон “обратно-към-началото”
  6. Предварително зареждане на изображения
  7. Проверка за успешно зареждане на изображения
  8. Автоматичен фикс на счупени изображения
  9. Изпращане на формуляр с AJAX
  10. Превключване на класове при Hover
  11. Деактивиране на поле за въвеждане
  12. Деактивиране зареждането на линкове
  13. Кеширане на jQuery-селектори
  14. Toggle-превключване на избледняването или приплъзгването
  15. Лесен “Акордеон”-ефект
  16. Изравняване височината на два div-елемента
  17. Отваряне на външни линкове в нов раздел или прозорец
  18. Намиране на елемент по текст
  19. Задействане на скрипт при промяна във видимостта
  20. Улавяне на грешка, върната от AJAX
  21. Верижно повикване на методи
  22. Сортиране на списък по азбучен ред
  23. Деактивиране на клик с десен бутон

Употребата на noConflict()

Символът $, полван от jQuery, се ползва също и от други JavaScript библиотеки. За да предотвратите конфликт с $-обектите на други библиотеки, добавете метод noConflict() в началото на документа:

jQuery.noConflict();

По този начин jQuery ще бъде рефенцирана под псевдоним jQuery вместо $ (например, jQuery('div p').hide()). Ако в един и същи документ имате няколко версии на jQuery (което не е препоръчително), може да ползвате noConflict(), за да зададете псевдоним за всяка от версиите:

let $x = jQuery.noConflict();

обратно към съдържанието

Проверка за успешно зареждане на jQuery

Преди да започнете да правите каквото и да е с jQuery, уверете се, че библиотеката е успешно заредена:

if (typeof jQuery == 'undefined') {
  console.log('jQuery hasn\'t loaded');
} else {
  console.log('jQuery has loaded');
}

Готови за излитане.

обратно към съдържанието

Проверка за наличност на даден елемент

Преди да започнете да манипулирате даден HTML елемент, е добре, да се уверите, че елементът вече е част от DOM-а.

if ($("#selector").length) {
  //тук направете нещо с елемента
}

обратно към съдържанието

Използвайте .on() вместо .click()

Функцията .on() има няколко предимства спрямо .click(), като например: …опция за добавяне на повече от едно събития (events)…

.on('click tap hover')

.on() обхваща не само вече съществуващите, но и динамично създаваните елементи, т.е. такива, които предстои да бъдат създадени чрез скрипта (няма нужда всеки елемент, динамично добавен към DOM-а, да бъде разглеждан като отделен случай)…

…както и възможността за определяне на пространство от имена (namespace):

.on('click.menuOpening')

Пространствата от имена (namespaces) дават възможност за отмяна на дадено събитие (например, .off('click.menuOpening')).

обратно към съдържанието

Бутон “обратно-към-началото”

Благодарение на методите animate и scrollTop в jQuery отпада необходимостта от имплементация на допълнителна функция за създаване на простичка анимация, която да превърта документа до горе.

// Връщане към началото
$('.container').on('click', '.back-to-top', function (e) {
  e.preventDefault();
  $('html, body').animate({scrollTop: 0}, 800);
});
<!-- Създайте таг "котва" -->
<div class="container">
  <a href="#" class="back-to-top">Back to top</a>
</div>

Променяйки стойността на scrollTop, вие оказвате позицията, на която лентата за превъртане (скролбарът) трябва да стопира. Това което се случва в горния пример, е че тялото (body) на документа бива анимирано, движейки се нагоре със скорост от 800 милисекунди, докато не се озове в самото начало на документа.

Внимание: Бъдете нащрек за бъгове със scrollTop.

обратно към съдържанието

Предварително зареждане на изображения

Ако уеб-страницата ви използва много изображения, някои от които не стават видими още в самото начало (а например само при поставяне на мишката отгоре - при т.нар. “hover”-ефект), тогава би било по-добре, да заредите изображенията предварително:

$.preloadImages = function () {
  for (var i = 0; i < arguments.length; i++) {
    $('<img>').attr('src', arguments[i]);
  }
};

$.preloadImages('img/hover-on.png', 'img/hover-off.png');

обратно към съдържанието

Проверка за успешно зареждане на изображения

Понякога, за да може скриптът да продължи да се изпълява по-нататък, се налага да се направи проверка за това, дали изображенията са вече напълно заредени:

$('img').on('load', function () {
  console.log('image load successful');
});

Ако заместите таг <img> с дадено ID или class, ще може да проверите зареждането за конкретно изображение.

обратно към съдържанието

Автоматичен фикс на счупени изображения

Ако се окаже, че сайтът ви съдържа счупени линкове към изображения, то поправянето на всеки един дефектен линк по отделно би било особено приятно занимание. В такъв случай следните няколко реда биха ви спестили доста главоболия:

$('img').on('error', function () {
  if(!$(this).hasClass('broken-image')) {
    $(this).prop('src', 'img/broken.png').addClass('broken-image');
  }
});

Като алтернатива на горния блок, ако предпочитате да скриете счупените изображения, следният код ще се погрижи за това:

$('img').on('error', function () {
  $(this).hide();
});

обратно към съдържанието

Изпращане на формуляр с AJAX

jQuery AJAX методите са често срещан подход за поискване на текст, HTML, XML, или JSON. Ако искате да изпратите формуляр чрез AJAX, може да съберете потребителските данни чрез метод val():

$.post('sign_up.php', {
  user_name: $('input[name=user_name]').val(),
  email:     $('input[name=email]').val(),
  password:  $('input[name=password]').val(),
});

Всички тези повиквания на val() обаче струват доста ресурси, а повикването на .val() върху <textarea>-елементи ще премахнат символите CR (Carriage Return). По-добър начин за събиране на потребителски данни предлага функцията serialize(), която събира данните като стринг:

$.post('sign_up', $('#sign-up-form').serialize());

обратно към съдържанието

Превключване на класове при Hover

Да предположим, че имате елемент, който може да бъде кликнат, и искате елементът да променя стила си, щом мишката попадне върху него (при т.нар. ефект “hover”):

$('.btn').on('hover', function () {
  $(this).addClass('hover');
}, function () {
  $(this).removeClass('hover');
});

Остава да добавите необходимия CSS. За още по-голямо улесняване, използвайте метод toggleClass:

$('.btn').on('hover', function () {
  $(this).toggleClass('hover');
});

Внимание: Макар и CSS да е по-бързият начин в този случай, струва си да се запознаете и с този вариант.

обратно към съдържанието

Деактивиране на поле за въвеждане

Може да се наложи submit-бутонът на даден формуляр, или пък някое от полетата за въвеждане на текст (input field) във формуляра, да останат деактивирани, докато потребителят не извърши определено действие (като например маркиране на отметката “Прочетох условията”). В такъв случай, добавете атрибута disabled (“деактивиран”) към съответното input-поле, за да може полето да се активира, едва когато трябва:

$('input[type="submit"]').prop('disabled', true);

Всичко, което трябва да направите, е да повикате метода prop върху input-полето още веднъж, само че този път задавайки на disabled стойността false:

$('input[type="submit"]').prop('disabled', false);

обратно към съдържанието

Деактивиране зареждането на линкове

Идеята при добавянето на линкове в страницата не винаги е, те да пренасочват към други страници или да презареждат текущата страница; вместо това, можете да използвате линковете с други цели, като например, да стартирате даден скрипт:

$('a.no-link').on('click', function (e) {
  e.preventDefault();
});

обратно към съдържанието

Кеширане на jQuery-селектори

Представете си, колко пъти общо може да се наложи да използвате един и същ селектор в даден проект. Селекторът $('.element') налага цялостно претърсване на DOM-а при всяко повикване, независимо, дали селекторът е бил задаван и преди. Вместо това, може да зададете селектора само веднъж, запазвайки резултатите в променлива:

var blocks = $('#blocks').find('li');

По този начин можете да ползвате променливата blocks винаги, щом поискате, бъз да се налага DOM-ът да бъде претърсван всеки път:

$('#hideBlocks').on('click', function () {
  blocks.fadeOut();
});

$('#showBlocks').on('click', function () {
  blocks.fadeIn();
});

Кеширането на jQuery-селектори допринася за по-добро и скоростно изпълнение на програмата.

обратно към съдържанието

Toggle-превключване на избледняването или приплъзгването

Slide (“плъзгане”) и fade (“избледняване”) се срещат често при анимирането с jQuery. Ако искате даден елемент да се появи, щом потребителят кликне върху нещо, спокойно може да използвате методите fadeIn(за появяване на елемента) и slideDown (“приплъзгване надолу”). Ако обаче искате елементът да се появи при клик и веднага след това да изчезне отново, следният код може да ви бъде от полза:

// Fade
$('.btn').on('click', function () {
  $('.element').fadeToggle('slow');
});

// Toggle
$('.btn').on('click', function () {
  $('.element').slideToggle('slow');
});

обратно към съдържанието

Лесен “Акордеон”-ефект

Това е простичък метод за бърз ефект-тип акордеон:

// Затваряне на всички панели
$('#accordion').find('.content').hide();

// Акордеон
$('#accordion').find('.accordion-header').on('click', function () {
  var next = $(this).next();
  next.slideToggle('fast');
  $('.content').not(next).slideUp('fast');
  return false;
});

Остава само да добавите необходимия HTML в уеб-страница си, за да може скриптът да има ефект.

обратно към съдържанието

Изравняване височината на два div-елемента

Ако искате два div-елемента да имат еднаква височина, независимо от тяхното съдържание:

$('.div').css('min-height', $('.main-div').height());

Този пример задава min-height(минималната височина), което означава, че реалната височина може да е по-голяма от тази на .main-div, но никога по-малка. По-гъвкавият вариант обаче е, да се обходи в цикъл група от елементи, и в height да се зададе височината на най-високия от елементите:

var $columns = $('.column');
var height = 0;
$columns.each(function () {
  if ($(this).height() > height) {
    height = $(this).height();
  }
});
$columns.height(height);

Ако искате всички колони да имат еднаква височина:

var $rows = $('.same-height-columns');
$rows.each(function () {
  $(this).find('.column').height($(this).height());
});

Внимание: Това може да бъде постигнато по няколко начина в CSS, но според ситуацията, е полезно да познавате и вариант за имплементация в jQuery.

обратно към съдържанието

Отваряне на външни линкове в нов раздел или прозорец

Отваряне на външни линкове в нов раздел на браузъра или в нов прозорец, така че ликовете от еднакъв източник (origin) да се отварят в същия раздел или прозорец:

$('a[href^="http"]').attr('target', '_blank');
$('a[href^="//"]').attr('target', '_blank');
$('a[href^="' + window.location.origin + '"]').attr('target', '_self');

Внимание: window.location.origin не проработва в IE10. Тази корекция отстранява проблема.

обратно към съдържанието

Намиране на елемент по текст

Селекторът contains() в jQuery позволява намирането на текст в съдържанието на даден елемент. В следния пример елементът ще бъде скрит, в случай че текстът не е намерен:

var search = $('#search').val();
$('div:not(:contains("' + search + '"))').hide();

обратно към съдържанието

Задействане на скрипт при промяна във видимостта

Задействане на JavaScript, щом раздел на браузъра остане извън фокус или при повторно фокусиране на раздела:

$(document).on('visibilitychange', function (e) {
  if (e.target.visibilityState === 'visible') {
    console.log('Tab is now in view!');
  } else if (e.target.visibilityState === 'hidden') {
    console.log('Tab is now hidden!');
  }
});

обратно към съдържанието

Улавяне на грешка, върната от AJAX

При връщане на грешка 404 или 500 от AJAX, се изпълнява функция, която улавя грешката. Ако не дефинирате тази функция, е възможно друг jQuery-код да не проработи по очаквания начин. За това може да дефинирате глобално функцията, улавяща грешката, по следния начин:

$(document).on('ajaxError', function (e, xhr, settings, error) {
  console.log(error);
});

обратно към съдържанието

Верижно повикване на методи

“Верижните” повиквания на методи в jQuery облекчават процеса на многократно претърсване на DOM-а и предотвратяват създаването на множество jQuery-обекти. Да предположим, че вашите методи са повикани по следния начин:

$('#elem').show();
$('#elem').html('bla');
$('#elem').otherStuff();

Така формулираният проблем може да бъде оптимиран значително чрез “верижни” повиквания:

$('#elem')
  .show()
  .html('bla')
  .otherStuff();

Друга алтернатива е кеширането на елемента в променлива (с префикс $):

var $elem = $('#elem');
$elem.hide();
$elem.html('bla');
$elem.otherStuff();

Както “верижните” повиквания, така и кеширането се считат за добри практики в jQuery, водещи до по-кратък и по-бързо изпълняем код.

обратно към съдържанието

Сортиране на списък по азбучен ред

Ако елементите от даден списък се окажат твърде много на брой, например в случай, че съдържанието е изготвено от Система за Управление на Съдържание (Content Management System / CMS), можете да подредите елементите по азбучен ред:

var ul = $('#list'),
lis = $('li', ul).get();

lis.sort(function (a, b) {
  return ($(a).text().toUpperCase() < $(b).text().toUpperCase()) ? -1 : 1;
});

ul.append(lis);

Готово.

обратно към съдържанието

Деактивиране на клик с десен бутон

Ако искате да деактивирате клик с десен бутон на мишката, може да го направите както за цялата страница…

$(document).ready(function () {
  $(document).bind('contextmenu', function (e) {
    return false;
  })
})

…така и за определен елемент:

$(document).ready(function () {
  $('#submit').bind('contextmenu', function (e) {
    return false;
  })
})

обратно към съдържанието

Поддръжка

Актуалните версии на Chrome, Firefox, Safari, Opera, Edge, и IE11.

обратно към съдържанието