placeHolder随想
html5的placeholder属性功能很好用,可以给表单元素添加一个tip,通常之前都是使用js去做,现在它的出现让一部分的浏览器摆脱了js的困扰。
比如:
<input type="text" placeholder="我是一个测试tip" />
上面是一个demo,你在支持该属性的浏览器上就可以看到效果,比如chrome,但是ie系列就全军覆没了,甚至是IE9。
那在不支持该属性的浏览器下怎么实现呢?
google出的很多教程使用了很简单的一段js。
placeholder : function(placeholderClassName, attributeName) {
$("input").each(function() {
var $this = $(this);
if ($this.attr(attributeName) != undefined) {
// deactivate placeholder
$this.focus(function() {
if ($this.val() == $this.attr(attributeName)) {
$this.removeClass(placeholderClassName);
$this.val("");
}
});
// activate placeholder
$this.blur(function() {
if ($this.val() == "") {
$this.addClass(placeholderClassName);
$this.val($this.attr(attributeName));
}
});
// initialize placeholder
$this.blur();
}
});
}
当然这是基于jquey的,原理大概是:
1、初始化时填入placeholder属性的值到value
2、focus时删除value的值
3、blur的时候如果填入的值如果为空则回填placeholder的值
但是这样处理会有几个问题:
1、初始化的时候表单如果默认有值会变成覆盖的情况
2、表单提交会把placeholder的值提交上去
3、reset时没做处理
我们可以用一种更好的方式去实现,使用label。
<div style="position: relative;" class="placeholder">
<label>选填,可以告诉卖家您的特殊要求</label>
<textarea id="guestbook" name="guestbook" placeholder="选填,可以告诉卖家您的特殊要求"></textarea>
</div>
当然,为了保持和html5的兼容性,外面的label和div需要使用js动态创建。
kissy实现:
KISSY.add('util/placeholder', function(S) {
var D = S.DOM, E = S.Event;
/**
* config{
* el:{HtmlElement}目标表单元素
* wrap: {Boolean} default true 需要创建一个父容器
* }
*
* 支持两种方式:
* 1、html5的placeholder属性
* 2、其他浏览器的支持
*/
function placeholder(el, cfg) {
var isSupport = "placeholder" in document.createElement("input"),
self = this;
//支持html5的placeHolder属性
if(isSupport) return;
var defaultCfg = {
wrap:true
};
if(self instanceof placeholder) {
var config = S.merge(defaultCfg, cfg);
self._init(el, config);
} else {
return new placeholder(el, cfg);
}
}
S.augment(placeholder, {
_init:function(target, cfg) {
var self = this;
if(!target) {
S.log('[placeholder] has no target to decorate');
}
target = S.one(target);
var placeHolderTip = target.attr('placeholder');
if(!placeHolderTip) return;
self._decorate = function() {
//创建一个label
var triggerLabel = self.triggerLabel = D.create(S.substitute('<label style="display: none">{tip}</label>', {
tip:placeHolderTip
}));
if(target.attr('id')) {
D.attr(triggerLabel, 'for', target.attr('id'));
} else {
S.one(triggerLabel).on('click', function() {
target[0].focus();
});
}
//create parent
if(cfg.wrap) {
var targetBox = D.create('<div class="placeholder" style="position: relative"></div>');
S.one(targetBox).appendTo(target.parent()).append(target);
}
//insertbefore target
D.insertBefore(triggerLabel, target);
//judge value && init form reset
S.later(function() {
if(!target.val()) {
D.show(triggerLabel);
}
}, 100);
};
target.on('focus', function(ev) {
D.hide(self.triggerLabel);
});
target.on('blur', function(ev) {
if(!target.val()) {
D.show(self.triggerLabel);
}
});
self._decorate();
},
/**
* 可以修改tip文案
* @param newTip
*/
text:function(newTip) {
D.text(this.triggerLabel, newTip);
}
});
//1.1.6 support
S.namespace("Util");
S.Util.placeholder = placeholder;
return placeholder;
});
reset处理好像做不了。。汗。。