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 验证表单(form)中的单选(radio)值
Sep 08 Javascript
浅谈tudou土豆网首页图片延迟加载的效果
Jun 23 Javascript
Jquery优化效率 提升性能解决方案
Sep 06 Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
Jan 25 Javascript
Jquery仿淘宝京东多条件筛选可自行结合ajax加载示例
Aug 28 Javascript
JQuery中使用on方法绑定hover事件实例
Dec 09 Javascript
jquery实现点击展开列表同时隐藏其他列表
Aug 10 Javascript
基于jquery实现全屏滚动效果
Nov 26 Javascript
JS基于面向对象实现的拖拽功能示例
Dec 20 Javascript
JS使用ActiveXObject实现用户提交表单时屏蔽敏感词功能
Jun 20 Javascript
在Vue中获取组件声明时的name属性方法
Sep 12 Javascript
在pycharm中开发vue的方法步骤
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父类调用子类方法的代码例子
2014/04/09 PHP
php加速器eAccelerator的配置参数、API详解
2014/05/05 PHP
php使用mysqli和pdo扩展,测试对比mysql数据库的执行效率完整示例
2019/05/09 PHP
php array_chunk()函数用法与注意事项
2019/07/12 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
CSS中一些@规则的用法小结
2021/03/09 HTML / CSS
js判断是否为数组的函数: isArray()
2011/10/30 Javascript
深入剖析JavaScript中的枚举功能
2014/03/06 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
2014/11/12 Javascript
javascript事件模型实例分析
2015/01/30 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
2015/08/26 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
JS提示:Uncaught SyntaxError: Unexpected token ILLEGAL错误的解决方法
2016/08/19 Javascript
JavaScript 引用类型实例详解【数组、对象、严格模式等】
2020/05/13 Javascript
Python实现的多线程http压力测试代码
2017/02/08 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
pyspark 读取csv文件创建DataFrame的两种方法
2018/06/07 Python
python调用摄像头显示图像的实例
2018/08/03 Python
Windows下PyCharm安装图文教程
2018/08/27 Python
python实现指定ip端口扫描方式
2019/12/17 Python
Pycharm+Python工程,引用子模块的实现
2020/03/09 Python
python使用PIL剪切和拼接图片
2020/03/23 Python
canvas实现烟花的示例代码
2020/01/16 HTML / CSS
大三预备党员入党思想汇报
2014/01/08 职场文书
档案接收函范文
2014/01/10 职场文书
常务副总经理岗位职责
2014/04/12 职场文书
工地门卫岗位职责范本
2014/07/01 职场文书
励志演讲稿200字
2014/08/21 职场文书
档案工作汇报材料
2014/08/21 职场文书
2014年乡镇纪委工作总结
2014/12/19 职场文书
采购内勤岗位职责
2015/04/13 职场文书
2015年支教教师工作总结
2015/07/22 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python
mysql数据库入门第一步之创建表
2021/05/14 MySQL