Создание собственных jQuery-селекторов

в категориях:
Версия для печатиВерсия для печати

Из всех JavaScript-библиотек, jQuery вероятно имеет синтаксис селекторов, наиболее близкий к спецификации CSS. Это делает её простой для изучения верстальщиками и веб-дизайнерам, разбирающихся в CSS, хотя в jQuery существует целых 52 селектора. Если вам нравятся CSS-селекторы :first-child, :hover или :only-child, то в арсенале jQuery вы сможете воспользоваться 34 подобными селекторами псевдоклассов.

Если вам будет недостаточно стандартных селекторов jQuery — таких как :animated, :even, :not() или :visible — то существует множество других селекторов, созданных сообществом разработчиков jQuery, которые вы можете смело использовать (например, :exactIgnoreCase(), :nothidden или :loaded()).

А все это значит, что вам нет нужды беспокоиться об изучении того, как создавать собственные селекторы — ведь так? А вот и нет!

Чем проще задача, тем больше шанс того, что она будет выполнена без ошибок. Попробуем выполнить следующий код:

if ($(el).offset().top > $(window).scrollTop() - $(el).outerHeight(true) && $(el).offset().top < $(window).scrollTop() + $(el).outerHeight(true) + $(window).height())
{
  // выполнить что-нибудь
}

А теперь взглянем на этот код:

if ($(el).is(":inview")) {
  // выполнить что-нибудь
}

Нетрудно догадаться, что оба куска кода выполняют одни и те же действия, и второй из них более понятный и короткий. И в первом, и во втором случае проверяется, находится ли элемент в области видимости в окне браузера.

Если вы понимаете, что условие получается слишком длинное и запутанное, и оно повторяется в коде скрипта не один раз, вы можете упростить скрипт, сделать его более понятным и удобным для доработки, создав собственный селектор. А сделать это очень легко:

jQuery.extend(jQuery.expr[':'], { // $.extend($.expr[':'], если покороче
  expression: function () {
    // функция должна возвращать булевское значение
    return false;
  }
});

В этом примере expression — это название вашего нового селектора… он может называться, например, inview, loaded или nothidden. В функции нужно отобрать элементы, которые должны быть отфильтрованы вашим селектором.

Теперь посмотрим на функционал функции фильтрации нашего селектора inview:

jQuery.extend(jQuery.expr[':'], {
  inview: function (el) {
    if ($(el).offset().top > $(window).scrollTop() - $(el).outerHeight(true) && $(el).offset().top < $(window).scrollTop() + $(el).outerHeight(true) + $(window).height()) {
      return true;
    }
    return false;
  }
});

Условие не самое оптимальное, но оно выполняет возложенную на него задачу. Код по созданию селекторов нужно добавить перед их использованием — можно вынести этот код в отдельный файл и оформить в виде плагина. Использовать созданный селектор можно любым доступным способом:

$("p:inview").css("color","orange");

или

$("p").filter(":inview").each(function(){
  // выполнить что-нибудь
});

или

if ($("p#desc").is(":inview")) {
  // выполнить что-нибудь
}  

Теперь попробуем немного оптимизировать созданный селектор. В созданном условии некоторые объекты вызываются несколько раз. Поэтому после их однократного использования нужно записать результат в переменную, и затем использовать только эту переменную. Теперь код выглядит следующим образом:

jQuery.extend(jQuery.expr[':'], {
  inview: function (el) {
    var $e = $(el),
    $w = $(window),
    top = $e.offset().top,
    height = $e.outerHeight(true),
    windowTop = $w.scrollTop(),
    windowScroll = windowTop - height,
    windowHeight = windowTop + height + $w.height();
    return (top > windowScroll && top < windowHeight);
  }
});

Мы создали свой собственный jQuery-селектор, который отбирает все элементы, видимые в окне браузера. Кроме того наш код оптимизирован и понятен.

Селектор "in view" уже достаточно давно был создан и используется многими разработчиками jQuery. Но только что созданный нами селектор кроме всего прочего учитывает и высоту элемента, так что селектор отберет и элементы, которые только частично видимы в окне браузера.

Статья основана на публикации "Make Your Own Custom jQuery Selector".

 

Ваша оценка: Нет Средняя: 9.5 (13 голосов)