/** * jQuery带箭头提示框插件 * email: tianshaojie@msn.com * date: 2013-01-15 * version: 1.0.0 */ (function($) { var max = Math.max, min = Math.min; $.pt = $.pureToolTips = function(options) { var opts = $.extend({ target : null, //目标元素,不能为空 position : 't', //提示框相对目标元素位置 t=top,b=bottom,r=right,l=left align : 'c', //提示框与目标元素的对齐方式,自动调节箭头显示位置,指向目标元素中间位置,c=center, t=top, b=bottom, l=left, r=right [postion=t|b时,align=l|r有效][position=t|b时,align=t|d有效] arrow : true, //是否显示箭头 content : '', //内容 width : 200, //宽度 height : 'auto', //高度 autoClose : true, //是否自动关闭 time : 2000, //自动关闭延时时长 leaveClose : false, //提示框失去焦点后关闭 close : null //关闭回调函数 }, options || {}), $ao, $ai, w, h, $pt = $('.pt'), $target = $(opts.target), top = $target.offset().top, left = $target.offset().left, width = $target.outerWidth(), height = $target.outerHeight(), position = opts.position, align = opts.align, arrow = opts.arrow, constant = {b:'pt-up', t:'pt-down', r:'pt-left', l:'pt-right'}, //相对位置正好和箭头方向相反 arrowClass = constant[position] || constant.t; //初始化元素,事件 function init() { if(!opts.target) { return; } if(!$pt.length) { $pt = $('
').appendTo(document.body); } $pt.removeClass().addClass('pt ' + (arrow ? arrowClass : '')).find('.cont').html(opts.content).css({width:opts.width, height:opts.height}); $ao = $pt.find('.out').toggle(arrow); $ai = $pt.find('.in').toggle(arrow); w = $pt.outerWidth(); h = $pt.outerHeight(); arrow && autoAdjust(); //设置箭头自动居中 $pt.css(setPos()).show(); //设置显示框位置和自动隐藏事件 opts.leaveClose && leaveClose();//离开关闭 opts.autoClose && !opts.leaveClose && autoClose(opts.timeout); //默认自动关闭,优先离开关闭 return $pt; } //计算提示框应该出现在目标元素位置 function setPos() { var btw = arrow ? parseInt($ao.css('border-top-width'), 10) : 3, brw = arrow ? parseInt($ao.css('border-right-width'), 10) : 3, result = {}; switch(align) { case 'c': break; case 't': result.top = top; break; case 'b': result.top = top + height - h; break; case 'l': result.left = left; break; case 'r': result.left = left + width - w; break; } switch(position) { case 't': result.top = top - h - brw; break; case 'b': result.top = top + height + brw; break; case 'l': result.left = left - w - btw; break; case 'r': result.left = left + width + btw; break; } result.top || (result.top = top + height/2 - h/2); result.left || (result.left = left + width/2 - w/2); return result; } //设置箭头自动居中 function autoAdjust() { var aop, aip, bw, auto='auto'; switch(position) { case't': bw = parseInt($ao.css('border-top-width'), 10); aop = {bottom:-bw, left:w/2-bw, top:auto, right:auto}; alignLR(); aip = {top:auto, left:aop.left+1, bottom:aop.bottom+1, right:auto}; break; case'b': bw = parseInt($ao.css('border-bottom-width'), 10); aop = {top:-bw, left:w/2 - bw, right:auto, bottom:auto}; alignLR(); aip = {top:aop.top+1, left:aop.left+1, bottom:auto, right:auto}; break; case'l': bw = parseInt($ao.css('border-left-width'), 10); aop = {top:h/2 - bw, right:-bw, left:auto, bottom:auto}; alignTB(); aip = {top:aop.top+1, right:aop.right+1, left:auto, bottom:auto}; break; case'r': bw = parseInt($ao.css('border-right-width'), 10); aop = {top:h/2 - bw, left:-bw, right:auto, bottom:auto}; alignTB(); aip = {top:aop.top+1, left:aop.left+1, right:auto, bottom:auto}; break; } //上下侧,左右对齐 function alignLR() { if(align === 'l' && width/2 > bw && width/2 < w-bw) { aop.left = width/2-bw/2; } else if(align === 'r' && width/2 > bw && width/2 < w-bw) { aop.left = w-width/2-bw/2; } } //左右侧,上下对齐 function alignTB() { if(align === 't' && height/2 > bw && height/2 < h-bw) { aop.top = height/2 - bw; } else if(align === 'b' && height/2 > bw && height/2 < h-bw) { aop.top = h - height/2 - bw; } } $ao.css(aop); $ai.css(aip); } //设置提示框自动关闭 function autoClose() { window.ptt && clearTimeout(ptt); window.pta && clearTimeout(pta); window.pta = setTimeout(function() { $pt.hide(); $.isFunction(opts.close) && opts.close(); }, opts.time); } //设置提示框失去焦点关闭 function leaveClose() { //先解绑再绑定,不然会形成事件链 $pt.unbind('mouseleave').mouseleave(function(e) { $pt.hide(); $.isFunction(opts.close) && opts.close(); }).unbind('mouseenter').mouseenter(function() { window.ptt && clearTimeout(ptt); }); } return init(); }; //扩展到包装集上 $.fn.pt = $.fn.pureToolTips = function(options) { var opts = $.extend({ leaveClose:true }, options || {}); return this.each(function() { $(this).mouseenter(function() { window.ptt && clearTimeout(ptt); window.pta && clearTimeout(pta); opts.target = this; $.pt(opts); }).mouseleave(function() { window.ptt = setTimeout(function() { $('.pt').hide(); $.isFunction(opts.close) && opts.close(); }, 500); }); }); }; })(jQuery);