События и методы в jQuery
Одной из наиболее часто используемых операций является динамическое изменение содержимого элементов. Давайте представим, что перед нами стоит задача изменить текст в абзаце, который обернут блоком с классом wrap. Смена текста должна происходить только, если пользователь кликнет по этому абзацу.
Создадим html страницу с нужными элементами:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Работа с jQuery</title>
<script type='text/javascript' src='js/jquery-1.7.2.min.js'></script>
</head>
<body>
<h1>Изменение текста в абзаце</h1>
<div class="wrap">
<p>Этот текст содержится в абзаце до того, как по нему кликнули.</p>
</div>
</body>
</html>
Не будем тратить много времени на украшательства через css - просто зададим для дива отступы слева и сверху, что бы текст не прижимался к границе окна браузера:
.wrap {margin:20px 0 0 30px;}
Пришла пора написать требуемый jQuery код и решить поставленную задачу. Прежде всего выберем требуемый элемент. Из прошлых статей мы уже знаем, как это сделать:
$(function () {
$('.wrap p')
});
Поскольку нам нужны только те абзацы, которые находятся внутри блока wrap, то и обратимся сначала к этому блоку, а затем через пробел укажем нужный элемент внутри него - $('.wrap p').
В задаче сказано, что смена текста должна происходить только по клику на абзаце (т.е. на элементе p). jQuery позволяет перехватывать всевозможные события и клик на элементе страницы - не исключение. За это отвечает обработчик события click():
$(function () {
$('.wrap p').click();
});
Теперь, все команды, которые мы пропишем внутри круглых скобок обработчика будут выполняться, только, если произойдет событие, за которое данный обработчик отвечает. Вернемся к задаче - нам потребуется написать функцию, которая расскажет, где и что нужно поменять. Внутри скобок обработчика пишем следующее:
$(function () {
$('.wrap p').click(function() {});
});
Тут все просто - объявляем анонимную функцию (без имени), в фигурных скобках которой пропишем команды, необходимые для выполнения поставленной задачи. Для смены текста в jQuery существует метод text(). Если ему не передавать никаких параметров (ничего не писать в круглых скобках), то он просто вернет текст, содержащийся в элементе, к которому применен. Если же в скобках что то указать, то текст элемента будет изменен на значение, указанное в параметрах метода.
Давайте поэкспериментируем. Снова обратимся к нашему абзацу и применим к нему метод text() без параметров. Что бы удостовериться, что нам действительно вернется строка, содержащаяся в теге p, сохраним результат в переменную и выведем его в модальном окне:
$(function () {
$('.wrap p').click(function() {
var text = $('.wrap p').text();
alert(text);
});
});
Запустите страницу в браузере и кликните по тексту. На экране появится модальное окно с точно таким же текстом, как и в абзаце. Снова вернемся к задаче. Для ее выполнения осталось совсем немного. Что бы поменять текст, нужно в методе text() передать параметр, строку, которой мы хотим заменить содержимое абзаца. Давайте сделаем это:
$(function () {
$('.wrap p').click(function() {
$('.wrap p').text('Текст, измененный с помощью метода jQuery');
});
});
Мы достигли желаемого, по клику на абзаце текст меняется и, казалось бы, можно идти пить кофе с чувством выполненного долга. Но давайте присмотримся к коду... Нам пришлось дважды обращаться к абзацу и оба раза мы писали конструкцию $('.wrap p'). Ошибки тут нет, однако можно сделать запись более грамотной. Если нам требуется сослаться на один и тот же элемент, который инициализировал событие, то для этого мы вполне можем использовать ключевое слово this. Давайте перепишем код с учетом только что полученной информации:
$(function () {
$('.wrap p').click(function() {
$(this).text('Текст, измененный с помощью метода jQuery');
});
});
Теперь нас не упрекнут в безграмотности даже бывалые программисты... или все же упрекнут? До сих пор мы работали со страницей, на которой присутствовал лишь один блок div с классом wrap и внутри него находился лишь один параграф с текстом. А что, произойдет, если страница изменится, например, так:
<h1>Изменение текста в абзаце</h1>
<div class="wrap">
<p>Этот текст содержится в абзаце до того, как по нему кликнули.</p>
</div>
<ul class="wrap">
<li><p>Этот текст находится в списке и не должен измениться.</p></li>
</ul>
<h2 class="wrap"><p>Этот текст тоже не должен меняться.</p></h2>
Попробуйте добавить новые элементы с тем же классом на страницу и пощелкайте по ним. Вот же засада - при клике по любому абзацу, расположенному внутри элемента с классом wrap, текст в нем изменяется. Что же происходит?
В отличии от id один и тот же класс может использоваться на странице сколько угодно раз, в том числе и с разными элементами. Когда мы отбирали требуемый элемент, то указали, что нас интересует абзац, который находится внутри элемента с классом wrap. Но мы не учли, что на странице может быть несколько разных элементов с таким же классом. Что же, исправим и эту нашу оплошность.
Еще раз внесем изменения в код:
$(function () {
$('div.wrap p').click(function() {
$(this).text('Текст, измененный с помощью метода jQuery');
});
});
В коде выше мы сказали jQuery, что нас интересует только тот абзац, который находится внутри блока div с классом wrap. Вот теперь можно пить спокойно кофе с уверенностью, что не будет стыдно в будущем за выполненную задачу. Все работает как требуется.
На всякий случай, если все же ничего не получилось (где то допущена ошибка и не получается ее найти), по ссылке ниже можно скачать готовый код и посмотреть, что сделано не так.
Подробно ознакомиться с существующими в jQuery методами можно на "этой странице.". А в следующих статьях мы попробуем попрактиковаться на более полезных для реальной жизни примерах и заодно закрепим в памяти полученную информацию.