Pull to refresh

<input placeholder="нажми чтобы написать">

JavaScript *
Sandbox
В силу моего параноидального отношения к сайтам а также из проф соображений, я использую firefox + noscript. Когда я впервые захожу на некоторые сайты, у меня выключен js и кликая на поле, для поиска где красуется надпись «search here» — получаю облом. При том что у меня современный браузер, который без проблем поддерживает атрибут placeholder. Как правило везде стоит вот такой ужас: <input value="Поиск по сайту" onfocus="if (this.value == 'Поиск по сайту') this.value == ''" onblur="if (this.value == '') this.value == 'Поиск по сайту'"> (эхо конца 90-ых).

Продвинутые мира сего, вынесли это дело за пределы <input>, но суть от этого не меняется. Еще более продвинутые, убрали значение из value и поместили его в title — это получше будет. Благо дядьки, создающие стандарты, узрели это дело и решили снабдить тэг специальным для этих целей атрибутом placeholder. Разработчики браузеров сразу внедрили этот функционал, но тут опять на дороге встал IE. Думаю не стоить напоминать, что в мире не мало компов где установлены 6-IE двинозавры, не говоря о 7 и уж тем более о 8. Напомню также, что дядьки из MSIE сочли данный атрибут излишком роскоши и не включили его даже в 9-ую версию. Чтобы обойти все эти недоразумения и облегчить себе жизнь при верстке страниц, я соcтряпал небольшой скриптик. Как можно увидеть далее, он базируется на jquery но ничего не может помешать при помощи простых манипуляций переделать на другой framework.

(function($)
{
	/**
	 * Ability for placeholder
	 * usage: <input placeholder="any text">
	 */
	$(function()
	{
		// if modernizr is available replace by var placeholder_support = Modernizr.input.placeholder;
		var placeholder_support = !!('placeholder' in document.createElement( 'input' ));
		if (!placeholder_support)
		{
			var inputs = $('input[placeholder]'),
					len = inputs.length,
					input,
					placeholder_class = 'placeholder';
			while (len--)
			{
				inputs[len].value = inputs[len].value ? inputs[len].value : inputs.eq(len).addClass(placeholder_class).attr('placeholder');
				inputs.eq(len).focus(function()
				{
					var th = $(this);
					if (this.value == th.attr('placeholder'))
					{
						th.removeClass(placeholder_class);
						this.value = '';
					}
				}).blur(function()
				{
					var th = $(this);
					if (this.value == '')
					{
						th.addClass(placeholder_class);
						this.value = th.attr('placeholder');
					}
				});
				(function(input)
				{
					$(input.form).bind('submit', function()
					{
						if (input.value == $(input).attr('placeholder')) input.value = '';
					});
				}(inputs[len]));
			}
		}
	});
}(jQuery));

Стоит отметить, может кто не заметил, что функция при активном placeholdere, добавляет класс placeholder, что можно использовать в купе с -webkit-input-placeholder,input::-webkit-input-placeholder, input:-moz-placeholder.

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

UPD: Из всей халивары что тут развелось единственное верное примечание было от rwz, о том что, value переопределять таким способом неправильно. Данное утверждение уводит на нет универсальность вышеуказанного метода. Поэтому, решил на скорую руку набросать другое решение, лишенное этих недостатков.
(function($)
{
	$(function()
	{
		var placeholder_support = !!('placeholder' in document.createElement( 'input' ));
		if (!placeholder_support)
		{
			var body = $(document.body);
			$('input[placeholder]').each(function(){
				var tpl = '<div class="placeholder" style="position:absolute;overflow:hidden;white-space:nowrap"/>',
					th = $(this),
					position = th.offset(),
					height = th.height(),
					width = th.width(),
					placeholder = $(tpl).appendTo(body)
						.css({
							top: position.top,
							left: position.left,
							width: width,
							height: height,
							padding: ((th.innerHeight(true) - height) / 2) + 'px ' +  ((th.innerWidth(true) - width) / 2) + 'px '
						})
						.text(th.attr('placeholder'))
						.addClass(th.attr('class'))
				;

				placeholder.bind('click focus', function(){placeholder.hide();th.focus();});
				th.bind('blur', function(){if (th.val() == '') placeholder.show()});

			});
		}
	});
}(jQuery));

Что нужно учитывать при использовании данного метода:
  1. Классу .placeholder нужно назначить тот-же размер и line-height что у его input. Все классы input копируются к div placeholdera
  2. Неверное положение при прокрутке если inpu находиться в контенере с position:fixed. При надобности исправляется легко.
  3. Ну и соответственно скорость. Хотя терпимо, на 100 input разбросанных по все странице firefox показал 177ms (для теста атрибут был изменена на data-placeholder).
  4. Минифицированный код занимает 597 байт — при желании можно еще уменьшить

Возможно есть и другие недочеты или недостатки, с радостью прочитаю ваши комментарии и внесу соответствующие изменения.

PPS: Речь в статье идет не о том включен js или нет. Это костыль для MSIE в частности и возможно для других браузерах.
Tags:
Hubs:
Total votes 89: ↑53 and ↓36 +17
Views 22K
Comments 46
Comments Comments 46

Posts