Главная страница   /   8.2. Работа с классами (Pro jQuery

Pro jQuery

Pro jQuery

Адам Фриман

8.2. Работа с классами

Хотя можно использовать общие атрибутивные методы для управления классами, jQuery предоставляет набор гораздо более удобных методов. Эти методы описаны в таблице 8-3. Наиболее часто классы используются в HTML документе для того, чтобы указать браузеру, что он должен применить набор CSS свойств, определенных в элементе style. Для более полной информации смотрите главу 3.

Таблица 8-3: Методы для работы с классами
Метод Описание
addClass(name name) Добавляет все элементы в объекте jQuery к указанному классу
addClass(function) Назначает классы элементам в объекте jQuery динамически
hasClass(name) Возвращает true, если как минимум один из элементов в объекте jQuery является членом указанного класса
removeClass(name name) Удаляет элементы в объекте jQuery из указанного класса
removeClass(function) Удаляет элементы в объекте jQuery из указанного класса динамически
toggleClass() Добавляет или удаляет классы, к которым принадлежат элементы в объекте jQuery
toggleClass(boolean) Добавляет или удаляет классы, к которым принадлежат элементы в объекте jQuery, в одном направлении (либо только добавлен, либо только удален)
toggleClass(name)
toggleClass(name name)
Добавляет или удаляет один или больше названных классов для всех элементов в объекте jQuery
toggleClass(name, boolean) Добавляет или удаляет названный класс для всех элементов в объекте jQuery в одном направлении (либо только добавлен, либо только удален)
toggleClass(function, boolean) Динамически добавляет или удаляет классы для всех элементов в объекте jQuery

Можно добавить элементы классу при помощи метода addClass, удалить элементы из класса при помощи метода removeClass и определить, принадлежит ли элемент классу, при помощи метода hasClass. В листинге 8-8 показано использование всех трех методов.

Листинг 8-8: Добавление, удаление и проверка принадлежности к классу
<style type="text/css">
	img.redBorder { border: thick solid red; }
	img.blueBorder { border: thick solid blue; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').addClass("redBorder");
		$('img:even').removeClass("redBorder").addClass("blueBorder");
		console.log("All elements: " + $('img').hasClass('redBorder'));
		$('img').each(function (index, elem) {
			console.log("Element: " + $(elem).hasClass('redBorder') + " " + elem.src);
		});
	});
</script>

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

Итак, я выбираю все элементы img в документе и добавляю их классу redBorder при помощи метода addClass. Затем я выбираю четные элементы img, удаляю их из класса redBorder и добавляю их классу blueBorder при помощи метода removeClass.

Совет

Метод addClass не удаляет существующие для элементов классы; он просто добавляет новый класс к тем классам, которые уже используются.

И наконец, я использую метод hasClass, чтобы проверить наличие класса redBorder для всего набора элементов img (который возвращает true, если как минимум один из элементов является членом класса) и для каждого элемента в отдельности. На рисунке 8-5 можно увидеть результат выполнения скрипта.

Рисунок 8-5: Применение стилей в зависимости от принадлежности к классу

Результат выполнения скрипта, где проверяется принадлежность к классу, следующий:

All elements: true
Element: false http://www.jacquisflowershop.com/jquery/astor.png
Element: true http://www.jacquisflowershop.com/jquery/daffodil.png
Element: false http://www.jacquisflowershop.com/jquery/rose.png
Element: true http://www.jacquisflowershop.com/jquery/peony.png
Element: false http://www.jacquisflowershop.com/jquery/primula.png
Element: true http://www.jacquisflowershop.com/jquery/snowdrop.png

Добавление и удаление классов с использованием функции

Можно динамически указать, какие классы должны быть добавлены или удалены из набора элементов, если добавить функцию методу addClass или removeClass. В листинге 8-9 показано использование функции с методом addClass.

Листинг 8-9: Использование метода addClass с функцией
<style type="text/css">
	img.redBorder { border: thick solid red; }

	img.blueBorder { border: thick solid blue; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').addClass(function (index, currentClasses) {
			if (index % 2 == 0) {
				return "blueBorder";
			} else {
				return "redBorder";
			}
		});
	});
</script>

Аргументами функции являются индекс элемента и текущий набор классов, к которым принадлежит элемент. Как и в похожих функциях, переменная this указывает на объект HTMLElement обрабатываемого элемента. Функция возвращает класс, к которому вы хотите присоединить элемент. В этом примере я использую аргумент index, чтобы поочередно добавить элементы в оба класса blueBorder и redBorder. Результат будет таким же, как показанный на рисунке 8-5.

При удалении элементов из классов применяется похожий подход. Методу removeClass передается функция, как показано в листинге 8-10.

Листинг 8-10: Удаление элементов из класса с использованием функции
<style type="text/css">
	img.redBorder { border: thick solid red; }

	img.blueBorder { border: thick solid blue; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').filter(':odd').addClass("redBorder").end()
			.filter(':even').addClass("blueBorder");

		$('img').removeClass(function (index, currentClasses) {
			if ($(this).closest('#row2').length > 0 
				&& currentClasses.indexOf('redBorder') > -1) {
				return "redBorder";
			} else {
				return "";
			}
		});
	});
</script>

В этом скрипте function, которую я передал методу removeClass, использует HTMLElement объект и текущий набор классов, чтобы удалить класс redBorder для любого элемента img, который является членом этого класса и потомком элемента с ID равном row2. Результат выполнения этого скрипта можно увидеть на рисунке 8-6.

Совет

Обратите внимание, что я возвращаю пустую строку, если я не хочу удалять любой из классов. Если вы вообще не возвращаете значение, jQuery удаляет все классы из элемента.

Рисунок 8-6: Удаление классов с использованием функции

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

В своей самой базовой форме, "переключение" класса обозначает добавление его к любому элементу, который не является его членом, и удаление его из любого, который является. Этого можно достичь, если передать имя класса, который вы хотите "переключать", методу toggleClass, как показано в листинге 8-11.

Листинг 8-11: Использование метода toggleClass
<style type="text/css">
		img.redBorder {border: thick solid red}
		img.blueBorder {border: thick solid blue}
	</style>

	<script type="text/javascript">
		$(document).ready(function () {
			$('img').filter(':odd').addClass("redBorder").end()
				.filter(':even').addClass("blueBorder");

			$("<button>Toggle</button>").appendTo("#buttonDiv").click(doToggle);

			function doToggle(e) {
				$('img').toggleClass("redBorder");
				e.preventDefault();
			};
		});
	</script>

Я начинаю этот скрипт с присвоения класса redBorder всем нечетным элементам img и класса blueBorder всем четным. Потом я создаю новую кнопку и присоединяю ее к элементу, чей id равен buttonDiv. Таким образом, моя новая кнопка размещена рядом с кнопкой "Place Order" (Разместить заказ), которая уже находится на странице. Я использовал метод click, чтобы указать функцию, которую вызовет jQuery, когда пользователь нажмет на кнопку. Это один из аспектов поддержки событий в jQuery, о чем я подробно расскажу в главе 9.

Функция, которая выполняется после нажатия кнопки, называется doToggle, а ключевое выражение следующее:

$('img').toggleClass("redBorder");

Это выражение выбирает в документе все элементы img и "переключает" класс redBorder. Аргумент функции и вызов метода preventDefault не важны для этой главы. Об этом я расскажу в главе 9. Результат выполнения скрипта можно увидеть на рисунке 8-7, хотя этот пример проще понять, если вы загрузите документ в браузер и сами нажмете на кнопку.

Рисунок 8-7: Смена принадлежности к классу при помощи метода toggleClass

Если вы внимательны, вы заметите кое-что странное в этом рисунке. У элементов, которых были красные рамки, больше их нет, а у элементов, которых были синие рамки, так эти рамки синими и остались. Случилось то, что jQuery удалил класс redBorder для нечетных элементов img и добавил его четным элементам, как и ожидалось. Однако элементы, которым был добавлен класс redBorder, также являются членами класса blueBorder. Стиль blueBorder определен после redBorder в элементе style, что обозначает, что это значение свойства имеет более высокий приоритет, как я пояснял в главе 3. Итак, переключение классов работает, но нельзя сбрасывать со счетов и нюансы CSS. Если вы хотите, чтобы была прорисована красная рамка, нужно поменять порядок объявления стилей, как показано в листинге 8-12.

Листинг 8-12: Смена порядка объявления стилей для более полной демонстрации переключения классов
<style type="text/css">
	img.blueBorder {border: thick solid blue}
	img.redBorder {border: thick solid red}
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').filter(':odd').addClass("redBorder").end()
		.filter(':even').addClass("blueBorder");
		$("<button>Toggle</button>").appendTo("#buttonDiv").click(doToggle);
		function doToggle(e) {
			$('img').toggleClass("redBorder");
			e.preventDefault();
		};
	});
</script>

Теперь, когда элемент принадлежит обоим классам blueBorder и redBorder, браузер будет использовать настройку redBorder для свойства border. Результат этого изменения можно увидеть на рисунке 8-8.

Рисунок 8-8: Результат согласования порядка объявления CSS стилей с переключением классов

Переключение нескольких классов

Можно добавить несколько имен классов, разделенных пробелом, методу toggleClass, и переключать каждый из них для выбранных элементов. В листинге 8-13 показан пример.

Листинг 8-13: Переключение нескольких классов
<style type="text/css">
	img.blueBorder { border: thick solid blue; }

	img.redBorder { border: thick solid red; }
</style>
<script type="text/javascript">
	$(document).ready(function () {
		$('img').filter(':odd').addClass("redBorder").end()
		.filter(':even').addClass("blueBorder");
		$("<button>Toggle</button>").appendTo("#buttonDiv").click(doToggle);
		function doToggle(e) {
			$('img').toggleClass("redBorder blueBorder");
			e.preventDefault();
		};
	});
</script>

В этом примере я переключаю классы redBorder и blueBorder для всех элементов img. Результат можно увидеть на рисунке 8-9.

Рисунок 8-9: Переключение нескольких классов

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

Можно переключать все классы, к которым принадлежит набор элементов, если вызвать метод toggleClass без аргументов. Это грамотный прием, потому что jQuery хранит переключаемые классы таким образом, что они корректно добавляются и удаляются. В листинге 8-14 содержится пример использования этого метода.

Листинг 8-14: Переключение всех классов для выбранных элементов
<style type="text/css">
	img.blueBorder { border: thick solid blue; }
	img.redBorder { border: thick solid red; }
	label.bigFont { font-size: 1.5em; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').filter(':odd').addClass("redBorder").end()
			.filter(':even').addClass("blueBorder");
		$('label').addClass("bigFont");
		$("<button>Toggle</button>").appendTo("#buttonDiv").click(doToggle);
		function doToggle(e) {
			$('img, label').toggleClass();
			e.preventDefault();
		};
	});
</script>

В этом примере я использовал метод addClass, чтобы добавить классы для элементов img и label. Когда нажимается кнопка Toggle, я выбираю эти же элементы и вызываю метод toggleClass без аргументов. Результат выполнения этого скрипта можно увидеть на рисунке 8-10.

Рисунок 8-10: Переключение всех классов

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

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

Можно ограничить переключение классов, если добавить аргумент boolean в метод toggleClass. Если вы добавите false, классы будут только удаляться, если вы добавите true, классы будут только добавляться. В данном случае вы получите тот же результат, как и при использовании методов addClass и removeClass, поэтому я фактически не использую эту возможность. В листинге 8-15 показан пример.

Листинг 8-15: Ограничение переключения классов
<style type="text/css">
	img.blueBorder { border: thick solid blue; }
	img.redBorder { border: thick solid red; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').filter(':odd').addClass("redBorder").end()
			.filter(':even').addClass("blueBorder");
		$("<button>Toggle On</button>").appendTo("#buttonDiv").click(doToggleOn);
		$("<button>Toggle Off</button>").appendTo("#buttonDiv").click(doToggleOff);
		function doToggleOff(e) {
			$('img, label').toggleClass("redBorder", false);
			e.preventDefault();
		};
		function doToggleOn(e) {
			$('img, label').toggleClass("redBorder", true);
			e.preventDefault();
		};
	});
</script>

Я добавил в документ две кнопки, каждая из которых будет переключать класс redBorder только в одном направлении. После того, как одна из кнопок будет нажата, дальнейшее ее нажатие не приведет ни к какому результату, пока не будет нажата вторая кнопка (потому что каждая кнопка переключает классы только в одном направлении).

Динамическое переключение классов

Вы можете решить, какие классы должны переключаться для элементов динамически, если добавите функцию в метод toggleClass. В листинге 8-16 показан простой пример этого.

Листинг 8-16: Переключение классов с использованием функции
<style type="text/css">
	img.blueBorder { border: thick solid blue; }
	img.redBorder { border: thick solid red; }
</style>

<script type="text/javascript">
	$(document).ready(function () {
		$('img').addClass("blueBorder");
		$('img:even').addClass("redBorder");

		$("<button>Toggle</button>").appendTo("#buttonDiv").click(doToggle);

		function doToggle(e) {
			$('img').toggleClass(function (index, currentClasses) {
				if (index % 2 == 0) {
					return "redBorder";
				} else {
					return "";
				}
			});
			e.preventDefault();
		};
	});
</script>

Я добавил класс blueBorder для всех элементов img, а класс redBorder для четных элементов img. Аргументами функции являются индекс обрабатываемого элемента и текущий набор классов, к которым принадлежит этот элемент. Кроме того, переменная this указывает на объекта HTMLElement для текущего элемента. Результат, который возвращает функция, – это имена классов, которые должны переключаться. Если вы не хотите переключать классы для элементов, тогда вы возвращаете пустую строку (если не вернуть результат, тогда для элемента переключатся все его классы).