Статьи

Как создать плагин Textarea JQuery с автоматическим расширением, часть 3

Авто-Расширение Textarea В первой части мы узнали, как можно создать автоматически расширяющуюся текстовую область , и сопоставили требования. Во второй части мы определили, как кодеры будут инициализировать наш компонент. Теперь пришло время испачкать руки с помощью JavaScript.

Мы создаем плагин jQuery с именем TextAreaExpander. Вы можете прочитать о тонкостях разработки плагинов jQuery в этом руководстве , но скелет нашего кода:


(function($) {

	// jQuery plugin definition
	$.fn.TextAreaExpander = function(minHeight, maxHeight) {

		// ... our code ...

		return this;
	};

})(jQuery);

Затем оператор $ .fn объявляет наш новый плагин jQuery TextAreaExpander с аргументами minHeight и maxHeight. Мы могли бы выразить это в объекте JSON, но вряд ли нам понадобятся дополнительные параметры, поэтому мы будем упрощать его.

Обратите внимание, что «this» относится к объекту jQuery; мы возвращаем его, чтобы другие jQuery-эффекты могли быть связаны с теми же элементами DOM.

Инициализация текстовой области

Следующий код инициализации добавлен в нашу функцию TextAreaExpander:

 
// initialize
this.each(function() {

	// is a textarea?
	if (this.nodeName.toLowerCase() != "textarea") return;

	// set height restrictions
	var p = this.className.match(/expand(d+)-*(d+)*/i);
	this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
	this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);

	// initial resize
	ResizeTextarea(this);

	// add events
	if (!this.Initialized) {
		this.Initialized = true;
		$(this).css("padding-top", 0).css("padding-bottom", 0);
		$(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
	}
});

return this;
};

Это проходит по всем выбранным jQuery узлам DOM и запускает анонимную функцию. Значение this в этой функции является отдельным узлом textarea. Происходит следующая инициализация:

  1. Первая строка гарантирует, что только для текстовых областей применяется эффект автоматического расширения.
  2. Следующие три строки извлекают минимальные и максимальные значения высоты. Аргументы, передаваемые в функцию TextAreaExpander, используются по умолчанию. Если ничего не указано, HTML-класс «раскрытия» текстовой области анализируется с помощью регулярного выражения. Если у нас все еще нет значений, предполагаются 0 и 99999 (обратите внимание, что текстовая область всегда будет иметь минимальную высоту 1 символа, поэтому нулевая высота никогда не применяется). Значения хранятся как свойства объекта узла textarea — поэтому мы можем исследовать их из любого кода.
  3. Следующая строка вызывает функцию ResizeTextarea и передает узел textarea. Это установит высоту соответствующего размера при инициализации автоматического расширения.
  4. Наконец, мы сбрасываем любые вертикальные отступы и определяем события «keyup» и «focus». Та же функция ResizeTextarea вызывается, когда текстовое поле получает фокус и после того, как текст был обновлен пользователем. Условие «если» вокруг этих событий гарантирует, что они могут быть применены только один раз к любой текстовой области. Это условие могло бы быть применено ко всей функции инициализации, однако этот код позволяет нам изменять минимальную и максимальную высоты по желанию.

Изменение размера текстовой области

Теперь нам нужно определить нашу функцию ResizeTextarea.

В первой части мы обсудили различия в браузерах и отметили, что IE и Opera никогда не должны устанавливать высоту textarea Поэтому мы назначим переменную, которая возвращает false, если используется IE или Opera:

 
var hCheck = !($.browser.msie || $.browser.opera);

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

Теперь мы можем кодировать нашу функцию ResizeTextarea:

 
// resize a textarea
function ResizeTextarea(e) {

	// event or element?
	e = e.target || e;

	// find content length and box width
	var vlen = e.value.length, ewidth = e.offsetWidth;
	if (vlen != e.valLength || ewidth != e.boxWidth) {

		if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0px";
		var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));

		e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
		e.style.height = h + "px";

		e.valLength = vlen;
		e.boxWidth = ewidth;
	}

	return true;
};

Этой функции передается аргумент «е». Это либо узел текстовой области (во время инициализации), либо объект события (когда происходит keyup или focus).

  1. Первая строка меняет ‘e’ на объект узла textarea, если событие было запущено.
  2. Количество символов, введенных в текстовое поле, присваивается vlen. Ширина в пикселях поля назначается ширине. Если эти значения не изменились, нам не нужно беспокоиться об изменении размера поля (пользователь может просто перемещать курсор). vlen и ewidth сохраняются как свойства объекта узла textarea с именами valLength и boxWidth. Они устанавливаются после изменения размера текстовой области, поэтому изменение размера всегда будет происходить при первом вызове ResizeTextarea.
  3. Следующая строка сбрасывает высоту текстовой области до 0px. Это происходит только для браузеров не IE / Opera, если содержимое было удалено или была изменена ширина окна.
  4. Значение scrollHeight текстовой области теперь присваивается переменной ‘h’. Math.min и Math.max используются для обеспечения того, чтобы значение находилось в пределах минимального и максимального пределов пикселей, определенных для этой текстовой области.
  5. Прежде чем изменить высоту текстовой области, мы изменим свойство переполнения CSS. Полосы прокрутки будут показаны только в том случае, если высота содержимого превышает высоту текстовой области.
  6. Теперь мы можем изменить высоту текстовой области и обновить значения valLength и boxWidth.
  7. Наконец, функция возвращает true, чтобы другие обработчики событий textarea не были отменены.

Наш плагин TextAreaExpander jQuery завершен. Однако нам нужно убедиться, что эффект применяется ко всем тегам textarea В конце нашего файла мы можем добавить событие, которое инициализирует все соответствующие текстовые области после загрузки страницы:

 
// initialize all expanding textareas
jQuery(document).ready(function() {
	jQuery("textarea[class*=expand]").TextAreaExpander();
});

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

Полезные ресурсы:

Смотрите также: