Прозрачный полифил атрибута 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. |
Вот моя реализация , если не брать к вниманию Кросс-браузерное добавление событий, получается 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> |
Цитата:
|
А кому-нибудь приходила в голову такая идея: при потере фокуса (blur), если value пустой, то сверху на поле накладывать div или span с текстом? :)
|
Ruslan_xDD,
проще не сверху, а снизу, сделав прозрачным поле. А если бы еще был селектор пустоты поля, то можно было бы переложить на css работу по скрытию/показу "плейсхолдера" |
Цитата:
и это давно было - сейчас можно, наверное, подхватить placeholder через селектор псевдоэлемента и проанимировать появление, например, через color (указав альфа канал) ну или ч-з opacity. хз, не пробовал |
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> |
Цитата:
Для jQuery есть плагин, он перехватывает функцию val(). Хотелось бы тоже самое, но для ванильного js. Цитата:
|
Цитата:
|
если я тебя правильно понял , ты хочешь вмести с placeholder сразу проверку всей формы ?
|
Часовой пояс GMT +3, время: 00:53. |