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 相关文章推荐
js压缩利器
Feb 20 Javascript
JS获取url链接字符串 location.href
Dec 23 Javascript
jQuery中click事件用法实例
Dec 26 Javascript
js实现顶部可折叠的菜单工具栏效果实例
May 09 Javascript
jQuery获取及设置表单input各种类型值的方法小结
May 24 Javascript
js定时器实例分享
Dec 20 Javascript
jQuery实现简单漂亮的Nav导航菜单效果
Mar 29 jQuery
angularjs 获取默认选中的单选按钮的value方法
Feb 28 Javascript
了解ESlint和其相关操作小结
May 21 Javascript
解决vue中post方式提交数据后台无法接收的问题
Aug 11 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
Jan 08 Javascript
JS使用栈判断给定字符串是否是回文算法示例
Mar 04 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
用PHP编程语言开发动态WAP页面
2006/10/09 PHP
php数组(array)输出的三种形式详解
2013/06/05 PHP
浅谈php自定义错误日志
2015/02/13 PHP
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
2020/08/03 PHP
newxtree.js代码
2007/03/13 Javascript
JavaScript实现三阶幻方算法谜题解答
2014/12/29 Javascript
javascript实现tab切换的四种方法
2015/11/05 Javascript
AngularJS directive返回对象属性详解
2016/03/28 Javascript
Bootstrap编写导航栏和登陆框
2016/05/30 Javascript
原生js仿淘宝网商品放大镜效果
2017/02/28 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
Angular 4.x中表单Reactive Forms详解
2017/04/25 Javascript
js中变量的连续赋值(实例讲解)
2017/07/08 Javascript
vue页面切换到滚动页面显示顶部的实例
2018/03/13 Javascript
JavaScript实现点击出现图片并统计点击次数功能示例
2018/07/23 Javascript
详解JavaScript事件循环机制
2018/09/07 Javascript
从表单校验看JavaScript策略模式的使用详解
2020/10/17 Javascript
jQuery插件实现图片轮播效果
2020/10/19 jQuery
[52:05]EG vs OG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python中使用Queue和Condition进行线程同步的方法
2016/01/19 Python
python 捕获 shell/bash 脚本的输出结果实例
2017/01/04 Python
python list删除元素时要注意的坑点分享
2018/04/18 Python
Python基本socket通信控制操作示例
2019/01/30 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
党委书记岗位职责
2013/11/24 职场文书
五年级音乐教学反思
2014/02/06 职场文书
《三个小伙伴》教学反思
2014/04/11 职场文书
幼儿园安全责任书
2014/04/14 职场文书
俞敏洪北大演讲稿
2014/05/22 职场文书
怎样写离婚协议书
2014/09/10 职场文书
讲文明懂礼貌演讲稿
2014/09/11 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
刑事撤诉申请书
2015/05/18 职场文书
个人欠条范本
2015/07/03 职场文书
《最后一头战象》教学反思
2016/02/16 职场文书
Python实现生成bmp图像的方法
2021/06/13 Python