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 相关文章推荐
IE JS编程需注意的内存释放问题
Jun 23 Javascript
JQuery下关于$.Ready()的分析
Dec 13 Javascript
js中查找最近的共有祖先元素的实现代码
Dec 30 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
Oct 12 Javascript
javascript实现日历控件(年月日关闭按钮)
Dec 12 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
Dec 20 Javascript
关于JavaScript对象的动态选择及遍历对象
Mar 10 Javascript
javascript中的深复制详解及实例分析
Dec 29 Javascript
关于Vue Webpack2单元测试示例详解
Aug 14 Javascript
React Native之TextInput组件解析示例
Aug 22 Javascript
bootstrap table sum总数量统计实现方法
Oct 29 Javascript
JavaScript引用类型Date常见用法实例分析
Aug 08 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
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
PHP 5.0对象模型深度探索之属性和方法
2008/03/27 PHP
php时间戳转换的示例
2014/03/31 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
PHP防止注入攻击实例分析
2014/11/03 PHP
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
php根据年月获取当月天数及日期数组的方法
2016/11/30 PHP
PHP 中使用explode()函数切割字符串为数组的示例
2017/05/06 PHP
php写入mysql中文乱码的实例解决方法
2019/09/17 PHP
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
MSN消息提示类
2006/09/05 Javascript
dtree 网页树状菜单及传递对象集合到js内,动态生成节点
2012/04/14 Javascript
jqueyr判断checkbox组的选中(示例代码)
2013/11/08 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
2014/06/10 Javascript
javascript文本模板用法实例
2015/07/31 Javascript
轻松掌握JavaScript中的Math object数学对象
2016/05/26 Javascript
gulp-uglify 与gulp.watch()配合使用时报错(重复压缩问题)
2016/08/24 Javascript
Angular将填入表单的数据渲染到表格的方法
2017/09/22 Javascript
js最简单的双向绑定实例讲解
2018/01/02 Javascript
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】
2018/05/26 jQuery
python实现发送和获取手机短信验证码
2016/01/15 Python
Java分治归并排序算法实例详解
2017/12/12 Python
django admin添加数据自动记录user到表中的实现方法
2018/01/05 Python
python获取酷狗音乐top500的下载地址 MP3格式
2018/04/17 Python
Python实现账号密码输错三次即锁定功能简单示例
2019/03/29 Python
python 有效的括号的实现代码示例
2019/11/11 Python
使用CSS3的appearance属性改变元素的外观的方法
2015/12/12 HTML / CSS
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
Melissa鞋英国官方网站:Nonnon
2019/05/01 全球购物
班组长安全生产职责
2013/12/16 职场文书
四川成都导游欢迎词
2014/01/18 职场文书
电力安全事故反思
2014/04/27 职场文书
2014年酒店年度工作总结
2014/12/10 职场文书
工作态度恶劣检讨书
2015/05/06 职场文书
致运动员加油稿
2015/07/21 职场文书
windows安装python超详细图文教程
2021/05/21 Python