Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.01.2015, 20:19
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 15.01.2015, 11:20
Профессор
Отправить личное сообщение для caetus Посмотреть профиль Найти все сообщения от caetus
 
Регистрация: 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.
Ответить с цитированием
  #3 (permalink)  
Старый 15.01.2015, 13:05
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Сообщение от caetus
Емулятор ie показывает что даже в 5 работает
В 7 и в 6 работает, про пятую не наю
Ответить с цитированием
  #4 (permalink)  
Старый 15.01.2015, 18:29
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 30.04.2012
Сообщений: 3,018

А кому-нибудь приходила в голову такая идея: при потере фокуса (blur), если value пустой, то сверху на поле накладывать div или span с текстом?
Ответить с цитированием
  #5 (permalink)  
Старый 16.01.2015, 00:25
Аватар для BETEPAH
Профессор
Отправить личное сообщение для BETEPAH Посмотреть профиль Найти все сообщения от BETEPAH
 
Регистрация: 23.06.2011
Сообщений: 1,165

Ruslan_xDD,
проще не сверху, а снизу, сделав прозрачным поле.
А если бы еще был селектор пустоты поля, то можно было бы переложить на css работу по скрытию/показу "плейсхолдера"
Ответить с цитированием
  #6 (permalink)  
Старый 16.01.2015, 06:35
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Ruslan_xDD Посмотреть сообщение
А кому-нибудь приходила в голову такая идея: при потере фокуса (blur), если value пустой, то сверху на поле накладывать div или span с текстом?
я так делал - нужно было placeholder показать через анимацию.

и это давно было - сейчас можно, наверное, подхватить placeholder через селектор псевдоэлемента и проанимировать появление, например, через color (указав альфа канал) ну или ч-з opacity. хз, не пробовал
Ответить с цитированием
  #7 (permalink)  
Старый 16.01.2015, 09:19
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 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>
Ответить с цитированием
  #8 (permalink)  
Старый 16.01.2015, 09:50
Аватар для danik.js
Профессор
Отправить личное сообщение для danik.js Посмотреть профиль Найти все сообщения от danik.js
 
Регистрация: 11.09.2010
Сообщений: 8,804

Сообщение от caetus
Вот моя реализация
Да обычные реализации есть давно. Я же предлагаю реализацию DOM-интерфейса - свойство input.placeholder (не очень полезно) и адекватный input.value (вот это уже важно).
Для jQuery есть плагин, он перехватывает функцию val(). Хотелось бы тоже самое, но для ванильного js.
Сообщение от Ruslan_xDD
на поле накладывать div или span с текстом?
Есть и такой полифил. Решает почти все проблемы: с value, с type=password, с отправкой формы, но имеет и свои минусы. Тоже в планах.
__________________
В личку только с интересными предложениями
Ответить с цитированием
  #9 (permalink)  
Старый 16.01.2015, 10:34
Аватар для BETEPAH
Профессор
Отправить личное сообщение для BETEPAH Посмотреть профиль Найти все сообщения от BETEPAH
 
Регистрация: 23.06.2011
Сообщений: 1,165

Сообщение от Ruslan_xDD
input:not(:focus):invalid + span
Это сработает там, где и плейсхолдер нативно работает. IE9- в пролёте.
Ответить с цитированием
  #10 (permalink)  
Старый 16.01.2015, 13:02
Профессор
Отправить личное сообщение для caetus Посмотреть профиль Найти все сообщения от caetus
 
Регистрация: 23.09.2014
Сообщений: 197

если я тебя правильно понял , ты хочешь вмести с placeholder сразу проверку всей формы ?

Последний раз редактировалось caetus, 16.01.2015 в 13:14.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
placeholder под IE mixtape Events/DOM/Window 4 18.09.2014 22:13
jquery для placeholder работает только для первого input в ie Nailya jQuery 1 13.05.2014 09:57
Изменение значения атрибута. tiros jQuery 0 05.05.2011 00:13
Не могу получить значение атрибута DenQ jQuery 9 06.02.2011 14:33
Кроссброузерно определить значение атрибута faunder Общие вопросы Javascript 5 21.02.2009 22:08