以下是 jQuery自定义方向气泡提示框代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html>
<!--[if lt IE 7 ]> <html class="no-js ie6" lang="zh"> <![endif]-->
<!--[if IE 7 ]> <html class="no-js ie7" lang="zh"> <![endif]-->
<!--[if IE 8 ]> <html class="no-js ie8" lang="zh"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="zh"> <!--<![endif]-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery自定义方向气泡提示框代码</title>
<link rel="stylesheet" href="css/grumble.min.css?v=5">
<style>
body {
font-size: 16px;
line-height: 24px;
background: #fff;
color: #330;
}
#container {
width: 690px;
margin: 50px auto;
}
p, li {
margin: 16px 0 16px 0;
width: 550px;
}
p.break {
margin-top: 35px;
}
.contact {
background: transparent;
color: #441;
}
.contact:active, .contact:hover {
background: transparent;
}
h1#demo1{
margin-top: 40px;
display:inline-block;
}
b.header {
font-size: 18px;
}
span.alias {
font-size: 14px;
font-style: italic;
margin-left: 20px;
}
table {
margin: 16px 0; padding: 0;
}
tr, td {
margin: 0; padding: 0;
}
td {
padding: 9px 15px 9px 0;
}
td.definition {
line-height: 18px;
font-size: 14px;
}
code, pre, tt {
font-family: Consolas, "Lucida Console", monospace;
font-size: 12px;
line-height: 18px;
color: #444;
}
code {
margin-left: 20px;
}
pre {
font-size: 12px;
padding: 2px 0 2px 12px;
border-left: 6px solid hotpink;
margin: 0px 0 10px;
}
li pre {
padding: 0;
border-left: 0;
margin: 6px 0 6px 0;
}
#diagram {
margin: 20px 0 0 0;
}
</style>
<style>
.ex {
display:inline-block;
width: 150px;
padding-left:10px;
height:30px;
border:1px solid #ddd;
font-size: 12px;
}
.grumble-button {
font-size:11px;
}
</style>
</head>
<body>
<div id="container">
<header>
<h1 id="demo1">grumble.js</h1>
</header>
<div id="main" role="main">
<h2>Examples</h2>
<p>下面是一组气泡动画效果,<a href="#" id="ex1">点击这里</a>来查看效果。</p>
<span class="ex" id="grumble1">没有文字</span>
<span class="ex" id="grumble2">不同的样式</span>
<span class="ex" id="grumble3">带关闭按钮</span>
<span class="ex" id="grumble4">大气泡效果</span>
<br/><br/>
<pre>
$('#grumble1').grumble(
{
text: '',
angle: 200,
distance: 3,
showAfter: 1000,
hideAfter: 2000
}
);
$('#grumble2').grumble(
{
text: 'Ohh, blue...',
angle: 180,
distance: 0,
showAfter: 2000,
type: 'alt-',
hideAfter: 2000
}
);
$('#grumble3').grumble(
{
text: 'Click me!',
angle: 150,
distance: 3,
showAfter: 3000,
hideAfter: false,
hasHideButton: true,
buttonHideText: 'Pop!'
}
);
$('#grumble4').grumble(
{
text: 'Whoaaa, this is a lot of text that i couldn\'t predict',
angle: 85,
distance: 50,
showAfter: 4000,
hideAfter: 2000,
}
);
);</pre>
</div>
<p>
Can I haz callbacks? Sure.
</p>
<pre>
$('#myElement').grumble({
showAfter: 1000,
hideAfter: 2000,
onShow: function(){
console.log('triggered when show animation completes');
},
onBeginHide: function(){
console.log('triggered when hide animation begins');
},
onHide: function () {
console.log('triggered when hide animation completes');
}
});
</pre>
<h2 id="thedarkside">The darkside of grumble.js</h2>
<p>
grumble.js 暴露了三个方法:'show'、'hide' 和 'adjust'。adjust方法可以用来更新grumble的位置或角度。
</p>
<p>
Warning: Clicking on this link may damage your <abbr title="User Experience">UX</abbr>. <a href="#" id="darkside">点击这里看看(:p)</a>
</p>
<pre>
$('#darkside').click(function(e){
var $me = $(this), interval;
e.preventDefault();
$me.grumble(
{
angle: 130,
text: 'Look at me!',
type: 'alt-',
distance: 10,
hideOnClick: true,
onShow: function(){
var angle = 130, dir = 1;
interval = setInterval(function(){
(angle > 220 ? (dir=-1, angle--) : ( angle < 130 ? (dir=1, angle++) : angle+=dir));
$me.grumble('adjust',{angle: angle});
},25);
},
onHide: function(){
clearInterval(interval);
}
}
);
});
</pre>
</div> <!-- eo #container -->
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="js/jquery.grumble.min.js?v=7"></script>
<script>
$('h1#demo1').grumble(
{
text: 'Bubble-tastic!',
angle: 85,
distance: 100,
showAfter: 500
}
);
var isSequenceComplete = true;
$('#ex1').click(function(e){
e.preventDefault();
if(isSequenceComplete === false) return true;
isSequenceComplete = false;
$('#grumble1').grumble(
{
text: '',
angle: 200,
distance: 3,
showAfter: 1000,
hideAfter: 2000
}
);
$('#grumble2').grumble(
{
text: 'Ohh, blue...',
angle: 180,
distance: 0,
showAfter: 2000,
type: 'alt-',
hideAfter: 2000
}
);
$('#grumble3').grumble(
{
text: 'Click me!',
angle: 150,
distance: 3,
showAfter: 3000,
hideAfter: false,
hasHideButton: true, // just shows the button
buttonHideText: 'Pop!'
}
);
$('#grumble4').grumble(
{
text: 'Whoaaa, this is a lot of text that i couldn\'t predict',
angle: 85,
distance: 50,
showAfter: 4000,
hideAfter: 2000,
onHide: function(){
isSequenceComplete = true;
}
}
);
});
$('#darkside').click(function(e){
var $me = $(this), interval;
e.preventDefault();
$me.grumble(
{
angle: 130,
text: 'Look at me!',
type: 'alt-',
distance: 10,
hideOnClick: true,
onShow: function(){
var angle = 130, dir = 1;
interval = setInterval(function(){
(angle > 220 ? (dir=-1, angle--) : ( angle < 130 ? (dir=1, angle++) : angle+=dir));
$me.grumble('adjust',{angle: angle});
},25);
},
onHide: function(){
clearInterval(interval);
}
}
);
});
</script>
</body>
</html>
JS代码(Bubble.js):
/** (c) 2011 James Cryer,Huddle (www.huddle.com)*/
/** http://jamescryer.github.com/grumble.js/*/
(function($,window){
var defaults ={
type:'',text:'',top:0,left:0,angle:45,size:50,distance:50,template:'<div class="grumble" style="display:none;
filter:progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\')"> 
</div>',textTemplate:'<div class="grumble-text" style="display:none;
"><div class="outer"><div class="inner">{
text}
</div></div></div>',context:null}
;
window.GrumbleBubble = function(options){
this.options = $.extend({
}
,defaults,options);
this.context = $(this.options.context || $('body'));
this.css ={
}
;
this.create();
}
;
window.GrumbleBubble.prototype ={
create:function(){
var tmpl = window.GrumbleBubble.prototype.tmpl;
this.bubble = $( tmpl(this.options.template) );
this.text = $( tmpl(this.options.textTemplate,{
text:this.options.text}
));
this.prepare();
}
,/* the rotation is adjusted because the background image defaults to what would look like 45 degrees I dont like this,the code should be agnostic of the image and style */
setBubbleRotation:function(){
this.rotateDeg = this.options.angle - 45;
if( this.rotateDeg < 0 ){
this.rotateDeg += 360;
}
}
,prepare:function(){
var isAlreadyInserted = this.bubble.get(0).parentNode;
this.setBubbleRotation();
this.applyStyles();
if( isAlreadyInserted !== this.context){
this.append();
}
this.rotate();
}
,applyStyles:function(){
this.setPosition();
this.css.width = this.options.size;
this.css.height = this.options.size;
this.text .css(this.css) .addClass('grumble-text'+this.options.size);
this.bubble .css(this.css) .addClass(this.options.type+'grumble'+this.options.size);
// remember calculated position for use by external components this.realLeft = this.css.left;
this.realTop = this.css.top;
}
,setPosition:function(){
var ratio = this.options.angle/-360,xRadius = Math.cos(ratio*2*Math.PI),yRadius = Math.sin(ratio*2*Math.PI),halfSize = this.options.size/2,sizeSquared = this.options.size*this.options.size,halfedHypotenuse = Math.sqrt(sizeSquared + sizeSquared)/2,top = (this.options.top+halfSize) - xRadius * (this.options.distance + halfedHypotenuse),left = (this.options.left-halfSize) - yRadius * (this.options.distance + halfedHypotenuse);
this.css.top = top - this.options.size;
this.css.left = left;
}
,append:function(){
var body = this.context;
this.bubble.appendTo(body);
this.text.appendTo(body);
}
,rotate:function(){
if(navigator.appName === 'Microsoft Internet Explorer' && window.document.documentMode < 10){
this.ieRotate();
}
else{
this.cssRotate();
}
}
,cssRotate:function(){
this.bubble.css({
'-moz-transform':'rotate('+this.rotateDeg+'deg)','-webkit-transform':'rotate('+this.rotateDeg+'deg)','-o-transform':'rotate('+this.rotateDeg+'deg)','transform':'rotate('+this.rotateDeg+'deg)'}
);
}
,ieRotate:function(){
var deg = this.rotateDeg,deg2radians = Math.PI * 2 / 360,rad = deg * deg2radians,costheta = Math.cos(rad),sintheta = Math.sin(rad),element = this.bubble.get(0),width,height;
// use Matrix filter element.filters.item(0).M11 = costheta;
element.filters.item(0).M12 = -sintheta;
element.filters.item(0).M21 = sintheta;
element.filters.item(0).M22 = costheta;
width = this.bubble.width();
height = this.bubble.height();
// adjust position,IE rotates from center but also increases the width and height this.bubble.css({
left:this.css.left - ((width - this.options.size)/2),top:this.css.top - ((height - this.options.size)/2)}
);
}
,adjust:function(options){
$.extend(this.options,options);
this.prepare();
}
,tmpl:function(template,obj,escapeContent){
for (var key in obj){
if (obj[key] === null) obj[key] = '';
if (typeof (obj[key]) === 'object' && obj[key].length){
obj[key] = obj[key].join(',');
}
template = template.replace(new RegExp('{
' + key + '}
','g'),escapeContent ? escape(obj[key]):obj[key]);
}
return template;
}
}
;
}
($,window));
CSS代码(grumble.min.css):
.grumble{position:absolute;background-image:url(../images/bubble-sprite.png);background-repeat:no-repeat;z-index:99999}
.grumble-text{position:absolute;text-align:center;z-index:99999;display:table;overflow:hidden;text-transform:uppercase;font-size:14px;line-height:14px}
.ie7 .grumble-text,.ie6 .grumble-text{display:block}
.grumble-text .outer{display:table-cell;vertical-align:middle;color:white}
.ie7 .grumble-text .outer,.ie6 .grumble-text .outer{display:block;width:85%;position:absolute;top:48%;left:0}
.ie7 .inner,.ie6 .inner{position:relative;top:-50%}
.grumble-text50 .outer{padding:6px}
.grumble-text100 .outer{padding:8px}
.grumble-text150 .outer{padding:10px}
.grumble-text200 .outer{padding:12px}
.grumble50{background-position:0 0}
.grumble100{background-position:0 -50px}
.grumble150{background-position:0 -150px}
.grumble200{background-position:0 -300px}
.alt-grumble50{background-position:-200px 0}
.alt-grumble100{background-position:-200px -50px}
.alt-grumble150{background-position:-200px -150px}
.alt-grumble200{background-position:-200px -300px}
.grumble-button{position:absolute;width:20px;height:12px;-moz-border-radius:3px;border-radius:3px;background:#ff5c00;color:#fff;text-align:center;font-size:.8em;line-height:.9em;-moz-box-shadow:1px 1px 1px #ccc;-webkit-box-shadow:1px 1px 1px #ccc;box-shadow:1px 1px 1px #ccc;cursor:pointer;z-index:99999}