基于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 相关文章推荐
javascript 出生日期和身份证判断大全
Nov 13 Javascript
jquery实现的一个导航滚动效果具体代码
May 27 Javascript
JS图片无缝滚动(简单利于使用)
Jun 17 Javascript
jquery批量设置属性readonly和disabled的方法
Jan 24 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
Jun 05 Javascript
跟我学习javascript的var预解析与函数声明提升
Nov 16 Javascript
页面向下滚动ajax获取数据的实现方法(兼容手机)
May 24 Javascript
浅谈js原生拖放
Nov 21 Javascript
Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)
Sep 18 Javascript
解决vue-router中的query动态传参问题
Mar 20 Javascript
node基于puppeteer模拟登录抓取页面的实现
May 09 Javascript
解决vue打包css文件中背景图片的路径问题
Sep 03 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
PHP5.2下chunk_split()函数整数溢出漏洞 分析
2007/06/06 PHP
解析php中如何直接执行SHELL
2013/06/28 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
浅谈javascript 面向对象编程
2009/10/28 Javascript
关于递归运算的顺序测试代码
2011/11/30 Javascript
JsRender for object语法简介
2014/10/31 Javascript
jQuery+jsp下拉框联动获取本地数据的方法(附源码)
2015/12/03 Javascript
jquery实现无刷新验证码的简单实例
2016/05/19 Javascript
从零开始学习Node.js系列教程五:服务器监听方法示例
2017/04/13 Javascript
详解如何在NodeJS项目中优雅的使用ES6
2017/04/22 NodeJs
ui-router中使用ocLazyLoad和resolve的具体方法
2017/10/18 Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
2019/06/10 jQuery
深入webpack打包原理及loader和plugin的实现
2020/05/06 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
2021/02/08 Javascript
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
Python解析最简单的验证码
2016/01/07 Python
python获取指定时间差的时间实例详解
2017/04/11 Python
Python面向对象编程之继承与多态详解
2018/01/16 Python
Python数据处理numpy.median的实例讲解
2018/04/02 Python
Python 面向对象之封装、继承、多态操作实例分析
2019/11/21 Python
3种python调用其他脚本的方法
2020/01/06 Python
PYcharm 激活方法(推荐)
2020/03/23 Python
在HTML5 canvas里用卷积核进行图像处理的方法
2018/05/02 HTML / CSS
美国家居装饰店:Pier 1
2019/09/04 全球购物
医科大学生的自我评价
2013/12/04 职场文书
初三化学教学反思
2014/01/23 职场文书
好人好事事迹材料
2014/02/12 职场文书
党的群众路线批评与自我批评发言稿
2014/10/16 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
生日答谢词
2015/01/05 职场文书
公司保洁员岗位职责
2015/02/13 职场文书
部门2015年度工作总结
2015/04/29 职场文书
党员观看《筑梦中国》心得体会
2016/01/18 职场文书
Python写情书? 10行代码展示如何把情书写在她的照片里
2022/04/21 Python
MySQL添加索引特点及优化问题
2022/07/23 MySQL