基于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 相关文章推荐
js监听输入框值的即时变化onpropertychange、oninput
Jul 13 Javascript
新浪微博字数统计 textarea字数统计实现代码
Aug 28 Javascript
jQuery实现单行文字间歇向上滚动源代码
Jun 02 Javascript
js获取当前页面的url网址信息
Jun 12 Javascript
javascript实现行拖动的方法
May 27 Javascript
简单纯js实现点击切换TAB标签实例
Aug 23 Javascript
Js+Ajax,Get和Post在使用上的区别小结
Jun 08 Javascript
jQuery图片拖动组件Dropzone用法示例
Jan 17 Javascript
解决浏览器会自动填充密码的问题
Apr 28 Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
Dec 09 Javascript
微信小程序picker组件关于objectArray数据类型的绑定方法
Mar 13 Javascript
小程序实现搜索框功能
Mar 26 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
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
php下MYSQL limit的优化
2008/01/10 PHP
VB中的RasEnumConnections函数返回632错误解决方法
2014/07/29 PHP
php实现随机生成易于记忆的密码
2015/06/19 PHP
js实现运行代码需要刷新的解决方法
2007/08/18 Javascript
从阶乘函数对比Javascript和C#的异同
2012/05/31 Javascript
js获取指定日期前后的日期代码
2013/08/20 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
JS选取DOM元素的简单方法
2016/07/08 Javascript
js实现右键自定义菜单
2016/12/03 Javascript
javascript+html5+css3自定义提示窗口
2017/06/21 Javascript
用vue封装插件并发布到npm的方法步骤
2017/10/18 Javascript
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
微信小程序methods中定义的方法互相调用的实例代码
2018/08/07 Javascript
使用Node.js在深度学习中做图片预处理的方法
2019/09/18 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
2019/09/30 Javascript
在vue中使用Base64转码的案例
2020/08/07 Javascript
JS模拟实现京东快递单号查询
2020/11/30 Javascript
[01:52]深扒TI7聊天轮盘语音出处7
2017/05/11 DOTA
python访问纯真IP数据库的代码
2011/05/19 Python
详解Python中的strftime()方法的使用
2015/05/22 Python
Python工程师面试必备25条知识点
2018/01/17 Python
Python os.rename() 重命名目录和文件的示例
2018/10/25 Python
使用Django连接Mysql数据库步骤
2019/01/15 Python
如何利用pygame实现简单的五子棋游戏
2019/12/29 Python
Django实现从数据库中获取到的数据转换为dict
2020/03/27 Python
支持IE8的纯css3开发的响应式设计动画菜单教程
2014/11/05 HTML / CSS
Shopbop中文官网:美国亚马逊旗下时尚购物网站
2020/12/15 全球购物
毕业生教师求职信
2013/10/20 职场文书
《那片绿绿的爬山虎》教学反思
2014/02/27 职场文书
电子商务求职信
2014/06/15 职场文书
意外伤害赔偿协议书范本
2014/09/28 职场文书
2016年第二十届“母亲节暨幸福工程救助贫困母亲活动日”活动总结
2016/04/06 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL
实例讲解Python中sys.argv[]的用法
2021/06/03 Python
SQL语法CONSTRAINT约束操作详情
2022/01/18 MySQL