jQuery имеет множество встроенных селекторов для выборки элементов по id, классу, тегу, атрибуту. Если данного списка селекторов jQuery вам недостаточно , вы можете создать собственные селекторы.
Теория
Шаблон для собственного селектора jQuery
1 2 3 4 5 6 7 8 9 10 | $.expr[':'].test = function(obj, index, meta, stack){ // obj - текущий элемент DOM // index - текущий индекс при обходе массива элементов // meta - метаданные селектора // stack - массив всех просматриваемых элементов // Return true если элемент соответствует селектору // Return false если элемент не соответствует селектору }; // Использование: $('.someClasses:test').doSomething(); |
Если вы хотите использовать параметр при вызове селектора (например :contains(некий_текст) ), то в селекторе вам необходимо смотреть значение параметра meta.
meta - это массив из четырех элементов:
[полное написание селектора, имя селектора, тип используемых в параметре кавычек, значение параметра].
Обратившись к meta[3] вы получите список переданных параметров, пример:
#1
1 2 3 4 5 6 7 8 | $('a:test'); //meta будет содержать следующие данные: [ ':test(argument)', // полный селектор 'test', // имя селектора undefined, // тип кавычек undefined // параметр ] |
#2
1 2 3 4 5 6 7 8 | $('a:test(argument)'); //meta будет содержать следующие данные: [ ':test(argument)', // полный селектор 'test', // имя селектора '', // кавычки не используются (пустая строка) 'argument' // параметр ] |
#3
1 2 3 4 5 6 7 8 | $('a:test("arg1, arg2")'); //meta будет содержать следующие данные: [ ':test('arg1, arg2')', // полный селектор 'test', // имя селектора '"', // используемые в параметре кавычки 'arg1, arg2' // параметр ] |
Примеры
Эти примеры, в основном, только для демонстрации возможностей собственных селекторов. Примеры полезных селекторов ниже.
:inline jQuery селектор
Возвращает все элементы с display:inline.
1 2 3 4 5 6 7 | $.extend($.expr[':'],{ inline: function(a) { return $(a).css('display') === 'inline'; } }); $(':inline'); // Выбирает все inline элементы $('a:inline'); // Выбирает все inline ссылки |
:red jQuery селектор
Проверяет цвет элемента.
1 2 3 4 5 6 7 | $.extend($.expr[':'],{ red: function(a) { return $(a).css('color') === 'red'; } }); // Вызов: $('p:red'); // Выбирает красные параграфы |
:childOfDiv jQuery селектор
Выбирает элементы, родитель у которых div.
1 2 3 4 5 6 7 8 | $.extend($.expr[':'],{ childOfDiv: function(a) { return $(a).parents('div').size(); } }); // Это только демонстрация. В скриптах следует использовать селектор $('div p') // вызов: $('p:childOfDiv'); // Выбирает параграфы, у которых родительский элемент DIV |
:biggerThan() jQuery селектор
Выбирает элементы больше чем указанные (сравнивает площадь).
1 2 3 4 5 6 7 8 | $.extend($.expr[':'],{ biggerThan: function(a,i,m) { if(!m[3]) {return false;} return $(a).width() * $(a).height() > $(m[3]).width() * $(m[3]).height(); } }); // вызов: $('div:biggerThan(div#banner))'); // Все DIVs размер которых больше чем у #banner |
:external jQuery селектор
Выбирает внешние ссылки.
1 2 3 4 5 6 7 8 9 | // (Только для ссылок с заданным атрибутом href): $.extend($.expr[':'],{ external: function(a,i,m) { if(!a.href) {return false;} return a.hostname && a.hostname !== window.location.hostname; } }); // вызов: $('a:external'); // Выбирает все внешние ссылки |
Примеры полезных селекторов
:width() jQuery селектор
Сравнивает ширину (больше/меньше).
1 2 3 4 5 6 7 8 9 10 | .extend($.expr[':'],{ width: function(a,i,m) { if(!m[3]||!(/^(<|>)\d+$/).test(m[3])) {return false;} return m[3].substr(0,1) === '>' ? $(a).width() > m[3].substr(1) : $(a).width() < m[3].substr(1); } }); // вызов: $('div:width(>200)'); // Все DIVs с шириной более 200px $('div:width(>200):width(<300)'); // Все DIVs с шириной в интервале от 200 до 300 px |
:inview jQuery селектор
Выбирает элементы, которые сейчас видны на экране.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $.extend($.expr[':'],{ inView: function(a) { var st = (document.documentElement.scrollTop || document.body.scrollTop), ot = $(a).offset().top, wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height(); return ot > st && ($(a).height() + ot) < (st + wh); } }); // Вызов: $('div:inView'); // Все DIV которые сейчас видны // Альтернативный вызов: if ( $('div#footer').is(':inView') ) { // Do stuff... } |
:loaded jQuery селектор
Возвращает список загруженных изображений.
1 2 3 4 5 6 7 8 9 10 11 12 | // Флаг завершения загрузки: $('img').load(function(){ $(this).data('loaded',true); }); // Расширяем список селекторов: $.extend($.expr[':'],{ loaded: function(a) { return $(a).data('loaded'); } }); // пример использования: alert( 'Images loaded so far: ' + $('img:loaded').size() ); |
:data jQuery селектор
Выбирает элементы, по хранимым данным .data()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // Обертка из анонимной функции: (function($){ // расширяем jQuery ':' $.extend($.expr[':'],{ // Новый метод "data" data: function(a,i,m) { var e = $(a).get(0), keyVal; // m[3] ссылается на значения внутри скобок вызываемого селектора // (передаваемые параметр) например :data(___) if(!m[3]) { // Цикл по свойствам объекта, находим ссылки на jquery: for (var x in e) { if((/jQuery\d+/).test(x)) { return true; } } } else { // создаем массив (name,value): keyVal = m[3].split('='); // если value задано: if (keyVal[1]) { // Test for regex syntax and test against it: if((/^\/.+\/([mig]+)?$/).test(keyVal[1])) { return (new RegExp( keyVal[1].substr(1,keyVal[1].lastIndexOf('/')-1), keyVal[1].substr(keyVal[1].lastIndexOf('/')+1)) ).test($(a).data(keyVal[0])); } else { // Test key against value: return $(a).data(keyVal[0]) == keyVal[1]; } } else { // Проверяем имеет ли элемент свойство data: if($(a).data(keyVal[0])) { return true; } else { // If it doesn't remove data (this is to account for what seems // to be a bug in jQuery): $(a).removeData(keyVal[0]); return false; } } } return false; } }); })(jQuery); |
Пример использования:
1. наличие данных
1 2 3 4 5 6 7 | // новый элемент: $('<img/>') .data('dom', true) // флаг .appendTo('body'); // добавляем в DOM $(':data(dom)'); // Все элементы у которых задан 'dom' флаг $('div:data(dom)'); // Все DIV с флагом 'dom' $(':not(:data(dom))'); // Все элементы БЕЗ флага 'dom' |
2. данные и значения
1 | $(':data(ABC=123)'); // Все элементы у которых ключ 'ABC' имеет значение 123 |
3. регулярные выражения
1 2 3 4 5 6 7 8 | // Предположим, у нас заданы разные данные для ряда элементов: $('div').each(function(i){ $(this).data('divInfo','index:' + i); // В результате имеем данные типа 'index:0', 'index:1', 'index:2' ... }); // Мы можем выбрать все эти DIV так: $('div:data(divInfo=/index:\\d+/)'); // Не забывайте экранировать слеши |
4. выбрать все элементы которые используют/не используют .data()
1 2 | $(':data'); // Все элементы использующие данные $(':not(:data)'); // Все элементы не использующие данные |
Другой селектор на основе .data()
:regex() jQuery селектор
Позволяет использовать регулярные выражения при поиске по атрибутам, css-стилям и данным .data()
1 2 3 4 5 6 7 8 9 10 11 | jQuery.expr[':'].regex = function(elem, index, match) { var matchParams = match[3].split(','), validLabels = /^(data|css):/, attr = { method: matchParams[0].match(validLabels) ? matchParams[0].split(':')[0] : 'attr', property: matchParams.shift().replace(validLabels,'') }, regexFlags = 'ig', regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g,''), regexFlags); return regex.test(jQuery(elem)[attr.method](attr.property)); } |
Примеры:
#1
1 2 3 4 5 6 | // Выбрать все элементы, ID которых начинается с гласной: $(':regex(id,^[aeiou])'); // Выбрать все DIV атрибут class которых содержит цифры: $('div:regex(class,[0-9])'); // выбрать все теги SCRIPT, SRC которых содержат jQuery: $('script:regex(src,jQuery)'); |
#2
1 2 3 4 | // Выбрать все элементы, ширина которых в диапазоне от 100 до 300px: $(':regex(css:width, ^[1-3]\\d{2}px$)'); // Выбрать все DIV, отображаемые не как блочные элементы: $('div:not(:regex(css:display, ^block$))'); |
#3
1 2 3 4 5 6 | // добавляем data для всех картинок (просто пример); $('img').each(function(){ $(this).data('extension', $(this)[0].src.match(/\.(.{1,4})$/)[1]); }); // Выбираем все картинки формата PNG и JPG: $('img:regex(data:extension, png|jpg)'); |
В статье использованы материалы следующих сайтов
Ноябрь 14th, 2010
Спасибо – насчёт data реально круто!
[Ответить]