Jquery 类似新浪微博,鼠标移到头像,用浮动窗口显示用户信息,已做成一个jquery插件
请注意!!!!! 该插件demo PHP 的 demo下载 C#.NET的demo下载
需要如下图,
1、鼠标移动到头像DIV时,Ajax获取数据,并让浮动DIV显示出来。
2、鼠标可以移动到上面浮动的DIV。
3、鼠标移出浮动DIV且移出头像DIV时,浮动DIV消失,
第一步,给DIV添加mouseon事件,触发获取数据:这个比较简单,我使用的是通过ajax get:$.get(url, function(data) {。。。。。}
第二步,显示DIV,
if(data=='error'){
alert('用户名片加载失败,请联系管理员!');
}else{
$(wrap_uid).append(data);//外面一层DIV,data本身就是HTML代码,当然也可以再这边先组织出data来
$(uid).show();//浮动窗口的DIV,show函数必须,不然这个新加的DIV是不会自个儿主动出来的!
}
第三步,这是比较头疼的一步了,最开始,是这样的思路,给头像DIV和浮动DIV的外面那层DIV添加一个事件,mouseout事件,在事件中将浮动DIV删除
,问题来了,很多时候,用户移动到头像DIV,然后浮动DIV显示出来了,用户就想去操作浮动DIV了,但是中间是分开的!只有一个箭头是和头像DIV在一起的,也就是说,鼠标从头像DIV移动到浮动DIV时,会有很大概率跑出大的DIV,一旦鼠标进入两个DIV中间的缝隙,mouseout事件就触发了,浮动DIV就木有了,很蛋疼。
最后想了个办法,让移除浮动DIV放到一个setTimeout中,在一定的时间内(0.2s或者0.1s),若用户鼠标移动到浮动的DIV上时,触发一个clearTimeout事件,把移除浮动DIV定时器给删了!想法挺好,看着也挺简单,但是中间还是有各种BUG,各种失败,最重要的一点就是,最外面的DIV的mouseout事件需要移除绑定,自己做过实验就会知道为什么了,下面直接贴代码
function load_user_info(uid, login_id) {
var my_timeout;
var url = 'xxxxxx';
console.log(url);
$.get(url, function(data) {
console.log(data);
if(data=='error'){
alert('用户名片加载失败,请联系管理员!');
}else{
$(wrap_id).append(data).mouseout(function() {
my_timeout = setTimeout(function() {
$(float_id).remove();
}, 200);
$(wrap_id).unbind('mouseout');
}).mouseover(function() {
clearTimeout(my_timeout);
});
$(float_id).show().mouseover(function() {
clearTimeout(my_timeout);
}).mouseout(function() {
my_timeout = setTimeout(function() {
$(float_id.remove();
}, 200);
});
}
});
}
还是写点清楚吧,也算锻炼下自己的表达能力!首先,鼠标移出外层DIV时,有两种情况,一种是鼠标它真的走了,还有一种是它其实是去浮动DIV了,所以,给他200毫秒时间,时间一到,如果它没到浮动DIV,就认为它真的走了,就删掉浮动DIV,如果到了浮动DIV,就把定时器给删了!浮动DIV依旧显示,然后,从浮动DIV出来,也有两种情况,一种是去头像DIV,一种是鼠标他真的走了,老样子。至于为什么要外层的DIV解除mouseout绑定,是因为当鼠标在浮动DIV移动的时候,实际上鼠标已经移出了外层DIV的范围,当鼠标在浮动DIV上不停滑动时,mouseout事件不断触发,会造成BUG,第一次完全OK,在浮动DIV移动时,不停clearTimeout 后面timeout越来越多,第二次开始timeout就乱了,无法正确删除clearTimeout事件.....还是有点说不清,囧....
感谢@tanshaohua的指点,指出了这段代码的改进之处,就是在用户鼠标移动到头像,显示出浮动框后,鼠标再次移动到头像时,不应该再去获取数据,增加了服务器的压力。最后贴一下改进后的代码,其实就是判断下float_id的DIV是否已经存在,存在了就不进行加载。代码还比较臃肿,先把手头上其他事解决了,再来处理这个问题
var my_timeout;
if($(float_id).size()>0){
$(wrap_id).mouseout(function() {
my_timeout = setTimeout(function() {
$("float_id).remove();
}, 200);
$(wrap_id).unbind('mouseout');
}).mouseover(function() {
clearTimeout(my_timeout);
$(float_id).show().mouseover(function() {
clearTimeout(my_timeout);
}).mouseout(function() {
my_timeout = setTimeout(function() {
$(float_id).remove();
}, 200);
});
}else{
var url = 'XXXXXXX';
// console.log(url);
$.get(url, function(data) {
// console.log(data);
if(data=='error'){
alert('用户名片加载失败,请联系管理员!');
}else{
$(wrap_id).append(data).mouseout(function() {
my_timeout = setTimeout(function() {
$(float_id).remove();
}, 200);
$(wrap_id).unbind('mouseout');
}).mouseover(function() {
clearTimeout(my_timeout);
$(float_id).show().mouseover(function() {
clearTimeout(my_timeout);
}).mouseout(function() {
my_timeout = setTimeout(function() {
$(float_id).remove();
}, 200);
});
}
});
}
今天把这个功能做成了一个jquery插件:,下面是插件的代码:
(function($) {
$.fn.popovercard = function(op) {
var nowObj = $(this);
var defaults = {
obj_type : 'user',
obj_id : '21',
url : '',
user_url : '/user/user_info_card?id=',
prod_url : '/prod/prod_info_card?id',
needParam : 'true',
popover_id : 'popover',
popover_wrap_id : 'popover_wrap',
onSuccess : null,
onError : null
};
if (typeof ($(this).data('obj_id')) != "undefined") {
defaults.obj_id = $(this).data('obj_id');
}
if (typeof ($(this).data('url')) != "undefined") {
defaults.url = $(this).data('url');
}
if (typeof ($(this).data('obj_type')) != "undefined") {
defaults.obj_type = $(this).data('obj_type');
}
if (typeof ($(this).data('needParam')) != "undefined") {
defaults.needParam = $(this).data('needParam');
}
if (typeof ($(this).data('popover_id')) != "undefined") {
defaults.popover_id = $(this).data('popover_id');
}
if (typeof ($(this).data('popover_wrap_id')) != "undefined") {
defaults.popover_wrap_id = $(this).data('popover_wrap_id');
}
return this.each(function() {
var opts = $.extend(defaults, op);
nowObj.mouseover(function() {
load_user_info(opts.obj_id, opts.obj_type,opts.needParam,opts.url);
});
});
function load_user_info(uid, type,needParam,url) {
var data_url;// 获取数据的URL
var my_timeout;// 隐藏浮动DIV的定时器
var popover_wrap_div;// 最外层包裹的DIV
// 浮动框的ID
var popover_id = defaults.popover_id + '_' + type + '_' + uid;
// 浮动框和IMG外面包裹的DIV的ID
var popover_wrap_id = defaults.popover_wrap_id + '_' + type + '_'
+ uid;
if ($("#" + popover_id).size() <= 0) {
if(url==''){
if (type == 'user') {
if (needParam == 'true') {
data_url = defaults.user_url + uid;
} else {
data_url = defaults.user_url;
}
} else if (type = 'prod') {
// 扩展其他url
data_url = defaults.prod_url;
} else {
if (needParam == 'true') {
data_url = defaults.url + uid;
} else {
data_url = defaults.url;
}
}
}else{
data_url = url;
} console.log(data_url);
$.get(data_url, function(data) {
if (data == 'error') {
alert('加载失败,请联系管理员!');
} else {
if ($("#" + popover_wrap_id).size() <= 0) {
// 在最外面包裹一层DIV
popover_wrap_div = '<div id ="' + popover_wrap_id
+ '"></div>';
nowObj.wrap(popover_wrap_div);
}
$("#" + popover_wrap_id).append(data);
od = $("#" + popover_wrap_id + ">div:last").attr('id',
popover_id);
$("#" + popover_id).show();
bindEvent(popover_wrap_id, popover_id);
}
});
}
bindEvent(popover_wrap_id, popover_id);
function bindEvent(popover_wrap_id, popover_id) {
$("#" + popover_wrap_id).mouseout(function() {
my_timeout = setTimeout(function() {
$("#" + popover_id).hide();
}, 200);
$("#" + popover_wrap_id).unbind('mouseout');
}).mouseover(function() {
clearTimeout(my_timeout);
});
$("#" + popover_id).show().mouseover(function() {
clearTimeout(my_timeout);
}).mouseout(function() {
my_timeout = setTimeout(function() {
$("#" + popover_id).hide();
}, 200);
});
}
}
};
})(jQuery);
接下来是使用说明:
参数说明:
<script type=‘text/javascript’ src=‘/js/jquery.js’></script>
<script type=‘text/javascript’ src=‘js/jquery.popovercard.js’></script>
<a data-obj_id=‘21‘ data-obj_type ='user' id=‘test_header’></a> // data-popover_id=‘21’其中21是主键的值
<script type=‘text/javascript’>
$(function(){
$("# test_header ").popovercard();
});
</script>
举例二:使用外部自定义URL
<script type=‘text/javascript’ src=‘/js/jquery.js’></script>
<script type=‘text/javascript’ src=‘js/jquery.popovercard.js’></script>
<a data-obj_id=‘21‘ data-url='/getsm/sm?id=' id=‘test_header’></a> // data-popover_id=‘21’其中21是主键的值
<script type=‘text/javascript’>
$(function(){
$("# test_header ").popovercard();
});
</script>
//其实就是给一个data-url即可。如果不需要参数,再加data-needParam='false',删掉data-obj-id即可。
最后补充说明:
参数的设置,也可以再popovercard实例化的时候设置,效果一样
例如:
<a id=‘test_header’ data-obj_id=‘12’ data-obj_type=‘prod’ ></a>
<script type=‘text/javascript’>
$(function(){
$("# test_header ").popovercard();
});
</script>
等同于:
<a id=‘test_header’></a>
<script type=‘text/javascript’>
$(function(){
$("# test_header ").popovercard({
obj_type:‘prod’, obj_id=‘12’
});
});
</script>
2013-06-27,对插件进行了改进,增加了自动左浮动和右浮动,并且锁定元素不再依靠id,使用class锁定元素,浮动效果如下 :
代码如下:
(function($) {
var popover_card_count = 0;
$.fn.popovercard = function(op) {
var nowObj = $(this);
var space = 20;// 浮动框左边空隙
var float_width = 324;// 浮动框宽度
var defaults = {
obj_type : 'user',
obj_id : '21',
url : 'get_user_card.php?id',
popover_class : 'popover_class',
popover_wrap_class : 'popover_wrap_class'
};
if (typeof ($(this).data('obj_id')) != "undefined") {
defaults.obj_id = $(this).data('obj_id');
}
if (typeof ($(this).data('url')) != "undefined") {
defaults.url = $(this).data('url');
}
if (typeof ($(this).data('obj_type')) != "undefined") {
defaults.obj_type = $(this).data('obj_type');
}
if (typeof ($(this).data('popover_class')) != "undefined") {
defaults.popover_class = $(this).data('popover_class');
}
if (typeof ($(this).data('popover_wrap_class')) != "undefined") {
defaults.popover_wrap_class = $(this).data('popover_wrap_class');
}
return this.each(function(key,value) {
var opts = $.extend(defaults, op);
nowObj.mouseover(function() {load_user_info(opts);});
});
function load_user_info(opts) {
var data_url;// 获取数据的URL
var my_timeout;// 隐藏浮动DIV的定时器
var popover_wrap_div;// 最外层包裹的DIV
// 浮动框的ID
var popover_class = opts.popover_class + '_' + popover_card_count;
// 浮动框和IMG外面包裹的DIV的ID
var popover_wrap_class = opts.popover_wrap_class + '_' + popover_card_count;
if (nowObj.next("div[class*='" + opts.popover_class + "']").size() <= 0) {
popover_card_count = popover_card_count + 1;
data_url = opts.url + opts.obj_id;
$.get(data_url, function(data) {
if (data == 'error') {
alert('加载失败,请联系管理员!');
} else {
if (nowObj.parent("div[class*='"+ opts.popover_wrap_class + "']").size() <= 0) {
// 在最外面包裹一层DIV
popover_wrap_div = '<div class ="' + popover_wrap_class + '"></div>';
nowObj.wrap(popover_wrap_div);
}
$("." + popover_wrap_class).append(data).css('float','left');
popover_class = $("." + popover_wrap_class + ">div:last").addClass(popover_class).attr('class');
resetPosition(popover_wrap_class,popover_class);
$("." + popover_class).show().css('float', 'right');
//bindEvent(popover_wrap_class, popover_class);
}
});
} else {
popover_class = nowObj.next("div").attr('class');
popover_wrap_class = nowObj.parent("div[class*='" + opts.popover_wrap_class + "']").attr('class');
resetPosition(popover_wrap_class,popover_class);
} // 重新定位,防止浮动框部分未显示
function resetPosition(wrap_div_class,div_class) {
var body_width = $("body").width();
var body_height = $("body").height();
var div_pop_over = $("div[class='"+div_class+"']");
var offset = nowObj.offset();
var left = offset.left - (space + $(div_pop_over).width());
var right = (body_width - offset.left) - (space + $(div_pop_over).width());
var top = offset.top - space - $(div_pop_over).height()+120-30;
var bottom = (body_height - offset.top ) - (space + $(div_pop_over).height());
console.log('left'+left+'right'+right+'top'+top+'bottom'+bottom);
//头像太左边
if(left<0){
$(div_pop_over).removeClass("left").addClass('right');
}
//头像太靠右
if(right<0){
$(div_pop_over).removeClass("right").addClass('left').css('margin-left', 0-($(div_pop_over).width()+70+space));
}
//头像太靠上,原本需要30px,这里的数据你可以根据自己需要随意调试
if(top<0){
$(div_pop_over).css('top',-30-top);
$(div_pop_over).find("div[class='arrow arrow-t']").css('top',60+top);
}
//头像太靠下
if(bottom<0){
//如果使用我的页面css,不可能出现这种情况 - -,忽略不计,如果需要,按照上面的,差不多改下
//也挺简单的
}
div_class = $(div_pop_over).attr('class');
bindEvent(wrap_div_class, div_class);
}
function bindEvent(popover_wrap_class, popover_class) {
$("div[class='"+popover_wrap_class+"']").mouseout(function() {
my_timeout = setTimeout(function() {
$("div[class='"+popover_class+"']").hide();
}, 100);
$("div[class='"+popover_wrap_class+"']").unbind('mouseout');
}).mouseover(function() {
clearTimeout(my_timeout);
});
$("div[class='"+popover_class+"']").show().mouseover(function() {
clearTimeout(my_timeout);
}).mouseout(function() {
my_timeout = setTimeout(function() {
$("div[class='"+popover_class+"']").hide();
}, 200);
});
$("div[class='"+popover_class+"']").show();return;
}
}
};
})(jQuery);
请注意!!!!! 该插件demo PHP 的 demo下载 C#.NET的demo下载
欢迎转载,原文地址:http://www.cnblogs.com/wangmy/p/3144723.html ,转载请注明地址,谢谢!
Jquery 类似新浪微博,鼠标移到头像,用浮动窗口显示用户信息,已做成一个jquery插件的更多相关文章
- VC/MFC 当鼠标移到控件上时显示提示信息
VC/MFC 当鼠标移到控件上时显示提示信息 ToolTip是Win32中一个通用控件,MFC中为其生成了一个类CToolTipCtrl,总的说来其使用方法是较简单的,下面讲一下它的一般用法和高级用法 ...
- lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单
lightinthebox头部分类菜单下拉导航,使鼠标移到See All Categories就显示下拉菜单 打开includes\templates\lightinthebox\common\tpl ...
- 使用Ajax+jQuery来实现前端收到的数据在console上显示+简单的主页设计与bootstrap插件实现图片轮播
1.实现前端输入的数据在console上显示 上一篇是解决了在前端的输入信息在cygwin上显示,这次要给前台们能看见的数据,因为数据库里插入的数据少,所以写的语句翻来覆去就那几个词,emmm···当 ...
- jQuery背景跟随鼠标移动的网页导航
首页 PSD模板 CSS模板 特效插件 源码下载 酷站欣赏 建站资源 建站教程 心境之旅 在线留言 设为首页 加入收藏 我要投稿 联系站长 Search 首页 PSD模板 CSS模板 特效插件 ...
- WPF中当鼠标移到按钮上时,按钮的背景图片消失的问题
如果给按钮设置了背景图片,当鼠标移到按钮上的时候,按钮就好变成一个浅蓝色的按钮,背景图片就消失了,对于这个问题有很多解决方法,我只分享一下我的解决方法. 我第一次用的方式是在按钮中添加一个图片,不用背 ...
- flask_用户信息和头像
一.用户信息页 1.创建视图函数(microblog.py) @app.route('/user/<nickname>') @login_required def user(nicknam ...
- JQuery鼠标移到小图显示大图效果的方法
JQuery鼠标移到小图显示大图效果的方法 本文实例讲述了JQuery鼠标移到小图显示大图效果的方法.分享给大家供大家参考.具体分析如下: 这里的显示大图功能类似上一篇<JQuery实现超链接鼠 ...
- Jquery打造的类似新浪微博@提醒功能
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 自定义Jquery插件——由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件
由于项目需要,对页面中过长的文本进行截取,鼠标移上去有一个title的提示,所以做了一个Jquery过长文本处理的插件下面是代码: // 掉用方式支持 $('select').textBeauty(1 ...
随机推荐
- MVC日期格式化的2种方式
原文:MVC日期格式化的2种方式 假设有这样的一个类,包含DateTime类型属性,在编辑的时候,如何使JoinTime显示成我们期望的格式呢? using System; using System. ...
- DDD分层架构的进化
.NET逻辑分层架构演示:DDD分层架构的进化 概述: 架构是高层的设计,如果设计和理解有误,必将在实现时带来各种问题.架构又是最稳定的,不会因为各种具体技术的依赖,如各种UI框架.ORM框架.I ...
- Webbrowser代理支持
原文:Webbrowser代理支持 1 通过设置注册表,再用InternetSetOption发送INTERNET_OPTION_SETTINGS_CHANGED与INTERNET_OPTION_RE ...
- Responsive Design in 3 Steps
Responsive web design is no doubt a big thing now. If you still not familiar with responsive design, ...
- linux 定时关机命令
一. 关机流程 Linux 运作时, 不能够直接将电源关闭, 否则, 可能会损毁档案系统. 因此, 必须依照正常的程序关机: 观察系统使用情形(或许当时, 正有使用者做着重要的工作呢!) 通知线上使用 ...
- 清除css、javascript及背景图在浏览器中的缓存
在实际项目开发过过程中,页面是上传到服务器上的.而为了减少服务器的压力,让用户少加载,浏览器会将图片.css.js缓存到本地中,以便下次访问网站时使用.这样做不仅减少了服务器的压力,并且也减少了用户的 ...
- 快速构建Windows 8风格应用14-ShareContract概述及原理
原文:快速构建Windows 8风格应用14-ShareContract概述及原理 本篇博文主要介绍Share Contract概述.Share Contract实现原理.实现Share Contra ...
- php soap调用asp.net webservice
原文:php soap调用asp.net webservice 首先做一下准备工作,找到安装环境里的php.ini把;extension=php_soap.dll去掉前面的;.我这里使用的是wamp, ...
- 有return如果是try catch finally运行命令
背景: 昨天一个朋友出去采访,遇到这样的问题:"C# catch那里return.finally也弄它运行?" 个人总结实践: 1.无论有木有出现异常.finally块中代码都会 ...
- Google Hacking的实现以及应用
Google Hacking其实并算不上什么新东西,在早几年我在一些国外站点上就看见过相关的介绍,但是由于当时并没有重视这种技术,认为最多就只是用来找找未改名的mdb或者别人留下的webshell什么 ...