基于jquery的气泡提示效果


Posted in Javascript onMay 31, 2010

代码注释已经尽可能的详细了,也不多说了.
初步测试暂未发现大的BUG,总体来说不满意的是鼠标移来移去不断触发气泡时会出现XX为空或不是对象的问题,
虽然不影响效果,但看着IE左下角的黄色警告不爽,暂时不知道如何改进. 加了try/catch解决...
还有就是气泡默认出现在触发对象的正上方,当触发对象在边上时,气泡会有一部分出现在窗口外面......也许这种情况可以让气泡显示在左边或是右边,感觉可能会有些麻烦,就没去弄了,比较懒......
越用jquery就越喜欢用它...
bubble.js:

/* 
* @date: 2010-5-30 11:57:22 
* @author: 胡灵伟 
* Depends: 
* jquery.js 
* 
* function:气泡提示效果 
* use:$("selectors").bubble({fn:getdata, width:width, height:height}); 
* 对所有需要气泡提示效果的对象使用bubble方法, 
* fn为气泡中显示内容获得方法,即fn中返回的数据会显示在气泡中 
* 以样式指代div则有: 
* width\height为contents的width\height属性 
* 气泡总width为left.width + contents.width + right.width 
* 气泡总height为top.height + contents.height + bottom.height 
*/ 
(function ($) { 
$.fn.bubble = function (options) { 
Bubble = function(){ 
this.defaults = { 
distance : 10, 
time : 250, 
hideDelay : 500, 
width:100, 
height:100 
}; 
this.options = $.extend(this.defaults, options); 
this.hideDelayTimer = new Array(); 
this.shown = new Array(); 
this.beingShown = new Array(); 
this.popup = new Array(); 
this.trigger = new Array(); 
this.makebubble = function(w, h){ 
var tpl = $('<div class="bubble-popup"></div>').append('<div class="topleft"></div>').append('<div class="top"></div>') 
.append($('<div class="topright"></div>')).append('<div class="left"></div>') 
.append('<div class="contents"></div>').append('<div class="right"></div>') 
.append('<div class="bottomleft"></div>') 
.append($('<div class="bottom"></div>') 
.append($('<div class="bottomtail"></div>'))) 
.append('<div class="bottomright"></div>').appendTo('body'); 
tpl.find('.left, .right, .contents').each(function(){$(this).height(h)}); 
tpl.find('.top, .bottom, .contents').each(function(){$(this).width(w)}); 
return tpl; 
}; 
this.add = function(triggers, options){ 
//此处的options为每次调用add方法传进来的参数,比如指定获取数据的方法fn, 气泡宽width高height 
//console.debug("length:"+triggers.length); 
var t = this.trigger.length; 
//将新加入的需要气泡提示效果的对象放到trigger数组中 
for(var j =0;j<triggers.length;j++) 
this.trigger.push(triggers[j]); 
//console.debug("trigger.length:" + this.trigger.length); 
var hout = this.handleout; 
var hover = this.handleover; 
var obj = this; 
//为新加入的对象绑定鼠标监听事件 
triggers.each(function(ind){ 
$(this).unbind('mouseover').mouseover(function(){ 
hover(t + ind, obj, options); 
}).unbind('mouseout').mouseout(function(){ 
hout(t + ind, obj, options); 
}); 
}); 
}; 
this.handleover = function(i, obj, options){ 
//console.debug("hideDelayTimer.length:" + obj.hideDelayTimer.length); 
//当新触发冒气泡事件时原先的定时器还没结束则将原来的定时器清除 
if (obj.hideDelayTimer[i]) clearTimeout(obj.hideDelayTimer[i]); 
if (obj.beingShown[i] || obj.shown[i]) { 
//如果气泡正在冒或已经冒出来了则不再重复冒气泡 
return; 
} else { 
var trigger = $(obj.trigger[i]); 
//标记正在冒气泡 
obj.beingShown[i] = true; 
//创建气泡 
obj.popup[i] = obj.makebubble(options.width||obj.options.width, options.height||obj.options.height); 
//对于气泡绑定同样的事件以使得鼠标离开触发对象后放到气泡上时气泡不会消失 
obj.popup[i].mouseover(function(){obj.handleover(i, obj)}).mouseout(function(){obj.handleout(i, obj)}); 
//调用获取数据的方法fn来显示数据 
obj.options.fn(obj.trigger[i], function(data){ 
obj.popup[i].find('.contents').text(data); 
}); 
//设定气泡的位置和显示属性,气泡默认出现在触发对象正上方 
obj.popup[i].css({ 
top: trigger.offset().top-obj.popup[i].height(), 
left: trigger.offset().left + trigger.width()/2 - obj.popup[i].width()/2, 
display: 'block' 
}).animate( 
//由于万恶的IE不能同时支持PNG半透明和滤镜,所以对于IE不使用滤镜 
$.browser.msie?{ 
top: '-=' + obj.options.distance + 'px' 
}:{ 
top: '-=' + obj.options.distance + 'px', 
opacity: 1 
}, obj.options.time, 'swing', function() { 
obj.beingShown[i] = false; 
obj.shown[i] = true; 
}); 
} 
return false; 
}; 
this.handleout = function(i, obj, options){ 
//console.debug("hideDelayTimer["+i+"]:"+obj.hideDelayTimer[i]); 
//处理当因为某些意外操作使得没有触发鼠标进入事件而直接再次触发鼠标离开事件时的情况 
if (obj.hideDelayTimer[i]) clearTimeout(obj.hideDelayTimer[i]); 
obj.hideDelayTimer[i] = setTimeout(function () { 
obj.hideDelayTimer[i] = null; 
try{ 



 obj.popup[i].animate( 
$.browser.msie?{ 
top: '-=' + obj.options.distance + 'px' 
}:{ 
top: '-=' + obj.options.distance + 'px', 
opacity: 0//渐隐效果 
}, obj.options.time, 'swing', function () { 
obj.shown[i] = false; 
obj.popup[i].css('display', 'none'); 
obj.popup[i] = null; 
});}catch(e){}; 
}, obj.options.hideDelay); 
return false; 
}; 
}; 
$.bubble = new Bubble();//单例 
$.bubble.add(this, options); 
}; 
})(jQuery);

使用方法:(用到的图片样式img.zip,注意路径,没图片是很难看的...)
<style type="text/css" media="screen"> 
<!-- 
* { 
margin: 0; 
padding: 0; 
} 
body { 
padding: 10px; 
} 
h1 { 
margin: 14px 0; 
font-family: 'Trebuchet MS', Helvetica; 
} 
.bubbletrigger { 
} 
/* Bubble pop-up */ 
.bubble-popup { 
position: absolute; 
display: none; 
z-index: 50; 
border-collapse: collapse; 
} 
.bubble-popup .topleft {width:19px; height:15px;float:left;background-image: url(../images/bubble/bubble-1.png);} 
.bubble-popup .top { width:1px;height:15px;float:left;background-image: url(../images/bubble/bubble-2.png); } 
.bubble-popup .topright { width:19px; height:15px;float:left;background-image: url(../images/bubble/bubble-3.png); } 
.bubble-popup .left { clear:left;width:19px; height:1px;float:left;background-image: url(../images/bubble/bubble-4.png); } 
.bubble-popup .contents { 
white-space:normal; 
word-break:break-all; 
float:left; 
font-size: 12px; 
line-height: 1.2em; 
background-color: #fff; 
color: #666; 
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", sans-serif; 
} 
.bubble-popup .right { width:19px; height:1px;float:left;background-image: url(../images/bubble/bubble-5.png); } 
.bubble-popup .bottomleft { clear:left;width:19px; height:15px;float:left;background-image: url(../images/bubble/bubble-6.png); } 
.bubble-popup .bottom {width:1px;height:15px;float:left;background-image: url(../images/bubble/bubble-7.png); text-align: center;} 
.bubble-popup .bottomtail { width:30px; height:29px; display: block; margin: 0 auto; background-image: url(../images/bubble/bubble-tail2.png);} 
.bubble-popup .bottomright { width:19px; height:15px;float:left;background-image: url(../images/bubble/bubble-8.png); } 
--> 
</style> 
<script src="../js/jquery-1.4.2.min.js" type="text/javascript"></script> 
<script src="../js/bubble-1.0.js" type="text/javascript"></script> 
<script type="text/javascript"><!-- 
aa = function(obj, callback){ 
$.ajax({ 
type : 'POST', 
data : {word:$(obj).attr('alt'),rand:Math.random()}, 
url : 'http://localhost/xun/ajax.svl?method=getdetailinfo', 
dataType : 'text', 
timeout : 1000, 
success : function(data){ 
callback(data); 
} 
}); 
}; 
bb = function(obj, callback){ 
$.ajax({ 
type : 'POST', 
data : {word:$(obj).attr('alt'),rand:Math.random()}, 
url : 'http://localhost/xun/ajax.svl?method=getdetailinfo', 
dataType : 'text', 
timeout : 1000, 
success : function(data){ 
callback(data + "aaaa"); 
} 
}); 
}; 
$(function(){ 
$('.bubbletrigger').bubble({width:150, height: 100, fn:aa}); 
$('#a').bubble({fn:bb}); 
}); 
// 
--></script> 
</head> 
<body id="page"> 
<h1>jQuery Bubble Example</h1> 
<div> 
<br/>aaaaaaaaaa 
<br/>aaaaaaaaaaaaaaaaaaaa 
<br/>aaaaaaaaaaaaaaaaaaaaaaaaaaaa 
<br/>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
<br/>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
<br/>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
</div> 
<div style="padding-left:100px;"> 
<img class="bubbletrigger" alt="a" src="../images/bubble/starburst.gif" /> 
<img class="bubbletrigger" alt="b" src="../images/bubble/starburst.gif" /> 
<img class="bubbletrigger" alt="c" src="../images/bubble/starburst.gif" /> 
<img class="bubbletrigger" alt="d" src="../images/bubble/starburst.gif" /> 
<img id="a" alt="e" src="../images/bubble/starburst.gif" /> 
</div> 
</body>

servlet只要返回一段字符串就可以了,就不贴了.
Javascript 相关文章推荐
jquery 元素相对定位代码
Oct 15 Javascript
Javascript中的isNaN函数使用说明
Nov 10 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
Feb 27 Javascript
JS去掉第一个字符和最后一个字符的实现代码
Feb 20 Javascript
jquery中$(#form :input)与$(#form input)的区别
Aug 18 Javascript
Javascript中拼接大量字符串的方法
Feb 05 Javascript
jquery实现的横向二级导航效果代码
Aug 26 Javascript
跟我学习javascript解决异步编程异常方案
Nov 23 Javascript
JS实现含有中文字符串的友好截取功能分析
Mar 13 Javascript
移动端刮刮乐的实现方式(js+HTML5)
Mar 23 Javascript
javascript数组拍平方法总结
Jan 20 Javascript
解决vue cli使用typescript后打包巨慢的问题
Sep 30 Javascript
niceTitle 基于jquery的超链接提示插件
May 31 #Javascript
jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
May 31 #Javascript
jQuery 获取对象 定位子对象
May 31 #Javascript
jQuery 获取对象 基本选择与层级
May 31 #Javascript
javascript 判断数组是否已包含了某个元素的函数
May 30 #Javascript
基于jquery的inputlimiter 实现字数限制功能
May 30 #Javascript
JQuery Easyui Tree的oncheck事件实现代码
May 28 #Javascript
You might like
2021年最新CPU天梯图
2021/03/04 数码科技
php max_execution_time执行时间问题
2011/07/17 PHP
完整删除ecshop中获取店铺信息的API
2014/12/24 PHP
PHP CURL或file_get_contents获取网页标题的代码及两者效率的稳定性问题
2015/11/30 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
2016/08/08 PHP
js函数的引用, 关于内存的开销
2012/09/17 Javascript
jQuery制作简洁的多级联动Select下拉框
2014/12/23 Javascript
javascript比较语义化版本号的实现代码
2016/09/09 Javascript
jQuery Validate 数组 全部验证问题
2017/01/12 Javascript
three.js实现3D视野缩放效果
2017/11/16 Javascript
微信小程序用户自定义模版用法实例分析
2017/11/28 Javascript
从vue源码解析Vue.set()和this.$set()
2018/08/30 Javascript
es6 for循环中let和var区别详解
2020/01/12 Javascript
原生javascript的ajax请求及后台PHP响应操作示例
2020/02/24 Javascript
JS Array.from()将伪数组转换成数组的方法示例
2020/03/23 Javascript
python 自动提交和抓取网页
2009/07/13 Python
Python中使用HTMLParser解析html实例
2015/02/08 Python
Python进行数据提取的方法总结
2016/08/22 Python
Python建立Map写Excel表实例解析
2018/01/17 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
Python单元测试与测试用例简析
2019/11/09 Python
python实现上传文件到linux指定目录的方法
2020/01/03 Python
python与mysql数据库交互的实现
2020/01/06 Python
pymysql的简单封装代码实例
2020/01/08 Python
Python 实现将大图切片成小图,将小图组合成大图的例子
2020/03/14 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
python简单实现插入排序实例代码
2020/12/16 Python
戴尔美国官方折扣店:Dell Outlet
2018/02/13 全球购物
Envie de Fraise意大利:法国网上推出的孕妇装品牌
2020/10/18 全球购物
初级Java程序员面试题
2016/03/03 面试题
测绘工程个人的自我评价
2013/11/10 职场文书
户外活动策划方案
2014/03/12 职场文书
运动会演讲稿
2014/05/07 职场文书
学习作风建设心得体会
2014/10/22 职场文书
校园广播站开场白
2015/06/01 职场文书
立春观后感
2015/06/18 职场文书