让你的网页文本框增加光晕效果(类似QQ2011)
我们都知道默认的Asp.Net文本框很丑陋的,看到QQ2011版的登录输入文本框那种光晕效果,不免让我们很是向往,不过我查看了源码却发现是通过C++实现的,那如何在我们的Asp.Net中添加同样的功能呢?先给大家秀一下我的运行截图:
默认文本框样式:
鼠标移入文本框:
是不是很酷呢?下面我将一一解释如何做出来的?首先我们建立一个WebSite应用程序。在开始做之前建立一个文件夹plugins/textbox并引入Jquery库,在textbox子文件夹下再添加一个images文件夹(包含一张背景图:border.png),大概的文件夹结构应该如下:
接着我们开始设计粗略版的html结构,大致如下:
<div class='span'>姓名</div>
<div class='aq_box'>
<div class='aq_box_wrap'>
<input type="text" id="name" class="textbox" label="姓名" />
</div>
</div>
很简单把,我们发现其中有几个地方包含了class以及伪属性label,但是根据我的想法,希望将它做成插件,给用户调用,这样就很方便了。我先给出调用代码和html结构:
<head>
<title></title>
<link href="jquey.textbox.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="jquery.textbox.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#name").textbox();
});
</script>
</head>
<body>
<input type="text" id="name" class="textbox" label="姓名" />
</body>
是不是调用更简单了,封装的足够好了把。接下来,我将带大家编写更为关键的CSS和JQuery插件。
首先看插件,由于功能需求不妨命名为jquery.textbox.js:
(function ($) {
$.addTextBox = function (t, p) {
p = $.extend({
width: 174
}, p);
var span = $.trim($(t).attr("label"));
if (span != "") {
$(t).before("<div class='span'>" + span + "</div>");
}
$(t).wrap("<div class='aq_box'><div class='aq_box_wrap'></div></div>")
.parents(".aq_box")
.siblings().removeClass("hover").end()
.hover(function () {
$(this).toggleClass("hover");
}, function () {
$(this).toggleClass("hover");
})
.find(".textbox").width(p.width);
};
var docloaded = false;
$(document).ready(function () {
docloaded = true
});
$.fn.textbox = function (p) {
return this.each(function () {
if (!docloaded) {
var t = this;
$(document).ready(function () {
$.addTextBox(t, p);
});
} else {
$.addTextBox(this, p);
}
});
}; //end textbox
})(jQuery);
对插件中应用的样式文件(jquery.textbox.css)在以下:
.span
{
padding: 3px 2px 0 0;
float: left;
display: inline;
}
.textbox
{
border: 0px;
height: 22px;
line-height: 22px;
overflow: hidden;
background: url(images/border.png) 0 -72px repeat-x;
}
.aq_box
{
padding-left: 3px;
background: url(images/border.png) left -24px no-repeat;
float: left;
}
.aq_box_wrap
{
padding-right: 3px;
background: url(images/border.png) right -24px no-repeat;
}
.aq_box.hover
{
background-position: left top;
}
.aq_box.hover .aq_box_wrap
{
background-position: right top;
}
.aq_box.hover .textbox
{
background-position: 0 -48px;
}
另外,我将背景图片(border.png)也贴上来,
这些准备工作做完之后,你就可以去浏览这些美妙的效果了。其实,这个功能还有很多改进的地方,比如可以添加水印,添加tooltip效果,添加搜索图标,添加键盘图标等等。我将在以后的插件开发中继续更新和完善,欢迎大家一起来欣赏。有兴趣的朋友在这里下载新版源码(解压后可以打开demo.htm欣赏效果)。
继续完善网页文本框系列之二(增加水印和提示)
在上一次我设计了一个带光晕的文本框,类似于QQ2011,给我们的网页增加了美感和动感。最后,我留给大家的是对文本框的继续优化,这次我增加了水印效果和提示效果。可能很多人说这些在Jquery中已经有内置插件了,为什么还需要自己去写呢?我历来的标准是:“拿来主义”分情况。对于已经满足我们要求且易于配置的的插件,我们直接拿来用就是。但是对于不能满足我们要求且本身已经很复杂的插件,则更愿意自己动手去写,以便了解整个插件的设计流程。下面就不废话了,先来看水印吧。我们设想了一个最简单的例子就是普通的文本框(<input type='text' id='txtName' value=''>),不外乎就是出发textbox的focus和blur事件作出不同的响应。以下是主要的文件结构和主要代码:
jquery.watermark.1.0.js:
(function ($) {
$.fn.watermark = function (defaultText) {
return this.each(function () {
var $this = $(this);
var text = $this.val();
if (defaultText) {
text = defaultText;
$this.val(text).addClass("watermark");
}
$this.focus(function () {
if ($this.val() == defaultText) {
$this.val('').removeClass("watermark");
}
}).blur(function () {
if ($this.val() == '') {
$this.val(defaultText).addClass("watermark");
}
});
});
}
})(jQuery);
注意其中有一个css效果,watermark:
.span
{
padding: 3px 2px 0 0;
float: left;
display: inline;
}
.textbox
{
border: 0px;
height: 22px;
line-height: 22px;
overflow: hidden;
background: url(images/border.png) 0 -72px repeat-x;
}
.aq_box
{
padding-left: 3px;
background: url(images/border.png) left -24px no-repeat;
float: left;
}
.aq_box_wrap
{
padding-right: 3px;
background: url(images/border.png) right -24px no-repeat;
}
.aq_box.hover
{
background-position: left top;
}
.aq_box.hover .aq_box_wrap
{
background-position: right top;
}
.aq_box.hover .textbox
{
background-position: 0 -48px;
}
.watermark
{
color: #999;
}
当插件写好之后,我们开始应用这个插件,前台页面如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="[path]/Scripts/plugins/textbox/textbox.css" rel="stylesheet" type="text/css" />
</head>
<body>
<input type="text" id="name" class="textbox" /><br />
<br />
<input type="password" id="password" class="textbox" />
<script src="[path]/Scripts/plugins/textbox/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="[path]/Scripts/plugins/textbox/jquery.textbox.js" type="text/javascript"></script>
<script src="[path]/Scripts/plugins/textbox/jquery.watermark.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#name").textbox().watermark("用户名");
$("#password").textbox().watermark("密码");
});
</script>
</body>
</html>
当运行之后你就可以看到效果:
默认以及鼠标离开(未填写任何值)的效果:
鼠标进入后的效果:
当填写文字之后的效果:
是不是很完美呢?但是我们发现密码那个框就没有这么幸运了,它的水印文字却变成了黑点,如下图:
怎么办呢?我们需要扩展我们的水印插件以支持密码水印效果。细想一下,我们可以发现密码框和文本框除了type不一致,其他均为一样的。此时,我们设想以做好的文本框作支撑,辅助实现密码水印效果。目标是动态配置一个与密码等宽登高的文本框来实现和密码框的切换(在focus和blur事件中)。由于需要支持以前的插件,因此我们单独对密码框来进行处理,我们可以通过以下语句来筛选密码框:
var ispwd = $this.attr("type").toLowerCase() == "password";
以下是我扩展以后支持密码框的水印效果(注意高亮处): jquery.watermark.1.1.js:
(function ($) {
$.fn.watermark = function (defaultText) {
return this.each(function () {
var $this = $(this);
var ispwd = $this.attr("type").toLowerCase() == "password";
var text = $this.val();
if (defaultText) {
text = defaultText;
if (ispwd) {
var tb = $("<input type='text' class='textbox'/>");
$this.hide().parent().append(tb.addClass("watermark").width($this.width()).val(text));
} else {
$this.val(text).addClass("watermark");
}
}
if (ispwd) {
$this.next().focus(function () {
if ($this.next().val() == defaultText) {
$this.next().hide().end().show().focus();
}
}).end().blur(function () {
if ($this.val() == '') {
$this.hide().next().show();
}
});
} else {
$this.focus(function () {
if ($this.val() == defaultText) {
$this.val('').removeClass("watermark");
}
}).blur(function () {
if ($this.val() == '') {
$this.val(defaultText).addClass("watermark");
}
});
}
});
}
})(jQuery);
做了这些工作后,再次运行之前的页面,你会发觉密码水印效果变成了这个样子:
当输入密码时,密码框变成:
这样就完美实现文本框和密码框的水印效果了。接下来,我们继续探讨提示的实现效果,其实这个功能已经在jquery中实现,其原理是:设置元素的title属性,然后以div浮动的形式来展现。
(function($){
$.fn.tooltip = function(options) {
var defaults = {
activation: "hover",
keepAlive: false,
maxWidth: "200px",
edgeOffset: 3,
defaultPosition: "bottom",
delay: 400,
fadeIn: 200,
fadeOut: 200,
attribute: "title",
content: false, // HTML or String to fill TipTIp with
enter: function(){},
exit: function(){}
};
var opts = $.extend(defaults, options);
// Setup tip tip elements and render them to the DOM
if($("#tiptip_holder").length <= 0){
var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>');
var tiptip_content = $('<div id="tiptip_content"></div>');
var tiptip_arrow = $('<div id="tiptip_arrow"></div>');
$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')));
} else {
var tiptip_holder = $("#tiptip_holder");
var tiptip_content = $("#tiptip_content");
var tiptip_arrow = $("#tiptip_arrow");
}
return this.each(function(){
var org_elem = $(this);
if(opts.content){
var org_title = opts.content;
} else {
var org_title = org_elem.attr(opts.attribute);
}
if(org_title != ""){
if(!opts.content){
org_elem.removeAttr(opts.attribute); //remove original Attribute
}
var timeout = false;
if(opts.activation == "hover"){
org_elem.hover(function(){
active_tiptip();
}, function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
} else if(opts.activation == "focus"){
org_elem.focus(function(){
active_tiptip();
}).blur(function(){
deactive_tiptip();
});
} else if(opts.activation == "click"){
org_elem.click(function(){
active_tiptip();
return false;
}).hover(function(){},function(){
if(!opts.keepAlive){
deactive_tiptip();
}
});
if(opts.keepAlive){
tiptip_holder.hover(function(){}, function(){
deactive_tiptip();
});
}
}
function active_tiptip(){
opts.enter.call(this);
tiptip_content.html(org_title);
tiptip_holder.hide().removeAttr("class").css("margin","0");
tiptip_arrow.removeAttr("style");
var top = parseInt(org_elem.offset()['top']);
var left = parseInt(org_elem.offset()['left']);
var org_width = parseInt(org_elem.outerWidth());
var org_height = parseInt(org_elem.outerHeight());
var tip_w = tiptip_holder.outerWidth();
var tip_h = tiptip_holder.outerHeight();
var w_compare = Math.round((org_width - tip_w) / 2);
var h_compare = Math.round((org_height - tip_h) / 2);
var marg_left = Math.round(left + w_compare);
var marg_top = Math.round(top + org_height + opts.edgeOffset);
var t_class = "";
var arrow_top = "";
var arrow_left = Math.round(tip_w - 12) / 2;
if(opts.defaultPosition == "bottom"){
t_class = "_bottom";
} else if(opts.defaultPosition == "top"){
t_class = "_top";
} else if(opts.defaultPosition == "left"){
t_class = "_left";
} else if(opts.defaultPosition == "right"){
t_class = "_right";
}
var right_compare = (w_compare + left) < parseInt($(window).scrollLeft());
var left_compare = (tip_w + left) > parseInt($(window).width());
if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){
t_class = "_right";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = -12;
marg_left = Math.round(left + org_width + opts.edgeOffset);
marg_top = Math.round(top + h_compare);
} else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){
t_class = "_left";
arrow_top = Math.round(tip_h - 13) / 2;
arrow_left = Math.round(tip_w);
marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5));
marg_top = Math.round(top + h_compare);
}
var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop());
var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0;
if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_top";
} else {
t_class = t_class+"_top";
}
arrow_top = tip_h;
marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset));
} else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){
if(t_class == "_top" || t_class == "_bottom"){
t_class = "_bottom";
} else {
t_class = t_class+"_bottom";
}
arrow_top = -12;
marg_top = Math.round(top + org_height + opts.edgeOffset);
}
if(t_class == "_right_top" || t_class == "_left_top"){
marg_top = marg_top + 5;
} else if(t_class == "_right_bottom" || t_class == "_left_bottom"){
marg_top = marg_top - 5;
}
if(t_class == "_left_top" || t_class == "_left_bottom"){
marg_left = marg_left + 5;
}
tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"});
tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class);
if (timeout){ clearTimeout(timeout); }
timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay);
}
function deactive_tiptip(){
opts.exit.call(this);
if (timeout){ clearTimeout(timeout); }
tiptip_holder.fadeOut(opts.fadeOut);
}
}
});
}
})(jQuery);
#tiptip_holder
{
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 99999;
}
#tiptip_holder.tip_top
{
padding-bottom: 5px;
}
#tiptip_holder.tip_bottom
{
padding-top: 5px;
}
#tiptip_holder.tip_right
{
padding-left: 5px;
}
#tiptip_holder.tip_left
{
padding-right: 5px;
}
#tiptip_content
{
font-size: 11px;
color: #fff;
text-shadow: 0 0 2px #000;
padding: 4px 8px;
border: 1px solid rgba(255,255,255,0.25);
background-color: #191919;
background-color: rgba(25,25,25,0.92);
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000));
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
box-shadow: 0 0 3px #555;
-webkit-box-shadow: 0 0 3px #555;
-moz-box-shadow: 0 0 3px #555;
}
#tiptip_arrow, #tiptip_arrow_inner
{
position: absolute;
border-color: transparent;
border-style: solid;
border-width: 6px;
height: 0;
width: 0;
}
#tiptip_holder.tip_top #tiptip_arrow
{
border-top-color: #fff;
border-top-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_bottom #tiptip_arrow
{
border-bottom-color: #fff;
border-bottom-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_right #tiptip_arrow
{
border-right-color: #fff;
border-right-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_left #tiptip_arrow
{
border-left-color: #fff;
border-left-color: rgba(255,255,255,0.35);
}
#tiptip_holder.tip_top #tiptip_arrow_inner
{
margin-top: -7px;
margin-left: -6px;
border-top-color: #191919;
border-top-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_bottom #tiptip_arrow_inner
{
margin-top: -5px;
margin-left: -6px;
border-bottom-color: #191919;
border-bottom-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_right #tiptip_arrow_inner
{
margin-top: -6px;
margin-left: -5px;
border-right-color: #191919;
border-right-color: rgba(25,25,25,0.92);
}
#tiptip_holder.tip_left #tiptip_arrow_inner
{
margin-top: -6px;
margin-left: -7px;
border-left-color: #191919;
border-left-color: rgba(25,25,25,0.92);
}
/* Webkit Hacks */
@media screen and (-webkit-min-device-pixel-ratio:0)
{
#tiptip_content
{
padding: 4px 8px 5px 8px;
background-color: rgba(45,45,45,0.88);
}
#tiptip_holder.tip_bottom #tiptip_arrow_inner
{
border-bottom-color: rgba(45,45,45,0.88);
}
#tiptip_holder.tip_top #tiptip_arrow_inner
{
border-top-color: rgba(20,20,20,0.92);
}
}
当做完这些之后,我们开始设计前台页面调用:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="[path]/Scripts/plugins/tooltip/tooltip.css" rel="stylesheet" type="text/css" />
</head>
<body>
<input type="text" id="name" class="textbox" title="请填写姓名" />
<input type="text" id="phone" class="textbox" title="请填写电话,格式:(010)87524576" />
<script src="[path]/Scripts/plugins/textbox/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="[path]/Scripts/plugins/textbox/jquery.textbox.js" type="text/javascript"></script>
<script src="[path]/Scripts/plugins/tooltip/jquery.tooltip.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#name").textbox({ label: "姓名" }).tooltip();
$("#phone").textbox({ label: "电话" }).tooltip();
});
</script>
</body>
</html>
当运行页面之后,你会发现文本框的提示效果:
是不是觉得比以前的alert以及模态框更有用户体验呢?我想就不用多言了吧。至此,我们做完了水印和提示的效果。总结一句话:插件的目的在于增加用户体验,封装所有细节,提供最简单的调用接口。 有兴趣的朋友在这里下载新版源码(解压后可以打开demo.htm欣赏效果)。 也许,这还没有完,我下一讲也将提供带图标的文本框以及智能感知效果的文本框,这些留给大家思考,我会逐步扩展并提供最终实现,欢迎交流。
本文转自:http://www.cnblogs.com/hmiinyu/archive/2011/12/23/2299891.html hmiinyu