Team:Imperial College London/balloontipjs
From 2011.igem.org
(Created page with "//Rich HTML Balloon Tooltip: http://www.dynamicdrive.com/dynamicindex5/balloontooltip.htm //Created: September 10th, 2006 //Updated: May 9th, 10 for window edge bug var disappea...") |
|||
Line 1: | Line 1: | ||
- | / | + | /*Speech Bubbles Tooltip (Initial: Dec 8th, 2010) |
- | + | * This notice must stay intact for usage | |
- | // | + | * Author: Dynamic Drive at http://www.dynamicdrive.com/ |
+ | * Visit http://www.dynamicdrive.com/ for full source code | ||
+ | */ | ||
- | var | + | var speechbubbles_tooltip={ |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | ///// | + | loadcontent:function($, selector, options, callback){ |
+ | var ajaxfriendlyurl=options.url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/") | ||
+ | $.ajax({ | ||
+ | url: ajaxfriendlyurl, //path to external content | ||
+ | async: true, | ||
+ | error:function(ajaxrequest){ | ||
+ | alert('Error fetching Ajax content.<br />Server Response: '+ajaxrequest.responseText) | ||
+ | }, | ||
+ | success:function(content){ | ||
+ | $(document.body).append(content) | ||
+ | callback(selector) | ||
+ | $(content).remove() | ||
+ | } | ||
+ | }) | ||
- | + | }, | |
- | + | ||
- | + | ||
- | function | + | buildtooltip:function($, setting){ |
- | var | + | var speechtext=(setting.speechid)? $('div#'+setting.speechid).html() : setting.speechtext |
- | + | if (speechtext){ | |
- | + | $speech=$('<div class="speechbubbles">'+speechtext+'</div>').appendTo(document.body) | |
- | + | $speech.addClass('speechbubbles').append('<div class="speechbubbles-arrow-border"></div>\n<div class="speechbubbles-arrow"></div>') | |
- | + | $speech.data('$arrowparts', $speech.find('div.speechbubbles-arrow, div.speechbubbles-arrow-border')) //store ref to the two arrow DIVs within tooltip | |
- | } | + | var arrowheight=(window.XMLHttpRequest)? $speech.data('$arrowparts').eq(0).outerHeight() : 10 |
- | return | + | $speech.data('measure', {w:$speech.outerWidth(), h:$speech.outerHeight()+arrowheight, arroww:$speech.data('$arrowparts').eq(0).outerWidth()}) //cache tooltip dimensions |
- | } | + | $speech.css({display:'none', visibility:'visible'}) |
+ | setting.$speech=$speech //remember ref to tooltip | ||
+ | } | ||
+ | return setting.$speech | ||
+ | }, | ||
+ | |||
- | function | + | positiontip:function($, $anchor, s, e){ |
- | + | var $speech=s.$speech | |
- | if ( | + | var $offset=$anchor.offset() |
- | + | var windowmeasure={w:$(window).width(), h:$(window).height(), left:$(document).scrollLeft(), top:$(document).scrollTop()} //get various window measurements | |
- | } | + | var anchormeasure={w:$anchor.outerWidth(), h:$anchor.outerHeight(), left:$offset.left, top:$offset.top} //get various anchor link measurements |
+ | var speechmeasure={w:$speech.data('measure').w, h:$speech.data('measure').h} //get tooltip measurements | ||
+ | var x=anchormeasure.left | ||
+ | var y=anchormeasure.top+anchormeasure.h | ||
+ | x=(x+speechmeasure.w>windowmeasure.left+windowmeasure.w-3)? x-speechmeasure.w+anchormeasure.w-5 : x //right align tooltip if no space to the right of the anchor | ||
+ | y=(y+speechmeasure.h>windowmeasure.top+windowmeasure.h)? y-speechmeasure.h-anchormeasure.h-10 : y+10 //top align tooltip if no space to the bottom of the anchor | ||
+ | var isrightaligned=x!=anchormeasure.left //Boolean to indicate if tooltip is right aligned | ||
+ | var istopaligned=y!=anchormeasure.top+anchormeasure.h+10 //Boolean to indicate if tooltip is top aligned | ||
+ | $speech.removeClass('downversion').addClass(istopaligned? 'downversion' : '') //add CSS "downversion" class to tooltip if arrow should be pointing down | ||
+ | var arrowpos=(isrightaligned)? speechmeasure.w-(anchormeasure.left+anchormeasure.w-e.pageX)-25 : e.pageX-anchormeasure.left-25 //25 is to move arrow 25px to the left so it's not obscured by cursor | ||
+ | if (arrowpos>speechmeasure.w-25) //if arrow exceeds the width of the tooltip | ||
+ | arrowpos=speechmeasure.w-40 //move it to the left of the cursor | ||
+ | else{ | ||
+ | arrowpos=(isrightaligned)? Math.max(anchormeasure.left-x+10, arrowpos) : Math.max(15, arrowpos) //make sure arrow doesn't appear too far to the left of the tooltip | ||
+ | } | ||
+ | $speech.data('$arrowparts').css('left', arrowpos) | ||
+ | var speechcss_before={opacity:0, left:x, top:(istopaligned)? y-speechmeasure.h-10 : y+speechmeasure.h+10} | ||
+ | var speechcss_after={opacity:1, top:y+10} | ||
+ | if (document.all && !window.msPerformance){ //detect IE8 and below | ||
+ | delete speechcss_before.opacity //remove opacity property, as IE8- does not animate this property well with CSS triangles present | ||
+ | delete speechcss_after.opacity | ||
+ | } | ||
+ | $speech.css(speechcss_before).show().animate(speechcss_after) | ||
+ | }, | ||
- | |||
- | |||
- | |||
- | function | + | init:function($, $anchor, options){ |
- | + | var s={speechtext:$anchor.attr('title'), speechid:$anchor.attr('rel')} | |
- | + | $.extend(s, options) | |
- | var | + | if (this.buildtooltip($, s)){ |
- | + | if (s.speechtext) //if title attribute of anchor is defined | |
- | if ( | + | $anchor.attr('title', "") //disable it |
- | + | $anchor.mouseenter(function(e){ | |
- | if ( | + | if (s.$speech.queue().length==0){ |
- | + | clearTimeout(s.hidetimer) | |
- | + | speechbubbles_tooltip.positiontip($, $anchor, s, e) | |
- | + | } | |
- | + | }) | |
- | + | $anchor.mouseleave(function(e){ | |
- | + | s.hidetimer=setTimeout(function(){s.$speech.stop(true,true).hide()}, 200) | |
- | + | }) | |
- | + | } | |
- | + | } | |
- | + | ||
- | + | ||
- | } | + | |
- | } | + | |
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
} | } | ||
- | + | jQuery.fn.speechbubble=function(options){ | |
- | + | var $=jQuery | |
- | + | function processanchor(selector){ | |
- | + | return selector.each(function(){ //return jQuery obj | |
- | else | + | var $anchor=$(this) |
- | + | speechbubbles_tooltip.init($, $anchor, options) | |
+ | }) | ||
+ | } | ||
+ | if (options && options.url) | ||
+ | speechbubbles_tooltip.loadcontent($, this, options, processanchor) | ||
+ | else | ||
+ | processanchor(this) | ||
+ | }; |
Revision as of 20:41, 21 September 2011
/*Speech Bubbles Tooltip (Initial: Dec 8th, 2010)
- This notice must stay intact for usage
- Author: Dynamic Drive at http://www.dynamicdrive.com/
- Visit http://www.dynamicdrive.com/ for full source code
- /
var speechbubbles_tooltip={
loadcontent:function($, selector, options, callback){
var ajaxfriendlyurl=options.url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/")
$.ajax({
url: ajaxfriendlyurl, //path to external content
async: true,
error:function(ajaxrequest){
alert('Error fetching Ajax content.
Server Response: '+ajaxrequest.responseText)
},
success:function(content){
$(document.body).append(content)
callback(selector)
$(content).remove()
}
})
},
buildtooltip:function($, setting){ var speechtext=(setting.speechid)? $('div#'+setting.speechid).html() : setting.speechtext if (speechtext){
$speech=$('$speech.data('$arrowparts', $speech.find('div.speechbubbles-arrow, div.speechbubbles-arrow-border')) //store ref to the two arrow DIVs within tooltip var arrowheight=(window.XMLHttpRequest)? $speech.data('$arrowparts').eq(0).outerHeight() : 10 $speech.data('measure', {w:$speech.outerWidth(), h:$speech.outerHeight()+arrowheight, arroww:$speech.data('$arrowparts').eq(0).outerWidth()}) //cache tooltip dimensions $speech.css({display:'none', visibility:'visible'}) setting.$speech=$speech //remember ref to tooltip } return setting.$speech },
positiontip:function($, $anchor, s, e){
var $speech=s.$speech
var $offset=$anchor.offset()
var windowmeasure={w:$(window).width(), h:$(window).height(), left:$(document).scrollLeft(), top:$(document).scrollTop()} //get various window measurements
var anchormeasure={w:$anchor.outerWidth(), h:$anchor.outerHeight(), left:$offset.left, top:$offset.top} //get various anchor link measurements
var speechmeasure={w:$speech.data('measure').w, h:$speech.data('measure').h} //get tooltip measurements
var x=anchormeasure.left
var y=anchormeasure.top+anchormeasure.h
x=(x+speechmeasure.w>windowmeasure.left+windowmeasure.w-3)? x-speechmeasure.w+anchormeasure.w-5 : x //right align tooltip if no space to the right of the anchor
y=(y+speechmeasure.h>windowmeasure.top+windowmeasure.h)? y-speechmeasure.h-anchormeasure.h-10 : y+10 //top align tooltip if no space to the bottom of the anchor
var isrightaligned=x!=anchormeasure.left //Boolean to indicate if tooltip is right aligned
var istopaligned=y!=anchormeasure.top+anchormeasure.h+10 //Boolean to indicate if tooltip is top aligned
$speech.removeClass('downversion').addClass(istopaligned? 'downversion' : ) //add CSS "downversion" class to tooltip if arrow should be pointing down
var arrowpos=(isrightaligned)? speechmeasure.w-(anchormeasure.left+anchormeasure.w-e.pageX)-25 : e.pageX-anchormeasure.left-25 //25 is to move arrow 25px to the left so it's not obscured by cursor
if (arrowpos>speechmeasure.w-25) //if arrow exceeds the width of the tooltip
arrowpos=speechmeasure.w-40 //move it to the left of the cursor
else{
arrowpos=(isrightaligned)? Math.max(anchormeasure.left-x+10, arrowpos) : Math.max(15, arrowpos) //make sure arrow doesn't appear too far to the left of the tooltip
}
$speech.data('$arrowparts').css('left', arrowpos)
var speechcss_before={opacity:0, left:x, top:(istopaligned)? y-speechmeasure.h-10 : y+speechmeasure.h+10}
var speechcss_after={opacity:1, top:y+10}
if (document.all && !window.msPerformance){ //detect IE8 and below
delete speechcss_before.opacity //remove opacity property, as IE8- does not animate this property well with CSS triangles present
delete speechcss_after.opacity
}
$speech.css(speechcss_before).show().animate(speechcss_after)
},
init:function($, $anchor, options){
var s={speechtext:$anchor.attr('title'), speechid:$anchor.attr('rel')}
$.extend(s, options)
if (this.buildtooltip($, s)){
if (s.speechtext) //if title attribute of anchor is defined
$anchor.attr('title', "") //disable it
$anchor.mouseenter(function(e){
if (s.$speech.queue().length==0){
clearTimeout(s.hidetimer)
speechbubbles_tooltip.positiontip($, $anchor, s, e)
}
})
$anchor.mouseleave(function(e){
s.hidetimer=setTimeout(function(){s.$speech.stop(true,true).hide()}, 200)
})
}
}
}
jQuery.fn.speechbubble=function(options){ var $=jQuery function processanchor(selector){ return selector.each(function(){ //return jQuery obj var $anchor=$(this) speechbubbles_tooltip.init($, $anchor, options) }) } if (options && options.url) speechbubbles_tooltip.loadcontent($, this, options, processanchor) else processanchor(this) };