11.01.2015, 20:19
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Прозрачный полифил атрибута placeholder
Короче, я подумал, почему бы не использовать геттеры/сеттеры для скрытия фэйкового плейсхолдера от скрипта?
input.value = '';
input.placeholder = 'placeholder';
alert(input.value); // пустая строка, не смотря на то, что в инпуте отображается 'placeholder'
Работает в IE8-9. В других браузерах - не знаю. Но знаю что подход работает в опере последней старой и в файрфоксе последнем. А значит, скорее всего будет работать и в старых версиях этих браузеров. В хроме облом. Хотя есть некоторые мысли, возможно и получится.
IE6-7 вот в пролете, да. Но это не многих огорчит.
Вот набросок:
<!DOCTYPE html>
<meta charset="utf-8" />
<style>
input.placeholder{
color: #999;
}
</style>
<form action="">
<p><input type="text" placeholder="abc" /></p>
</form>
<script>
var input = document.getElementsByTagName('input')[0];
var object = 'value' in input.constructor.prototype ? input.constructor.prototype : input;
var nativeValueDescriptor = Object.getOwnPropertyDescriptor(object, 'value');
input._value = input.value;
input._placeholder = input.getAttribute('placeholder') || '';
input.removeAttribute('placeholder'); // для теста в новых браузерах
input._placeholderVisible = false;
function showPlaceholder() {
input._placeholderVisible = true;
input.className += ' placeholder';
nativeValueDescriptor.set.call(input, input._placeholder);
}
function hidePlaceholder() {
input._placeholderVisible = false;
input.className = (' ' + input.className + ' ').replace(/\s+placeholder\s+/);
nativeValueDescriptor.set.call(input, '');
}
var phDescriptor = {
set: function(value) {
this._placeholder = value;
if (this._placeholderVisible)
nativeValueDescriptor.set.call(input, this._placeholder);
},
get: function() {
return this._placeholder;
}
};
var valueDescriptor = {
set: function(value) {
input._placeholderVisible = false;
nativeValueDescriptor.set.call(this, value);
},
get: function() {
if (this._placeholderVisible)
return '';
return nativeValueDescriptor.get.call(this);
}
};
Object.defineProperty(input, 'value', valueDescriptor);
Object.defineProperty(input, 'placeholder', phDescriptor);
if (!input._value) {
showPlaceholder();
}
input.onfocus = function(e) {
if (this._placeholderVisible)
hidePlaceholder();
};
input.onblur = function(e) {
if (!nativeValueDescriptor.get.call(this))
showPlaceholder();
};
</script>
Почему-то в IE input.getAttribute('placeholder') дает null
Причем setAttribute на самом деле устанавливает свойство, а не атрибут.
Наверно в IE не нужно ставить setter на placeholder, достаточно слушать propertychange.
__________________
В личку только с интересными предложениями
Последний раз редактировалось danik.js, 11.01.2015 в 20:24.
|
|
15.01.2015, 11:20
|
Профессор
|
|
Регистрация: 23.09.2014
Сообщений: 197
|
|
Вот моя реализация , если не брать к вниманию Кросс-браузерное добавление событий, получается 20 строк -+.
Емулятор ie показывает что даже в 5 работает , только я что то сомневаюсь ...
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<meta charset="utf-8">
<style>
input {
color: silver;
}
</style>
</head>
<div id="placeholder">
<input type="text" data-pl="abc" value='abc'>
<input type="text" data-pl="abc1" value='abc1'>
<input type="text" data-pl="abc11" value='abc11'>
<input type="text" data-pl="abc12" value='abc12'>
</div>
<div id="place">
<input type="text" data-pl="abc1" value='abc1'>
<input type="text" data-pl="abc2324" value='abc2324'>
</div>
[JS run]
<script>
function addevent(obj, e, h) {if (obj.addEventListener) { obj.addEventListener(e, h, false);} else if (obj.attachEvent) { obj.attachEvent('on'+e, h);} else { obj['on'+e]=function() { h();};}} function delevent(obj, e, h) { if (obj.removeEventListener) { obj.removeEventListener(e, h, false);} else if (obj.detachEvent) { obj.detachEvent('on'+e, h);} else {obj['on'+e]=null;}}
var fn = function (elem) {
var placeholder = document.getElementById(elem);
var o = {
focus: function (e) {
e = e.target || e.srcElement;
if(!e.type == 'text') return;
if(e.value == e.getAttribute('data-pl')) {
e.value = '';
e.style.color = 'black'
}
addevent(e, 'blur', o.blur);
},
blur: function (e) {
e = e.target || e.srcElement;
if(e.value === '' || e.value == ' ') {
e.value = e.getAttribute('data-pl');
e.style.color = 'silver';
}
delevent(e, 'blur', o.blur);
}
}
addevent(placeholder, 'click', o.focus);
}
var place1 = fn('placeholder')
var place2 = fn('place')
</script>
[/JS]
</html>
Последний раз редактировалось caetus, 15.01.2015 в 11:52.
|
|
15.01.2015, 13:05
|
без статуса
|
|
Регистрация: 25.05.2012
Сообщений: 8,219
|
|
Сообщение от caetus
|
Емулятор ie показывает что даже в 5 работает
|
В 7 и в 6 работает, про пятую не наю
|
|
15.01.2015, 18:29
|
|
Профессор
|
|
Регистрация: 30.04.2012
Сообщений: 3,018
|
|
А кому-нибудь приходила в голову такая идея: при потере фокуса (blur), если value пустой, то сверху на поле накладывать div или span с текстом?
|
|
16.01.2015, 00:25
|
|
Профессор
|
|
Регистрация: 23.06.2011
Сообщений: 1,165
|
|
Ruslan_xDD,
проще не сверху, а снизу, сделав прозрачным поле.
А если бы еще был селектор пустоты поля, то можно было бы переложить на css работу по скрытию/показу "плейсхолдера"
|
|
16.01.2015, 06:35
|
sinistral
|
|
Регистрация: 28.03.2011
Сообщений: 5,418
|
|
Сообщение от Ruslan_xDD
|
А кому-нибудь приходила в голову такая идея: при потере фокуса (blur), если value пустой, то сверху на поле накладывать div или span с текстом?
|
я так делал - нужно было placeholder показать через анимацию.
и это давно было - сейчас можно, наверное, подхватить placeholder через селектор псевдоэлемента и проанимировать появление, например, через color (указав альфа канал) ну или ч-з opacity. хз, не пробовал
|
|
16.01.2015, 09:19
|
|
Профессор
|
|
Регистрация: 30.04.2012
Сообщений: 3,018
|
|
BETEPAH,
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
input + span {
color: #AAA;
display: none;
font-style: italic;
line-height: 20px;
margin-left: -165px;
position: absolute;
}
input:not(:focus):invalid + span {
display: inline;
}
</style>
</head>
<body>
<input required="required" type="text">
<span>Placeholder</span>
</body>
</html>
|
|
16.01.2015, 09:50
|
|
Профессор
|
|
Регистрация: 11.09.2010
Сообщений: 8,804
|
|
Сообщение от caetus
|
Вот моя реализация
|
Да обычные реализации есть давно. Я же предлагаю реализацию DOM-интерфейса - свойство input.placeholder (не очень полезно) и адекватный input.value (вот это уже важно).
Для jQuery есть плагин, он перехватывает функцию val(). Хотелось бы тоже самое, но для ванильного js.
Сообщение от Ruslan_xDD
|
на поле накладывать div или span с текстом?
|
Есть и такой полифил. Решает почти все проблемы: с value, с type=password, с отправкой формы, но имеет и свои минусы. Тоже в планах.
__________________
В личку только с интересными предложениями
|
|
16.01.2015, 10:34
|
|
Профессор
|
|
Регистрация: 23.06.2011
Сообщений: 1,165
|
|
Сообщение от Ruslan_xDD
|
input:not(:focus):invalid + span
|
Это сработает там, где и плейсхолдер нативно работает. IE9- в пролёте.
|
|
16.01.2015, 13:02
|
Профессор
|
|
Регистрация: 23.09.2014
Сообщений: 197
|
|
если я тебя правильно понял , ты хочешь вмести с placeholder сразу проверку всей формы ?
Последний раз редактировалось caetus, 16.01.2015 в 13:14.
|
|
|
|