placeholder 実装マニアックス

placeholder

<input type="text" placeholder="Placeholder Text">

Supports

Hatena.UgoMemo.Form.Placeholder

<input name="channel-name" placeholder="チャンネル名を入力">
new Hatena.UgoMemo.Form.Placeholder(elem['channel-name']);
Hatena.UgoMemo.Form.Placeholder = new Ten.Class({
    initialize: function (el) {
        var self = this;
        this.element = el;

        // If @placeholder is natively supported:
        var tester = document.createElement(el.nodeName);
        if (typeof(tester.placeholder) != 'undefined') return;

        new Ten.Observer(el, 'onchange', this, 'disable');    
        new Ten.Observer(el, 'onfocus', this, 'hide');
        this.blurObserver = new Ten.Observer(el, 'onblur', this, 'show');

        // Prevent placeholder values from being cached
        if (Hatena.UgoMemo.Form.Placeholder.hasBfcache) {
            self._SetPageEvents();
        } else {
            self._OnBeforeunload = new Ten.Observer(window, 'onbeforeunload', this, 'hide');
            self._OnLoad = new Ten.Observer(window, 'onload', function () {
                self.show();
            });
            self._OnPageshow = new Ten.Observer(window, 'onpageshow', self, '_StopPageshow');
        }

        if (el.form) {
            new Ten.Observer(el.form, 'onsubmit', this, 'hide');
        }

        this.show();
    }
}, {
    _SetPageEvents: function () {
        new Ten.Observer(window, 'onpagehide', this, 'hide');
        new Ten.Observer(window, 'onpageshow', this, 'show');
    },
    _StopPageshow: function () {
      this._OnBeforeunload.stop();
      this._OnLoad.stop();
      this._SetPageEvents();
      this._OnPageshow.stop();
    },

    disable: function () {
        if (this.element.value == '') {
            this.blurObserver.start();
        } else {
            this.blurObserver.stop();
        }
        Ten.DOM.removeClassName(this.element, 'um-placeholder');
    },
    show: function () {
        if (this.shown()) return;

        if (this.element.value != '') return;

        var ph = this.element.getAttribute('placeholder');
        if (ph == null) return;

        this.element.value = ph;
        Ten.DOM.addClassName(this.element, 'um-placeholder');
    },
    hide: function () {
        if (!this.shown()) return;

        this.element.value = '';
        Ten.DOM.removeClassName(this.element, 'um-placeholder');
    },
    shown: function () {
        return Ten.DOM.hasClassName(this.element, 'um-placeholder');
    }
});

Hatena.Bookmark.Form.Placeholder

<textarea id="comment" ... placeholder="コメントする"></textarea>
<script type="text/javascript">
  new Hatena.Bookmark.Form.Placeholder( document.getElementById('comment') );
</script>
.placeholder {
  position: absolute;
  color: #aaa;
  padding: 3px;
}

The static-position containing block is the containing block of a hypothetical box that would have been the first box of the element if its specified 'position' value had been 'static'...

If all three of 'left', 'width', and 'right' are 'auto': ... set 'left' to the static position ...

Hatena.Bookmark.Form.Placeholder = new Hatena.Bookmark.Class({
    initialize: function (text) {
        if (typeof document.createElement(text.tagName).placeholder !== 'undefined') return;
        this.text = text;
        this.placeholder = Ten.Element('span', { className: 'placeholder' }, text.getAttribute('placeholder'));
        this.blurHandler();
        this.text.parentNode.insertBefore(this.placeholder, this.text);
        new Ten.Observer(this.text, 'onfocus', this, 'focusHandler');
        new Ten.Observer(this.text, 'onblur', this, 'blurHandler');
        new Ten.Observer(this.placeholder, 'onclick', this, 'clickHandler');
    }
}, {
    focusHandler: function () {
        this.placeholder.style.display = 'none';
    },
    blurHandler: function () {
        this.placeholder.style.display = this.text.value ? 'none' : '';
    },
    clickHandler: function () {
        this.text.focus();
    }
});

Hatena.XxxxxXxxxxx.PlaceHolder

<input type="text" class="placeholder" id="comment-container" value="コメント" />
new Hatena.XxxxxXxxxxx.PlaceHolder(commentContainer, 'コメント');
Hatena.XxxxxXxxxxx.PlaceHolder = new Ten.Class ({
    initialize: function($, placeholder, className) {
        this.placeholder = placeholder;
        this.className = className || 'placeholder';

        var self = this;
        $.focus(function(e) { self.focus(e.target); });
        $.focusout(function(e) { self.focusout(e.target); });
        $.each(function(i, e) {
            e.getText = function() {
                if (Ten.DOM.hasClassName(e, self.className) &&
                    e.value === self.placeholder) {
                    return '';
                }
                else {
                    return e.value;
                }
            }
        });
    }
}, {
    focus: function(e) {
        if (Ten.DOM.hasClassName(e, this.className)) {
            e.value = '';
        }
    },

    focusout: function(e) {
        if (e.value === '') {
            Ten.DOM.addClassName(e, this.className);
            e.value = this.placeholder;
        }
        else {
            Ten.DOM.removeClassName(e, this.className);
        }
    }
});

jQuery Placeholder by Michael J. Ryan

$(input.data(phl))
	.css('top', input.position().top + 'px')
	.css('left', input.position().left + 'px')
	.css('display', !!input.val() ? 'none' : 'block');

jQuery Placeholder Plugin by Paul Mucur

Conclusions

Thank You