В сегодняшней статье, мы закончим изучение селекторов JQuery, как и в прошлой статье, рассмотрев пару интересных примеров их использования. Прочитав статью, вы научитесь применять селекторы, для стилизации ячеек, строк или заголовков таблиц, а также искать и находить элементы по заданному значению.
Специальные селекторы
К большому разнообразию CSS и XPath селекторов, JQuery добавляет еще и свои собственные селекторы. Большинство этих селекторов позволяет выбирать элементы, как говорится, из расположения. Синтаксис этих селекторов подобен синтаксису CSS-псевдо классов, когда селектор начинается с двоеточия (:)
Например, если нам нужно выбрать элементы второго уровня , из соответствующего набора div-ов с примененным к ним стилем horizontal, мы должны написать следующее:
($('div.horizontal:eq(1)'))
Заметим, что eq(1) получает элемент второго уровня из набора, потому что Java-Script массив нумеруется с нуля, то есть первый элемент 0, второй 1 и т.д. Для контраста, CSS нумеруется с единицы, поэтому CSS-селектор подобный этому $(‘div:nth-child(1)’), получит первый div-элемент, являющей дочерним от своего родителя.
Стилизация чередующихся строк
Два наиболее полезных из специальных селекторов библиотеки JQuery — это :odd и :even. Давайте посмотрим, как можно использовать эти селекторы для раскрашивания таблицы в полоску, возьмем следующую таблицу:
<table> <tr> <td>As You Like It</td> <td>Comedy</td> <td></td> </tr> <tr> <td>All's Well that Ends Well</td> <td>Comedy</td> <td>1601</td> </tr> <tr> <td>Hamlet</td> <td>Tragedy</td> <td>1604</td> </tr> <tr> <td>Macbeth</td> <td>Tragedy</td> <td>1606</td> </tr> <tr> <td>Romeo and Juliet</td> <td>Tragedy</td> <td>1595</td> </tr> <tr> <td>Henry IV, Part I</td> <td>History</td> <td>1596</td> </tr> <tr> <td>Henry V</td> <td>History</td> <td>1599</td> </tr> </table>
Теперь добавим два класса в css файл, один для нечетных строк, и один четных:
.odd { background-color: #ffc; /* желтый цвет для нечетных ячеек */ } .even { background-color: #cef; /* синий цвет для четных ячеек */ }
И наконец напишем JQuery-код, добавляющий классы к ячейкам таблицы (тег <tr>):
$(document).ready(function() { $('tr:odd').addClass('odd'); $('tr:even').addClass('even'); });
Вот этот небольшой фрагмент кода, может представить таблицу следующим образом:
На первый взгляд, может показаться что строки раскрашены наоборот. Однако, также как и селектор :eq(), селекторы :odd() и :even(), используют JavaScript нумерацию, начинающуюся с нуля. Следовательно, первая строчка 0 (четная), вторая 1 (нечетная) и т.д.
Стоит отметить, что мы можем увидеть неожиданные результаты, если таблиц на странице несколько. Например, если фоновый цвет последней строчки нашей таблицы является, синим, то первая строка следующей таблицы будет выкрашена в желтый цвет. Как обойти эту проблему будет рассказано позже, а пока просто следует запомнить.
Для того чтобы узнать как действует последний специальный селектор, давайте представим что нам нужно выделить в таблице строчку, содержащую только пьесы Генри. Для начала как обычно добавляем класс в CSS-файл, содержащий полужирное начертание и красный цвет шрифта:
.table-heading{ background: lime; }
И добавляем одну строчку, к уже написанному нами коду JQuery, использующую селектор :contains():
$(document).ready(function() { $('tr:odd').addClass('odd'); $('tr:even').addClass('even'); $('td:contains("Henry")').addClass('highlight'); });
Итак, мы видим нашу прекрасную полосатую таблицу, с ярко выделенными пьесами Генри.
Следует признать, что расцвечивание элементов на странице, можно проводить и без JQuery, или любого другого программирования на клиенте. Но, несмотря на это, JQuery вместе с CSS, это отличная альтернатива, для стилизации динамического контента страницы.
Методы доступа к DOM
JQuery селекторы, изученные нами, позволяли получать наборы элементов, так как мы перемещались вниз по дереву DOM, и фильтровали полученные результаты. Если бы это был единственный метод доступа к данным, наши возможности были бы весьма ограничены.
Существует множество случаев, когда получения родителя или предка элемента, имеет важное значение. И в этом случае может сыграть методы доступа к DOM. С этими методами мы сможем с легкостью двигаться вверх, вниз и даже кругом, по дереву элементов.
Некоторые из этих методов, весьма похожи на селекторные выражения, вот например строку, в который мы раскрашивали нечетные строки таблицы $(‘tr:odd’).addClass(‘odd’), легко можно переписать с использованием метода .filter(), следующим образом:
$('tr').filter(':odd').addClass('odd');
Хотя по большей части, эти два метода получения элементов дополняют друг друга. Давайте снова взглянем на нашу полосатую таблицу и увидим, что именно возможно получить с этими методами.
Ну, во-первых, таблица вполне может иметь строку заголовка, поэтому давайте дополним ее еще одной строкой tr, в которую внесем два элемента th, вместо тегов td:
<tr> <th>Title</th> <th>Category</th> </tr>
Ну что ж, давайте, стилизуем заголовок таблицы, назначив ему зеленый фоновый цвет, вместо положенного светло-синего цвета. Также представим, что пользователь хочет видеть красный полужирный цвет, только в названиях категорий представленных пьес.
Стилизация заголовка таблицы
Задача стилизации заголовка таблицы может быть выполнена следующим способом. Мы можем найти все элементы th, получить их родительский контейнер tr, и раскрасить его. Затем с помощью комбинации CSS, XPath и специальных селекторов JQuery, оставшиеся элементы, можно выбрать действием от обратного, то есть мы выберем все элементы tr, не содержащие в себе дочерних элементов th, и назначим им нужный стиль.
В результате получится следующее:
$(document).ready(function() { $('th').parent().addClass('table-heading'); $('tr:not([th]):even').addClass('even'); $('tr:not([th]):odd').addClass('odd'); $('td:contains("Henry")').addClass('highlight'); });
Здесь для получения родителя тега th, мы используем метод parent(), потому что точно знаем, что у нас есть только одна строка tr, содержащая в себе элементы th.
С остальными строками все еще проще, сначала мы выбрали все элементы tr, не содержащие в себе элементов th, а затем применили к ним фильтр :odd() и :even(). Заметьте, что порядок расположения селекторов очень важен, наша таблица выглядела бы совсем по-другому если бы мы написали $(‘tr:odd:not([th])’), вместо положенного $(‘tr:not([th]):odd’).
Стилизация ячейки по категории
Со стилизацией наименования пьес, еще проще, главное правильно поставить задачу. То есть фактически нам нужно найти ячейку, содержащую слово «Henry», и применить нужный стиль к ячейке находящейся по соседству, то есть в столбце «Category». Для этого мы напишем соответствующий селектор и применим метод next():
$(document).ready(function() { $('th').parent().addClass('table-heading'); $('tr:not([th]):even').addClass('even'); $('tr:not([th]):odd').addClass('odd'); $('td:contains("Henry")').next().addClass('highlight'); });
Теперь с применением вышеперечисленных стилей, наша таблица будет выглядеть вот так:
Метод next() применяет нужный нам стиль в пределах одного контейнера только к следующему элементу. А теперь представим, что в нашей таблице появится третий столбик, в котором будет содержаться год издания пьесы. Раскрасить текст всех ячеек, строки содержащий слово «Henry», можно сделать несколькими способами:
1. Получить ячейку, содержащую слово «Henry», и применить стиль ко всем ее «родственным» элементам с помощью метода siblings(). Этот метод выбирает элементы, содержащиеся в одном родительском контейнере
$('td:contains("Henry")').siblings().addClass('highlight');
2. Получить ячейку, содержащую слово «Henry», получить ее родителя (tr), затем найти все ячейки внутри родителя, порядковый номер которых больше нуля (где ноль это первая ячейка), и добавить им нужный класс:
$('td:contains("Henry")').parent().find('td:gt(0)').addClass('highlight');
3. Получить ячейку, содержащую слово «Henry», получить ее родителя (tr), затем найти все ячейки внутри родителя, не содержащих в себе строк «Henry», и добавить им нужный класс:
$('td:contains("Henry")').parent().find('td').not(':contains("Henry")') ).addClass('highlight');
4. Получить ячейку, содержащую слово «Henry», получить ее родителя (tr), затем найти вторую дочернюю ячейку, применить к ней нужный класс, сбросить на начало, найти третью дочернюю ячейку и применить к ней нужный класс:
$('td:contains("Henry")').parent().find('td:eq(1)').addClass('highlight').end().find('td:eq(2)').addClass('highlight');
Все эти способы приведут к одинаковому результату:
Если быть честным, не все из представленных способов комбинации селекторных выражений и методов рекомендованы. Фактически четвертый способ совершенно нелепый. Это просто пример, иллюстрирующий насколько гибкими могу быть методы доступа к DOM.
Сцепление
Все четыре представленных метода демонстрируют способность JQuery к сцеплению. JQuery умеет выбирать один или множество элементов, и производить над ними одно или множество действий. Для примера можно переписать четвертый метод, в виде семи линий, каждая из которых имеет свой собственный комментарий, а работать они при этом будут как одна строка:
$('td:contains("Henry")') //получить все ячейки содержащие "Henry" .parent() //получить их родителя .find("td:eq(1)") //найти внутри родительского контейнера вторую ячейку .addClass("highlight") //применить к ней класс "highlight" .end() //вернуться на этап нахождения родительского контейнера, ячейки содержащей "Henry" .find("td:eq(2)") //найти внутри родительского контейнера третью ячейку .addClass("highlight"); //добавить к ней класс "highlight"
Конечно эта статья, немного сложнее для понимания чем предыдущие, но если разобрать на примерах, то на самом деле все не так страшно как кажется.
Holy Diver says:
Спасибо, хорошая растолковка. Особенно пригодилась конструкция вида $(‘tr:not([th]):even’).addClass(‘even’);
Как раз подобное и искал.
18.02.2009 — 11:13
seredobodera says:
Я в шоке просто!
08.07.2012 — 10:41
tumbas says:
Не нужно вопить. На все ваши вопросы задавайте вопросы в Google.
14.11.2012 — 12:38
madbirdy says:
Отличная статья спасибо! Есть вопрос, а как получить содержание элемента, т.е. что-то вроде innerHTML?
17.07.2009 — 18:48
dreamhelg says:
Знаю только в общих чертах, что для этого используется метод
HTML
, чуть подробнее можно прочесть здесь20.07.2009 — 12:44
EGORR says:
Прошу прощения, в предыдущем примере движок блога порезал пример PHP кода. Но идея осталась.
05.08.2009 — 21:55
veterrus says:
Спасибо большое!
Очень понятно и просто!
18.09.2009 — 16:27
veterrus says:
Подскажите пожалуйста, а если мне надо применить скрипт
$(‘tr:odd’).addClass(‘odd’);
$(‘tr:even’).addClass(‘even’);
к одной из таблиц на странице, а не ко всем?
Как мне это сделать?
Что то понять немогу :(
21.09.2009 — 14:20
dreamhelg says:
Если есть возможность, назначьте этой таблице какой-нибудь ID, например «mytable», и тогда ваш код будет такой:
$("#mytable tr:odd").addClass("odd");
$("#mytable tr:even").addClass("even");
должно работать.
21.09.2009 — 14:23
veterrus says:
Ок, спасибо огромное!!!
Сейчас попробую!
21.09.2009 — 14:28
veterrus says:
Получилось!!! :)
21.09.2009 — 14:29
Ramalah says:
Недавно стал работать с jQuery и никак не могу встретить такого, как найти родительский элемент:
asaa
известен класс ббб, как правильно сослаться на а?
05.10.2009 — 22:47
dreamhelg says:
не совсем понятно, что именно вам нужно получить. Если вы хотите получить элемент а, в котором содержится текст asaa, то тут можно использовать такой селектор:
$("a:contains('asaa')")
06.10.2009 — 07:15
kama says:
Спасибо за то что выложил здесь код! Очень пригодился.
24.10.2009 — 20:36
Алексей says:
Подскажите как удалить текст например ААА из контента посредством jQuery?
21.11.2009 — 19:54
dreamhelg says:
просто текст, должен в чем-то содержатся, например в
p
, в этом случае можно очистить его содержимое примерно так:$("p").html('');
Попробуйте, должно сработать.
23.11.2009 — 08:45
EGORR says:
Плохой способ. К тому же удалит все параграфы.
23.11.2009 — 16:02
dreamhelg says:
Да, возможно есть способ и получше, мне это никогда особо не нужно было, поэтому знаю только такой. Может поделитесь как еще можно это сделать?
23.11.2009 — 16:10
Алексей says:
Если я правельно понял конструкция типа
$(«p»).html(«AAA»).remove();
должна удалить все AAA из параграфов, но ничего не происходит, даже того что говорит EGORR
23.11.2009 — 20:21
dreamhelg says:
Не нужно remove, вот точно так, как я написала нужно сделать, и он очистит весь текст, содержащийся в тегах параграфа.
24.11.2009 — 08:10
EGORR says:
Друзья, надо иногда вылезать за пределы jQuery.
Все очень просто:
$(document).ready(function(){
//var str = document.body.innerHTML; // если неизвестен элемент содержащий искомый текст, берем всё
// var str = $('body').html(); // конструкция jQuery выдаст тот же результат
var str = $('table').html(); // если элемент известен, берем его
var result = (str.replace("Эту строку мы ищем", "На эту строку мы заменяем"));
alret(result);
});
Здесь применена функция замены строки из арсенала JS, которой нет в jQuery, но которую мы запросто можем применять, поскольку jQuery — родная дочь(а может сын) JavaScript.
Хотя сама идея замены текста на клиентской стороне нехороша. Разве что нет доступа на сервант…
24.11.2009 — 11:26
dreamhelg says:
спасибо за пример
24.11.2009 — 13:07
Дмитрий says:
Например, если фоновый цвет последней строчки нашей таблицы является, синим, то первая строка следующей таблицы будет выкрашена в желтый цвет. Как обойти эту проблему будет рассказано позже, а пока просто следует запомнить.
так как же все таки обойти эту проблему? или я просто не нашел, где проблема решается?
23.03.2011 — 23:07
Роман says:
А я не нашел где эта проблема решается, будьте добры — подскажите.
12.04.2012 — 15:16
Дмитрий says:
Все, разобрался :)
25.03.2011 — 18:39
FugQueuenPype says:
Давайте сюда складывать все новые интересные статьи и ответы по теме
02.03.2012 — 16:22
kuhniBioreldectoli says:
Вам это не нравится?
03.05.2012 — 08:42
Евгений says:
Важный вопрос — не могу найти ответа:
Пример кода:
$(document).ready(function() {
$(‘.small1’).click(function(){
$(document).find(‘.small1’).attr(‘class’,’small2′);
alert(‘1’)
})
$(‘.small2’).click(function(){
$(document).find(‘.small2’).attr(‘class’,’small3′);
alert(‘2’)
})
})
Результат:
сколько не нажимай по всегда будет выполняться $(‘.small1’).click()
НО! Я же меняю значение атрибута class. И это значение меняется!!!!
Т.е. Даже после смены значения атрибута class на ‘small2’ — продолжает выполняться действие для ‘small1’
Как обновить кеш селекторов? Или как это называется? Как обновить DOM? Как заставить это работать?)))
23.07.2012 — 10:57
dreamhelg says:
Когда вы изменяете DOM средствами яваскрипта и хотите при этом навесить обработчик события на новый элемент, нужно использовать метод .on:
$('.small1').click(function(){
$(document).find('.small1').attr('class','small2');
alert('1');
})
$('body').on('click', '.small2', function(){
$(document).find('.small2').attr('class','small3');
alert('1');
})
В результате оба клика запустятся сразу же один за другим, если это именно то, что вам нужно было получить.
23.07.2012 — 20:49
Евгений says:
Не совсем то… Пробовал live() использовать — on() это в jQuery 1.7+ появилась…
Попробуйте выполнить мой код — создайте 3 дива и потыкайте по ним… заметите странное поведение…
Даже после on() при нажатии на див с изменённым классом — срабатывает старый эвент или оба.
Я не меняю DOM, я изменяю атрибут элемента. Или при изменении значения атрибута засчитывается изменение DOM?
24.07.2012 — 00:29
dreamhelg says:
Вы навешиваете обработчик события клик на класс, которого в DOM изначально нет, поэтому он не срабатывает. То что при исползовании .on срабатывают оба обработчика нормальное поведение, если вам нужно получить что-то другое, попробуйте изменить решение задачи.
24.07.2012 — 07:09
Евгений says:
Логично…
Тогда возможно ли навесить обработчик события на только что созданный класс? И убрать его с прошлого класса.
14.11.2012 — 20:27
Евгений says:
Спасибо за объяснения!
24.07.2012 — 10:48
Леонид says:
Уважаемый Евгений, подскажите, пожалуйста:
Есть форма
echo »;
……………
for ($i = 0; $i < $columns; $i++) {
echo '’;
echo »;
echo ‘        ‘.»$MassFld[$i]».»;
}
……………
По отмеченному frm4Chck2 (одному, например $n — это получается), мне нужно в jQuery получить селектор для $MassFld[$n].
Как это сделать?
08.06.2013 — 15:02
Marat says:
Что-то я не нашёл где описано решение данной проблемы?
20.07.2013 — 23:03
bjq says:
addClass()-добавляет указанный класс всем элементам коллекции. В качестве параметра можно указать несколько названий классов через пробел.
Пример
Напишем простой скрипт что при наведении мыши на блок (div id=»premer_content1″) в блоке (div id=»div_1″) добавится (методом addClass) клас class2, при уходе мыши с блока (div id=»premer_content1″) удалим (методом removeClass) class2 и добавим class1.
05.07.2014 — 23:08
bjq says:
removeClass ( [] )— удаляет указанный класс у всех элементов коллекции. В качестве параметра можно указать несколько классов через пробел. Если название класса не указано, то будут удалены все классы.
Пример
Сделаем такой пример что при нажатии на кнопку с идентификатором input_1. У нас удалятся все классы с именем class1, благодаря методу removeClass(). Таким образом мы видим что у нас два блока div имеют данный класс благодаря которому текст в блоках синий. А после нажатия на кнопку данный класс удаляется и текст станет чорным.
05.07.2014 — 23:09