jQuery实现的一个自定义Placeholder属性插件


Posted in Javascript onAugust 11, 2014

HTML5中文本框的新属性placeholder是个非常好用的属性,但是IE系列直至IE9都不支持这一属性,这就让大家在用这一属性的时候有些犹豫不决。自己曾经写过很多类似共的小控件,但是都不是很通用,这里分享一个渐进增强的自定义placeholder的jQuery插件。有点是使用简单,大家也可以根据自己的需要进行改进。平常写jQuery插件比较少,考虑到用jQuery的同学比较多,这里就用jQuery插件的形式编写了。

在这里简单的介绍一下实现思路。

1.表现与html5原生的placeholder尽量类似
2.渐进增强对于支持placeholder的浏览器不做处理

一、首先是几个工具方法:

1.supportProperty(nodeType, property),获取浏览器是否支持某一控件的某一属性
2.getPositionInDoc(target, parent),获取对象在文档中的位置
3.$c,一个快速创建Dom对象的方法

这几个工具方法都是一些比较常见通用的方法,如果你有自己的或者更合适的可以自行替换。

二、主体,CustomPlaceholder对象。这个对象主要是维护每一个文本框的信息,包括其位置,应该显示的提示信息等等,另外它还包含创建提示信息以及定位等方法以及对象的相应事件。

事件主要是在initEvents函数中进行的处理,这里特别要注意的是对提示信息事件的处理,当提示信息被点击时焦点应该被重新定位到文本框。而文本框要处理的则是focus和blur事件。

$(self.hint).bind( 'click', function(e){

 self.input.focus();

});
$(self.input).bind( 'focus', function(e){

 self.hint.style.display = 'none';

});
$(self.input).bind( 'blur', function(e){

 if(this.value == ''){

  self.hint.style.display = 'inline';

 }

});

CustomPlacehodler对象的两个主要方法是createHintLabel(text, position)和position()。createHintLabel是用于创建提示信息的DOM对象并对其进行定位,并返回这个对象。position方法用于强制对提示消息进行重新定位。主要用于页面大小改变的情况。这两个方法的功能和实现都比较简单。

三、插件的功能实现部分。jQuery插件实现方式就不多说了。这里首先进行了能力检测,如果原生支持placeholder则直接返回。

if(supportProperty('input', 'placeholder')){

 return;

}

接下来是根据选择的input对象,生成相应的CustomPlaceholder对象,保存在数组中,并获取每个对象的提示信息的DOM对象,添加到容器中,最后将容器附加到body对象中。

var customPlaceholders = [];

if(this.length > 0){

 var box = $c('div', 'dk_placeholderfixed_box');

 for(var i = 0, len = this.length; i < len; i++){

  var input = this[i];

  customPlaceholders.push(new CustomPlaceholder(box, input, option));

 }
 document.body.appendChild(box);

}

最后还有一件比较重要的事情,为window对象绑定resize事件,当window对象触发resize事件时对所有的customPlacehoder对象进行重新定位。

$(window).bind( 'resize', function(e){

 for(var i = 0, len = customPlaceholders.length; i < len; i++){

  var customPlaceholder = customPlaceholders[i];

  customPlaceholder.position();

 }
});

这个简单的小插件到这里就写完了。

插件源码:

(function($){

var eles = {
	div: document.createElement('div'),
	ul: document.createElement('ul'),
	li: document.createElement('li'),
	span: document.createElement('span'),
	p: document.createElement('p'),
	a: document.createElement('a'),
	fragment: document.createDocumentFragment(),
	input: document.createElement('input')
}
	
var supportProperty = function(nodeType, property){
	switch(arguments.length){
		case 0:
			return false;
		case 1:
			var property = nodeType, nodeType = 'div';
			property = property.split('.');
			
			if(property.length == 1){
				return typeof eles[nodeType][property[0]] !== 'undefined';
			}else if(property.length == 2){
				return typeof eles[nodeType][property[0]][property[1]] !== 'undefined';
			}
		case 2:
			property = property.split('.');
			
			if(property.length == 1){
				return typeof eles[nodeType][property[0]] !== 'undefined';
			}else if(property.length == 2){
				return typeof eles[nodeType][property[0]][property[1]] !== 'undefined';
			}
			
			return false;
			
			
		default:
			return false;
	}
};

var getPositionInDoc = function(target, parent) {
	if (!target) {
		return null;
	}
	var left = 0,
		top = 0;
	do {
		left += target.offsetLeft || 0;
		top += target.offsetTop || 0;
		target = target.offsetParent;
		if(parent && target == parent){
			break;
		}
	} while (target);
	return {
		left: left,
		top: top
	};
}

var $c = function(tagName, id, className){
	var ele = null;
	if(!eles[tagName]){
		ele = eles[tagName] = document.createElement(tagName);
	}else{
		ele = eles[tagName].cloneNode(true);
	}
	if(id){
		ele.id = id;
	}
	if(className){
		ele.className = className;
	}
	return ele;
};
	
var CustomPlaceholder = function(box, input, option){
	var self = this;
	var position = getPositionInDoc(input);
	self.input = input;
	
	self.option = {xOffset:0, yOffset:0};
	for(var item in option){
		self.option[item] = option[item];
	}
	self.hint = self.createHintLabel(input.getAttribute('placeholder'), position);
	box.appendChild(self.hint);
	
	self.initEvents = function(){
		$(self.hint).bind( 'click', function(e){
			self.input.focus();
		});
		
		$(self.input).bind( 'focus', function(e){
			self.hint.style.display = 'none';
		});
		
		$(self.input).bind( 'blur', function(e){
			if(this.value == ''){
				self.hint.style.display = 'inline';
			}
		});
	};
	
	self.initEvents();
};

CustomPlaceholder.prototype = {
	createHintLabel: function(text, position){
		var hint = $c('label');
		hint.style.cusor = 'text';
		hint.style.position = 'absolute';
		hint.style.left = position.left + this.option.xOffset + 'px';
		hint.style.top = position.top + this.option.yOffset + 'px';
		hint.innerHTML = text;
		hint.style.zIndex = '9999';
		return hint;
	},
	position: function(){
		var position = getPositionInDoc(this.input);
		this.hint.style.left = position.left + this.option.xOffset + 'px';
		this.hint.style.top = position.top + this.option.yOffset + 'px';
	}
};

$.fn.placeholder = function(option){
	if(supportProperty('input', 'placeholder')){
		return;
	}
	var customPlaceholders = [];
	if(this.length > 0){
		var box = $c('div', 'dk_placeholderfixed_box');
		for(var i = 0, len = this.length; i < len; i++){
			var input = this[i];
			if($(input).is(':visible')){
				customPlaceholders.push(new CustomPlaceholder(box, input, option));
			}
		}
		
		document.body.appendChild(box);
	}
	
	$(window).bind( 'resize', function(e){
		for(var i = 0, len = customPlaceholders.length; i < len; i++){
			var customPlaceholder = customPlaceholders[i];
			customPlaceholder.position();
		}
		
	});
};

})(jQuery);
Javascript 相关文章推荐
JavaScript CSS修改学习第一章 查找位置
Feb 19 Javascript
文本框中,回车键触发事件的js代码[多浏览器兼容]
Jun 07 Javascript
jQuery bxCarousel实现图片滚动切换效果示例代码
May 15 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
node.js中的require使用详解
Dec 15 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
Feb 13 Javascript
Bootstrap每天必学之附加导航(Affix)插件
Apr 25 Javascript
常用的js方法合集
Mar 10 Javascript
jQuery插件FusionCharts实现的Marimekko图效果示例【附demo源码】
Mar 24 jQuery
JS创建Tag标签的方法详解
Jun 09 Javascript
vue脚手架搭建项目的兼容性配置详解
Jul 17 Javascript
JavaScript 与 TypeScript之间的联系
Nov 27 Javascript
javascript中解析四则运算表达式的算法和示例
Aug 11 #Javascript
javascript实现的平方米、亩、公顷单位换算小程序
Aug 11 #Javascript
jquery访问ashx文件示例代码
Aug 11 #Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
Aug 10 #Javascript
JavaScript动态改变HTML页面元素例如添加或删除
Aug 10 #Javascript
网页运行时提示对象不支持abigimage属性或方法
Aug 10 #Javascript
js中直接声明一个对象的方法
Aug 10 #Javascript
You might like
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
PHP统计目录大小的自定义函数分享
2014/11/18 PHP
Smarty foreach控制循环次数的一些方法
2015/07/01 PHP
Zend Framework入门教程之Zend_View组件用法示例
2016/12/09 PHP
js实现权限树的更新权限时的全选全消功能
2009/02/17 Javascript
jquery 实现的全选和反选
2009/04/15 Javascript
JS实现简洁、全兼容的拖动层实例
2015/05/13 Javascript
理解JavaScript事件对象
2016/01/25 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
2017/02/22 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
每周一练 之 数据结构与算法(Stack)
2019/04/16 Javascript
js实现随机点名程序
2020/09/17 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
Vue实现穿梭框效果
2020/09/30 Javascript
[05:39]2014DOTA2西雅图国际邀请赛 淘汰赛7月14日TOPPLAY
2014/07/14 DOTA
简单的编程0基础下Python入门指引
2015/04/01 Python
Python实现身份证号码解析
2015/09/01 Python
python中的单引号双引号区别知识点总结
2019/06/23 Python
详解Python高阶函数
2020/08/15 Python
Python 带星号(* 或 **)的函数参数详解
2021/02/23 Python
HTML5 Canvas像素处理使用接口介绍
2012/12/02 HTML / CSS
美国开幕式潮店:Opening Ceremony
2018/02/10 全球购物
香港通票:Hong Kong Pass
2019/02/26 全球购物
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
汽车检测与维修专业求职信
2013/10/30 职场文书
工商企业管理应届生求职信
2013/11/03 职场文书
医学专业本科毕业生自我鉴定
2013/12/28 职场文书
培训演讲稿范文
2014/01/12 职场文书
会计职业生涯规划书
2014/01/13 职场文书
庆中秋节主题活动方案
2014/02/03 职场文书
测控技术自荐信
2014/06/05 职场文书
动物科学专业求职信
2014/07/27 职场文书
先进班集体申报材料
2014/12/26 职场文书
2015年物资管理工作总结
2015/05/20 职场文书
nginx基于域名,端口,不同IP的虚拟主机设置的实现
2021/03/31 Servers
PyTorch中的torch.cat简单介绍
2022/03/17 Python