├── .gitignore ├── Gruntfile.js ├── changelog.md ├── cluetip.jquery.json ├── demo ├── ajax.html ├── ajax2.html ├── ajax3.html ├── ajax4.html ├── ajax5.html ├── ajax6.html ├── ajaxclick.htm ├── boy-wonder.jpg ├── cross.png ├── demo.css ├── demo.js ├── grate.jpg ├── grskating.jpg ├── handovermouth.jpg ├── headbg.jpg ├── index.html ├── kids-drop-sand.jpg ├── outdoor-sculpture.jpg ├── pixel.gif ├── test-demo.html ├── tristan.jpg └── wait.gif ├── images ├── arrowdown.gif ├── arrowleft.gif ├── arrowright.gif ├── arrowup.gif ├── bl.gif ├── bl.png ├── br.gif ├── br.png ├── darrowdown.gif ├── darrowleft.gif ├── darrowright.gif ├── darrowup.gif ├── itunes.png ├── rarrowdown.gif ├── rarrowleft.gif ├── rarrowright.gif ├── rarrowup.gif ├── tl.gif ├── tl.png ├── tr.gif ├── tr.png └── wait.gif ├── index.html ├── jquery.cluetip.css ├── jquery.cluetip.js ├── jquery.cluetip.min.js ├── lib ├── jquery-1.3.2.js ├── jquery-1.7.1.min.js ├── jquery.bgiframe.js ├── jquery.bgiframe.min.js ├── jquery.compat.cluetip.css ├── jquery.compat.cluetip.js ├── jquery.hoverIntent.js ├── jquery.js └── themeswitchertool.js ├── package.json ├── readme.md └── test ├── demo ├── demo.css ├── demo.html ├── demo.js ├── files └── ajax1.html ├── index.html ├── qunit.css ├── qunit.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | demo-more* -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:false*/ 2 | 3 | module.exports = function(grunt) { 4 | 5 | // Because I'm lazy 6 | var _ = grunt.util._; 7 | 8 | // Project configuration. 9 | grunt.initConfig({ 10 | name: 'cluetip', 11 | component: './bower.json', 12 | pkg: grunt.file.readJSON('cluetip.jquery.json'), 13 | meta: { 14 | banner: '/*!<%= "\\n" %>' + 15 | ' * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + 16 | '<%= grunt.template.today("yyyy-mm-dd") + "\\n" %>' + 17 | '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' + 18 | ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>' + 19 | '<%= "\\n" %>' + 20 | ' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>' + 21 | ' (<%= _.pluck(pkg.licenses, "url").join(", ") %>)' + 22 | '<%= "\\n" %>' + ' */' + 23 | '<%= "\\n\\n" %>' 24 | }, 25 | concat: { 26 | all: { 27 | src: ['jquery.<%= pkg.name %>.js'], 28 | dest: 'jquery.<%= pkg.name %>.js' 29 | }, 30 | options: { 31 | stripBanners: { 32 | block: true 33 | }, 34 | banner: '<%= meta.banner %>' 35 | } 36 | }, 37 | uglify: { 38 | all: { 39 | files: { 40 | 'jquery.<%= pkg.name %>.min.js': ['<%= concat.all.dest %>'] 41 | }, 42 | options: { 43 | preserveComments: 'some' 44 | } 45 | } 46 | }, 47 | watch: { 48 | scripts: { 49 | files: '<%= jshint.all %>', 50 | tasks: ['jshint:all'] 51 | } 52 | }, 53 | shell: { 54 | rsync: { 55 | // command is set by setshell:rsync. 56 | stdout: true 57 | } 58 | }, 59 | setshell: { 60 | rsync: { 61 | file: 'gitignore/settings.json', 62 | cmdAppend: '<%= pkg.name %>/' 63 | } 64 | }, 65 | jshint: { 66 | all: ['Gruntfile.js', 'src/**/*.js'], 67 | options: { 68 | curly: true, 69 | // eqeqeq: true, 70 | // immed: true, 71 | latedef: true, 72 | newcap: true, 73 | noarg: true, 74 | sub: true, 75 | undef: true, 76 | boss: true, 77 | eqnull: true, 78 | browser: true, 79 | globals: { 80 | jQuery: true 81 | } 82 | } 83 | }, 84 | version: { 85 | patch: { 86 | src: [ 87 | '<%= pkg.name %>.jquery.json', 88 | 'package.json', 89 | 'jquery.<%= pkg.name %>.js' 90 | ], 91 | options: { 92 | release: 'patch' 93 | } 94 | }, 95 | same: { 96 | src: ['package.json', 'jquery.<%= pkg.name %>.js'] 97 | }, 98 | bannerPatch: { 99 | src: ['jquery.<%= pkg.name %>.js'], 100 | options: { 101 | prefix: '- v', 102 | release: 'patch' 103 | } 104 | } 105 | } 106 | }); 107 | 108 | grunt.registerMultiTask( 'setshell', 'Set grunt shell commands', function() { 109 | var settings, cmd, 110 | tgt = this.target, 111 | cmdLabel = 'shell.' + tgt + '.command', 112 | file = this.data.file, 113 | append = this.data.cmdAppend || ''; 114 | 115 | if ( !grunt.file.exists(file) ) { 116 | grunt.warn('File does not exist: ' + file); 117 | } 118 | 119 | settings = grunt.file.readJSON(file); 120 | if (!settings[tgt]) { 121 | grunt.warn('No ' + tgt + ' property found in ' + file); 122 | } 123 | 124 | cmd = settings[tgt] + append; 125 | grunt.config(cmdLabel, cmd); 126 | grunt.log.writeln( ('Setting ' + cmdLabel + ' to:').cyan ); 127 | 128 | grunt.log.writeln(cmd); 129 | 130 | }); 131 | 132 | grunt.registerTask( 'deploy', ['setshell:rsync', 'shell:rsync']); 133 | 134 | grunt.registerTask( 'component', 'Update component.json', function() { 135 | var comp = grunt.config('component'), 136 | pkg = grunt.config("pkg"), 137 | json = {}; 138 | 139 | ['name', 'version', 'dependencies'].forEach(function(el) { 140 | json[el] = pkg[el]; 141 | }); 142 | 143 | _.extend(json, { 144 | main: grunt.config('concat.all.dest'), 145 | ignore: [ 146 | 'demo/', 147 | 'lib/', 148 | 'src/', 149 | '*.json' 150 | ] 151 | }); 152 | json.name = 'jquery.' + json.name; 153 | 154 | grunt.file.write( comp, JSON.stringify(json, null, 2) ); 155 | grunt.log.writeln( "File '" + comp + "' updated." ); 156 | }); 157 | 158 | grunt.registerTask('build', ['jshint', 'concat', 'version:same', 'uglify']); 159 | grunt.registerTask('patch', ['jshint', 'concat', 'version:bannerPatch', 'version:patch', 'uglify']); 160 | grunt.registerTask('default', ['build']); 161 | 162 | grunt.loadNpmTasks('grunt-contrib-jshint'); 163 | grunt.loadNpmTasks('grunt-contrib-uglify'); 164 | grunt.loadNpmTasks('grunt-contrib-concat'); 165 | grunt.loadNpmTasks('grunt-version'); 166 | grunt.loadNpmTasks('grunt-shell'); 167 | }; 168 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | 2 | 1.2.2 / 2011-09-01 3 | ================== 4 | 5 | * fix typo when checking indexOf; remove box-shadow inline style when dropShadow option is false or dropShadowSteps is 0. 6 | * only shift off heading of tipParts if opts.showTitle is true. fixes #55 7 | * trivial cleanup 8 | -------------------------------------------------------------------------------- /cluetip.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cluetip", 3 | "version": "1.2.10", 4 | "title": "clueTip", 5 | "description": "Displays a highly customizable tooltip when the user interacts with the matched element.", 6 | "author": { 7 | "name": "Karl Swedberg", 8 | "email": "kswedberg@gmail.com", 9 | "url": "http://www.learningjquery.com/" 10 | }, 11 | "main": "jquery.cluetip.js", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/kswedberg/jquery-cluetip" 15 | }, 16 | "homepage": "http://plugins.learningjquery.com/cluetip/", 17 | "docs": "http://plugins.learningjquery.com/cluetip/", 18 | "bugs": "https://github.com/kswedberg/jquery-cluetip/issues", 19 | "demo": "http://plugins.learningjquery.com/cluetip/demo/", 20 | "licenses": [ 21 | { 22 | "type": "MIT", 23 | "url": "http://www.opensource.org/licenses/mit-license.php" 24 | } 25 | ], 26 | "dependencies": { 27 | "jquery": ">=1.3" 28 | }, 29 | "keywords": [ 30 | "jQuery", 31 | "plugin", 32 | "tooltip" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /demo/ajax.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Title 7 | 18 | 19 | 20 | 21 | 22 | 23 |

A Web Page

24 | 25 |

This is a full web page with all the trappings. It's just a little short

26 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 27 |

28 | 29 | -------------------------------------------------------------------------------- /demo/ajax2.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | some page 7 | 8 | 9 | 10 |
11 |

here is div #someid1

12 |

text is text is text is text

13 |
14 |
15 |

here is div #someid2

16 |

and more text inside the div

17 |
18 | 19 | -------------------------------------------------------------------------------- /demo/ajax3.html: -------------------------------------------------------------------------------- 1 |

This clueTip has some nicely formatted text. Just kidding! 2 |

3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/ajax4.html: -------------------------------------------------------------------------------- 1 | 2 |

Another clueTip? consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 3 |

4 | 5 | 6 | -------------------------------------------------------------------------------- /demo/ajax5.html: -------------------------------------------------------------------------------- 1 |

This is another clueTip. It is here for demonstration purposes only.

2 | Boy Wonder 3 |

Did you know that jQuery has a vibrant community of web developers and designers who discuss the library and offer help to those seeking it? You can find it at forum.jquery.com. 4 |

5 | 6 | 7 | -------------------------------------------------------------------------------- /demo/ajax6.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | sticky option 7 | 8 | 9 | 10 | 11 | Kids Drop Sand 12 |

The sticky option is really nice when you have a clueTip with a link to learningjquery.com in it (or any other site). Now, you can click the link to go somewhere else. Not that you'd want to.

13 | Kids Drop Sand 14 | 15 |

Notice that this is another example of a full web page. It even has a nice photograph in it. Twice!

16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /demo/ajaxclick.htm: -------------------------------------------------------------------------------- 1 | Boy Wonder 2 |

This clueTip won't appear unless you click to activate it. And it won't go away until you click again, or until you activate another clueTip by hovering or clicking. Only one clueTip gets to show at a time.

3 |

To learn more, visit learningjquery.com. ;-) 4 |

5 | 6 | 7 | -------------------------------------------------------------------------------- /demo/boy-wonder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/boy-wonder.jpg -------------------------------------------------------------------------------- /demo/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/cross.png -------------------------------------------------------------------------------- /demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Helvetica, Verdana, sans-serif; 3 | font-size: 95%; 4 | margin: 0; 5 | } 6 | 7 | h1 { 8 | height: 80px; 9 | font-weight: normal; 10 | padding: 20px 20px 0; 11 | margin: 0 0 .5em; 12 | color: #fff; 13 | background: #6363c1 url(headbg.jpg) repeat-x 0 0; 14 | } 15 | li { 16 | margin-top: .5em; 17 | margin-bottom: .5em; 18 | } 19 | pre, code { 20 | font-size: 1em; 21 | } 22 | pre { 23 | padding: .5em; 24 | background-color: #eef; 25 | } 26 | #navigation { 27 | float: left; 28 | list-style-type: none; 29 | margin: -60px 0 0 20px; 30 | padding-left: 0; 31 | } 32 | 33 | #navigation li { 34 | float: left; 35 | margin: 5px 0; 36 | padding: 5px 0; 37 | } 38 | #navigation a { 39 | color: #fff; 40 | background: #6565c1; 41 | padding: 5px; 42 | text-decoration: none; 43 | border: 1px solid #fff; 44 | } 45 | #navigation a.active { 46 | color: #009; 47 | background: #fff; 48 | border: 1px solid #009; 49 | border-bottom: 1px solid #fff; 50 | } 51 | #container { 52 | clear: left; 53 | padding: .5em 20px 100px 20px; 54 | } 55 | 56 | .highlight { 57 | background: #fcc; 58 | } 59 | .highlighter { 60 | background: #ff3; 61 | } 62 | .back-to-top { 63 | display: block; 64 | margin-top: 1em; 65 | width: 7em; 66 | } 67 | 68 | .float-left { 69 | float: left; 70 | margin-right: .5em; 71 | display: inline; 72 | position: relative; 73 | } 74 | .float-right { 75 | float: right; 76 | margin-left: .5em; 77 | display: inline; 78 | position: relative; 79 | } 80 | h2 { 81 | font-size: 1.1em; 82 | } 83 | h3 { 84 | margin-top: 0; 85 | padding-top: 1em; 86 | } 87 | h4 { 88 | margin: .5em 0; 89 | } 90 | a { 91 | color: #009; 92 | } 93 | .html, .jquery { 94 | margin-top: .5em; 95 | color: #900; 96 | cursor: pointer; 97 | font-size: .9em; 98 | width: 8.5em; 99 | } 100 | 101 | ul li { 102 | margin: .5em 0; 103 | } 104 | ins { 105 | text-decoration: none; 106 | color: #090; 107 | } 108 | #jqlogo { 109 | position:absolute; 110 | top: 10px; 111 | right: 10px; 112 | } 113 | #jqlogo img { 114 | border: 0; 115 | } -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | 2 | /* the next line is an example of how you can override default options globally (currently commented out) ... */ 3 | 4 | // $.fn.cluetip.defaults.tracking = true; 5 | // $.fn.cluetip.defaults.width = 'auto'; 6 | // $.fn.cluetip.defaults.sticky = true; 7 | // $.fn.cluetip.defaults.arrows = true; 8 | 9 | $(document).ready(function() { 10 | 11 | // $.cluetip.setup({insertionType: 'insertBefore', insertionElement: 'div:first'}); 12 | // $.fn.cluetip.defaults.ajaxSettings.beforeSend = function(ct) { 13 | // console.log(this); 14 | // }; 15 | 16 | //default theme 17 | $('a.title').cluetip({splitTitle: '|'}); 18 | $('a.basic').cluetip(); 19 | $('a.custom-width').cluetip({width: '200px', showTitle: false}); 20 | $('h4').cluetip({attribute: 'id', hoverClass: 'highlight'}); 21 | $('#sticky').cluetip({sticky: true, closePosition: 'title', arrows: true }); 22 | $('#examples a:eq(5)').cluetip({ 23 | hoverClass: 'highlight', 24 | sticky: true, 25 | closePosition: 'bottom', 26 | closeText: 'close', 27 | truncate: 60 28 | }); 29 | $('a.load-local').cluetip({local:true, hideLocal: true, sticky: true, arrows: true, cursor: 'pointer'}); 30 | $('#clickme').cluetip({activation: 'click', sticky: true, width: 650}); 31 | $('ol:first a:last').cluetip({tracking: true}); 32 | 33 | // jTip theme 34 | $('a.jt:eq(0)').cluetip({ 35 | cluetipClass: 'jtip', 36 | arrows: true, 37 | dropShadow: false, 38 | sticky: true, 39 | mouseOutClose: true, 40 | closePosition: 'title', 41 | closeText: 'close' 42 | }); 43 | $('a.jt:eq(1)').cluetip({cluetipClass: 'jtip', arrows: true, dropShadow: false, hoverIntent: false}); 44 | $('span[title]').css({borderBottom: '1px solid #900'}).cluetip({splitTitle: '|', arrows: true, dropShadow: false, cluetipClass: 'jtip'}); 45 | 46 | $('a.jt:eq(2)').cluetip({ 47 | cluetipClass: 'jtip', 48 | arrows: true, 49 | dropShadow: false, 50 | height: '150px', 51 | sticky: true, 52 | positionBy: 'bottomTop' 53 | }); 54 | 55 | $('a.jt:eq(3)').cluetip({local: true, hideLocal: false}); 56 | 57 | $('a.jt:eq(4)').cluetip({ 58 | cluetipClass: 'jtip', arrows: true, 59 | dropShadow: false, 60 | onActivate: function(e) { 61 | var cb = $('#cb')[0]; 62 | return !cb || cb.checked; 63 | } 64 | }); 65 | 66 | // Rounded Corner theme 67 | $('ol.rounded a:eq(0)').cluetip({arrows: true, sticky: true, splitTitle: '|', cluetipClass: 'rounded', showTitle: false}); 68 | $('ol.rounded a:eq(1)').cluetip({cluetipClass: 'rounded', dropShadow: false, showTitle: false, positionBy: 'mouse'}); 69 | $('ol.rounded a:eq(2)').cluetip({cluetipClass: 'rounded', dropShadow: false, showTitle: false, positionBy: 'bottomTop', topOffset: 70}); 70 | $('ol.rounded a:eq(3)').cluetip({cluetipClass: 'rounded', dropShadow: false, sticky: true, ajaxCache: false}); 71 | $('ol.rounded a:eq(4)').cluetip({cluetipClass: 'rounded', dropShadow: false}); 72 | }); 73 | 74 | //unrelated to clueTip -- just for the demo page... 75 | 76 | $(document).ready(function() { 77 | $('div.html, div.jquery').next().css('display', 'none').end().click(function() { 78 | $(this).next().toggle('fast'); 79 | }); 80 | 81 | $('a.false').click(function() { 82 | return false; 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /demo/grate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/grate.jpg -------------------------------------------------------------------------------- /demo/grskating.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/grskating.jpg -------------------------------------------------------------------------------- /demo/handovermouth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/handovermouth.jpg -------------------------------------------------------------------------------- /demo/headbg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/headbg.jpg -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | clueTip Plugin Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

clueTip : A jQuery Plugin

17 | 26 |
27 |
28 |

clueTip Plugin Demo

29 |

Below are quite a few examples of how you can add a clueTip to your page, using a wide range of options. Keep in mind that there is nothing magical about the HTML markup. You can use any jQuery selector you want to attach your clueTips. For example, if you want to attach clueTips to all links with a class of "peanuts," you would simply write in your jQuery code: $('a.peanuts').cluetip();.

30 |

Default Style

31 |
32 |
    33 |
  1. basic tip from title: This example pulls the clueTip's contents from the invoking element's title attribute via the "splitTitle" option. 34 |
    View the HTML
    35 |
    <a class="title" href="#" title="This is the title|The first set of contents comes after the first delimiter in the title.|In this case, the delimiter is a pipe">
    36 |
    View the jQuery
    37 |
    $('a.title').cluetip({splitTitle: '|'});
    38 |
  2. 39 |
  3. basic ajax, with no title attribute: This one requires no options. 40 |
    41 |
    View the HTML
    42 |
    <a class="basic" href="ajax.html" rel="ajax.html">
    43 |
    View the jQuery
    44 |
    $('a.basic').cluetip();
    45 |
  4. 46 |
  5. custom width and hidden title bar: This tip has a custom width of 200px. The clueTip title bar (heading) is hidden. Try me! 47 |
    View the HTML
    48 |
    <a class="custom-width" href="ajax3.html" rel="ajax3.html">
    49 |
    View the jQuery
    50 |
    $('a.custom-width').cluetip({width: '200px', showTitle: false});
    51 |
  6. 52 |
  7. sticky, with arrows:This sticky clueTip has its "close" text in the title bar. It won't close until you close it, or until you hover over another clue-tipped link. It also displays an arrow on one of its sides, pointing to the invoking element. sticky clueTip with arrows 53 |
    View the HTML
    54 |
    <a id="sticky" href="ajax6.html" rel="ajax6.html">
    55 |
    View the jQuery
    56 |
    $('#sticky').cluetip({sticky: true, closePosition: 'title', arrows: true});
    57 |
  8. 58 | 59 |
  9. non-link element, custom attribute, and hover class: Block-level items such as this h4 have clueTips positioned by the mouse. 60 |

    Hover over me.

    61 |
    View the HTML
    62 |
    <h4 title="Fancy Title!" id="ajax3.html">Hover over me</h4>
    63 |
    View the jQuery
    64 |
    $('h4').cluetip({attribute: 'id', hoverClass: 'highlight'});
    65 |
  10. 66 |
  11. local, with arrows: This one uses local content from a hidden div element and displays an arrow that points to the invoking element: hover for local 67 |
    View the HTML
    68 |
    <a class="load-local" href="#loadme" rel="#loadme">
    69 |
    View the jQuery
    70 |
    $('a.load-local').cluetip({local:true, cursor: 'pointer'});
    71 |
  12. 72 |
  13. sticky, truncated clueTip with custom hover class, close position, and close text (it also has a title). Its href is different from its rel, so if you click it, you'll go to the linked page hover for cluetip, click to visit URL 73 |
    View the HTML
    74 |
    <a href="http://www.learningjquery.com" title="about this link:" rel="ajax6.html">
    75 |
    View the jQuery
    76 |
    $('#examples a:eq(5)').cluetip({
     77 |   hoverClass: 'highlight',
     78 |   sticky: true,
     79 |   closePosition: 'bottom',
     80 |   closeText: '<img src="styles/cross.png" alt="" />'
     81 |   truncate: 60
     82 | });
    83 |
  14. 84 |
  15. click to activate: This one won't show the clueTip unless you click it: click me. It's also really wide. 85 |
    View the HTML
    86 |
    <a href="ajaxclick.htm" rel="ajax5.html" title="active ingredients">
    87 |
    View the jQuery
    88 |
    $('#clickme').cluetip({activation: 'click', width: 650});
    89 |
  16. 90 |
  17. experimental mouse tracking: The clueTip will move in the direction of your mouse movement, as long as you're still hovering over the invoking element. 91 |
    View the HTML
    92 |
    <a href="ajax5.html" title="mouse tracks" rel="ajax5.html">
    93 |
    View the jQuery
    94 |
    $('ol:first a:last').cluetip({tracking: true});
    95 |
  18. 96 |
97 |

jTip Theme

98 |
    99 |
  1. jTip Style clueTip, with slideDown effect and an image placed in the title for closing it, because it's sticky.
    100 | New: The clueTip will close if you mouse out of it. 101 |
    View the HTML
    102 |
    <a class="jt" href="ajax6.html" rel="ajax6.html" title="jTip Style!">
    103 |
    View the jQuery
    104 |
    $('a.jt:eq(0)').cluetip({
    105 |   cluetipClass: 'jtip',
    106 |   arrows: true,
    107 |   dropShadow: false,
    108 |   hoverIntent: false,
    109 |   sticky: true,
    110 |   mouseOutClose: true,
    111 |   closePosition: 'title',
    112 |   closeText: '<img src="cross.png" alt="close" />'
    113 | });
    114 | 
    115 |
  2. 116 |
  3. This one has hoverIntent turned off. Look for the link floated right: jTip Style clueTip 117 |
    View the HTML
    118 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    119 |
    View the jQuery
    120 |
    $('a.jt:eq(1)').cluetip({cluetipClass: 'jtip', arrows: true, dropShadow: false, hoverIntent: false});
    121 | 
    122 |
  4. 123 |
  5. This one pulls the clueTip contents directly from the title attribute of a span tag: splitTitle clueTip 124 |
    View the HTML
    125 | <span title="Split Title|This clueTip's contents were created directly from the title attribute|Nice for minimum info."> 126 |
    View the jQuery
    127 |
    $('span[title]').css({borderBottom: '1px solid #900'}).cluetip({
    128 |   splitTitle: '|',
    129 |   arrows: true,
    130 |   dropShadow: false,
    131 |   cluetipClass: 'jtip'}
    132 | );
    133 |
  6. 134 |
  7. this sticky clueTip has a fixed height. It's generally a good idea to make fixed-height clueTips sticky as well, just in case the content requires a scrollbar to read it fully. It will be positioned below the clicked element unless there isn't enough room, in which case it will be positioned above. 135 |
    View the HTML
    136 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    137 |
    View the jQuery
    138 |
    $('a.jt:eq(2)').cluetip({
    139 |   cluetipClass: 'jtip', arrows: true,
    140 |   dropShadow: false,
    141 |   height: '150px',
    142 |   sticky: true,
    143 |   positionBy: 'bottomTop'
    144 | });
    145 |
  8. 146 |
  9. For this one, we're loading visible local content 147 |
    View the HTML
    148 |
    <a class="jt" href="#" rel="p.localvisible">visible local content</a>
    149 |
    View the jQuery
    150 |
    $('a.jt:eq(3)').cluetip({local: true, hideLocal: false});
    151 |

    and here is our visible local content!

    152 |
  10. 153 |
  11. togglable clueTip can be turned off by unchecking the checkbox
    154 | 155 |
    View the HTML
    156 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    157 |
    View the jQuery
    158 |
    $('a.jt:eq(3)').cluetip({
    159 |   cluetipClass: 'jtip', arrows: true,
    160 |   dropShadow: false,
    161 |   onActivate: function(e) {
    162 |     var cb = $('#cb')[0];
    163 |     return !cb || cb.checked;
    164 |   }
    165 | });
    166 |
  12. 167 |
168 |

Rounded Corners Theme

169 |
    170 |
  1. content from title attribute, with the clueTip heading hidden. 171 |
    View the HTML
    172 |
    <a href="ajax4.html" title="|first line body|second line body">
    173 |
    View the jQuery
    174 |
    $('ol.rounded a:eq(0)').cluetip({arrows: true, sticky: true, splitTitle: '|', cluetipClass: 'rounded', showTitle: false});
    175 |
  2. 176 |
  3. 177 | rounded corners theme and positioning by mouse. 178 |
    View the HTML
    179 |
    <a href="ajax4.html" rel="ajax4.html" title="mouse positioned">
    180 |
    View the jQuery
    181 |
    $('ol.rounded a:eq(1)').cluetip({
    182 |   cluetipClass: 'rounded',
    183 |   dropShadow: false,
    184 |   positionBy: 'mouse'
    185 | });
    186 |
  4. 187 |
  5. Another one with rounded corners theme. This one has "bottomTop" positioning: positioned under link, unless there isn't enough room (then over). It also has "topOffset" set to 70. 188 |
    View the HTML
    189 |
    <a href="ajax4.html" rel="ajax4.html" title="bottom/top positioned">
    190 |
    View the jQuery
    191 |
    $('ol.rounded a:eq(2)').cluetip({cluetipClass: 'rounded', dropShadow: false, positionBy: 'bottomTop', topOffset: 70});
    192 |
  6. 193 |
  7. non-caching ajax clueTip. 194 |
    View the HTML
    195 |
    <a href="ajax4.html" rel="ajax4.html" title="rounded corners">
    196 |
    View the jQuery
    197 |
    $('ol.rounded a:eq(3)').cluetip({cluetipClass: 'rounded', dropShadow: false, sticky: true, ajaxCache: false});
    198 |
  8. 199 |
  9. ajax error: This one points to a file that does not exist. 200 |
    View the HTML
    201 |
    <a href="ajax404.htm" rel="ajax404.htm">
    202 |
    View the jQuery
    203 |
    $('ol.rounded a:eq(4)').cluetip({cluetipClass: 'rounded', dropShadow: false});
    204 |
  10. 205 |
206 | 207 |
208 | 209 |
this is the local content to load when the 'local' parameter is set to true.
210 |
211 | 212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /demo/kids-drop-sand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/kids-drop-sand.jpg -------------------------------------------------------------------------------- /demo/outdoor-sculpture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/outdoor-sculpture.jpg -------------------------------------------------------------------------------- /demo/pixel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/pixel.gif -------------------------------------------------------------------------------- /demo/test-demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | clueTip Plugin Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

clueTip : A jQuery Plugin

20 | 29 |
30 |
31 |
32 |

clueTip Plugin Demo

33 |

Below are quite a few examples of how you can add a clueTip to your page, using a wide range of options. Keep in mind that there is nothing magical about the HTML markup. You can use any jQuery selector you want to attach your clueTips. For example, if you want to attach clueTips to all links with a class of "peanuts," you would simply write in your jQuery code: $('a.peanuts').cluetip();.

34 |

Default Style

35 |
36 |
    37 |
  1. basic tip from title: This example pulls the clueTip's contents from the invoking element's title attribute via the "splitTitle" option. 38 |
    View the HTML
    39 |
    <a class="title" href="#" title="This is the title|The first set of contents comes after the first delimiter in the title.|In this case, the delimiter is a pipe">
    40 |
    View the jQuery
    41 |
    $('a.title').cluetip({splitTitle: '|'});
    42 |
  2. 43 |
  3. basic ajax, with no title attribute: This one requires no options. 44 |
    45 |
    View the HTML
    46 |
    <a class="basic" href="ajax.html" rel="ajax.html">
    47 |
    View the jQuery
    48 |
    $('a.basic').cluetip();
    49 |
  4. 50 |
  5. custom width and hidden title bar: This tip has a custom width of 200px. The clueTip title bar (heading) is hidden. Try me! 51 |
    View the HTML
    52 |
    <a class="custom-width" href="ajax3.html" rel="ajax3.html">
    53 |
    View the jQuery
    54 |
    $('a.custom-width').cluetip({width: '200px', showTitle: false});
    55 |
  6. 56 |
  7. sticky, with arrows:This sticky clueTip has its "close" text in the title bar. It won't close until you close it, or until you hover over another clue-tipped link. It also displays an arrow on one of its sides, pointing to the invoking element. sticky clueTip with arrows 57 |
    View the HTML
    58 |
    <a id="sticky" href="ajax6.html" rel="ajax6.html">
    59 |
    View the jQuery
    60 |
    $('#sticky').cluetip({sticky: true, closePosition: 'title', arrows: true});
    61 |
  8. 62 | 63 |
  9. non-link element, custom attribute, and hover class: Block-level items such as this h4 have clueTips positioned by the mouse. 64 |

    Hover over me.

    65 |
    View the HTML
    66 |
    <h4 title="Fancy Title!" id="ajax3.html">Hover over me</h4>
    67 |
    View the jQuery
    68 |
    $('h4').cluetip({attribute: 'id', hoverClass: 'highlight'});
    69 |
  10. 70 |
  11. local, with arrows: This one uses local content from a hidden div element and displays an arrow that points to the invoking element: hover for local 71 |
    View the HTML
    72 |
    <a class="load-local" href="#loadme" rel="#loadme">
    73 |
    View the jQuery
    74 |
    $('a.load-local').cluetip({local:true, cursor: 'pointer'});
    75 |
  12. 76 |
  13. sticky, truncated clueTip with custom hover class, close position, and close text (it also has a title). Its href is different from its rel, so if you click it, you'll go to the linked page hover for cluetip, click to visit URL 77 |
    View the HTML
    78 |
    <a href="http://www.learningjquery.com" title="about this link:" rel="ajax6.html">
    79 |
    View the jQuery
    80 |
    $('#examples a:eq(5)').cluetip({
     81 |   hoverClass: 'highlight',
     82 |   sticky: true,
     83 |   closePosition: 'bottom',
     84 |   closeText: '<img src="styles/cross.png" alt="" />'
     85 |   truncate: 60
     86 | });
    87 |
  14. 88 |
  15. click to activate: This one won't show the clueTip unless you click it: click me. It's also really wide. 89 |
    View the HTML
    90 |
    <a href="ajaxclick.htm" rel="ajax5.html" title="active ingredients">
    91 |
    View the jQuery
    92 |
    $('#clickme').cluetip({activation: 'click', width: 650});
    93 |
  16. 94 |
  17. experimental mouse tracking: The clueTip will move in the direction of your mouse movement, as long as you're still hovering over the invoking element. 95 |
    View the HTML
    96 |
    <a href="ajax5.html" title="mouse tracks" rel="ajax5.html">
    97 |
    View the jQuery
    98 |
    $('ol:first a:last').cluetip({tracking: true});
    99 |
  18. 100 |
101 |

jTip Theme

102 |
    103 |
  1. jTip Style clueTip, with slideDown effect and an image placed in the title for closing it, because it's sticky.
    104 | New: The clueTip will close if you mouse out of it. 105 |
    View the HTML
    106 |
    <a class="jt" href="ajax6.html" rel="ajax6.html" title="jTip Style!">
    107 |
    View the jQuery
    108 |
    $('a.jt:eq(0)').cluetip({
    109 |   cluetipClass: 'jtip', 
    110 |   arrows: true, 
    111 |   dropShadow: false,
    112 |   hoverIntent: false,
    113 |   sticky: true,
    114 |   mouseOutClose: true,
    115 |   closePosition: 'title',
    116 |   closeText: '<img src="cross.png" alt="close" />'
    117 | });
    118 | 
    119 |
  2. 120 |
  3. This one has hoverIntent turned off. Look for the link floated right: jTip Style clueTip 121 |
    View the HTML
    122 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    123 |
    View the jQuery
    124 |
    $('a.jt:eq(1)').cluetip({cluetipClass: 'jtip', arrows: true, dropShadow: false, hoverIntent: false});
    125 | 
    126 |
  4. 127 |
  5. This one pulls the clueTip contents directly from the title attribute of a span tag: splitTitle clueTip 128 |
    View the HTML
    129 | <span title="Split Title|This clueTip's contents were created directly from the title attribute|Nice for minimum info."> 130 |
    View the jQuery
    131 |
    $('span[title]').css({borderBottom: '1px solid #900'}).cluetip({
    132 |   splitTitle: '|', 
    133 |   arrows: true, 
    134 |   dropShadow: false, 
    135 |   cluetipClass: 'jtip'}
    136 | );
    137 |
  6. 138 |
  7. this sticky clueTip has a fixed height. It's generally a good idea to make fixed-height clueTips sticky as well, just in case the content requires a scrollbar to read it fully. It will be positioned below the clicked element unless there isn't enough room, in which case it will be positioned above. 139 |
    View the HTML
    140 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    141 |
    View the jQuery
    142 |
    $('a.jt:eq(2)').cluetip({
    143 |   cluetipClass: 'jtip', arrows: true, 
    144 |   dropShadow: false, 
    145 |   height: '150px', 
    146 |   sticky: true,
    147 |   positionBy: 'bottomTop'
    148 | });
    149 |
  8. 150 |
  9. For this one, we're loading visible local content 151 |
    View the HTML
    152 |
    <a class="jt" href="#" rel="p.localvisible">visible local content</a>
    153 |
    View the jQuery
    154 |
    $('a.jt:eq(3)').cluetip({local: true, hideLocal: false});
    155 |

    and here is our visible local content!

    156 |
  10. 157 |
  11. togglable clueTip can be turned off by unchecking the checkbox
    158 | 159 |
    View the HTML
    160 |
    <a class="jt" href="ajax5.html" rel="ajax5.html">
    161 |
    View the jQuery
    162 |
    $('a.jt:eq(3)').cluetip({
    163 |   cluetipClass: 'jtip', arrows: true, 
    164 |   dropShadow: false, 
    165 |   onActivate: function(e) {
    166 |     var cb = $('#cb')[0];
    167 |     return !cb || cb.checked;
    168 |   }
    169 | });
    170 |
  12. 171 |
172 |

Rounded Corners Theme

173 |
    174 |
  1. content from title attribute, with the clueTip heading hidden. 175 |
    View the HTML
    176 |
    <a href="ajax4.html" title="|first line body|second line body">
    177 |
    View the jQuery
    178 |
    $('ol.rounded a:eq(0)').cluetip({splitTitle: '|', dropShadow: false, cluetipClass: 'rounded', showTitle: false});
    179 |
  2. 180 |
  3. 181 | rounded corners theme and positioning by mouse. 182 |
    View the HTML
    183 |
    <a href="ajax4.html" rel="ajax4.html" title="mouse positioned">
    184 |
    View the jQuery
    185 |
    $('ol.rounded a:eq(1)').cluetip({
    186 |   cluetipClass: 'rounded', 
    187 |   dropShadow: false, 
    188 |   positionBy: 'mouse'
    189 | });
    190 |
  4. 191 |
  5. Another one with rounded corners theme. This one has "bottomTop" positioning: positioned under link, unless there isn't enough room (then over). It also has "topOffset" set to 70. 192 |
    View the HTML
    193 |
    <a href="ajax4.html" rel="ajax4.html" title="bottom/top positioned">
    194 |
    View the jQuery
    195 |
    $('ol.rounded a:eq(2)').cluetip({cluetipClass: 'rounded', dropShadow: false, positionBy: 'bottomTop', topOffset: 70});
    196 |
  6. 197 |
  7. non-caching ajax clueTip with arrows enabled. 198 |
    View the HTML
    199 |
    <a href="ajax4.html" rel="ajax4.html" title="rounded corners">
    200 |
    View the jQuery
    201 |
    $('ol.rounded a:eq(3)').cluetip({cluetipClass: 'rounded', dropShadow: false, sticky: true, ajaxCache: false, arrows: true});
    202 |
  8. 203 |
  9. ajax error: This one points to a file that does not exist. 204 |
    View the HTML
    205 |
    <a href="ajax404.htm" rel="ajax404.htm">
    206 |
    View the jQuery
    207 |
    $('ol.rounded a:eq(4)').cluetip({cluetipClass: 'rounded', dropShadow: false});
    208 |
  10. 209 |
210 | 211 |
212 | 213 |
this is the local content to load when the 'local' parameter is set to true.
214 |
215 | 216 |
217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /demo/tristan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/tristan.jpg -------------------------------------------------------------------------------- /demo/wait.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/demo/wait.gif -------------------------------------------------------------------------------- /images/arrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/arrowdown.gif -------------------------------------------------------------------------------- /images/arrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/arrowleft.gif -------------------------------------------------------------------------------- /images/arrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/arrowright.gif -------------------------------------------------------------------------------- /images/arrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/arrowup.gif -------------------------------------------------------------------------------- /images/bl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/bl.gif -------------------------------------------------------------------------------- /images/bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/bl.png -------------------------------------------------------------------------------- /images/br.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/br.gif -------------------------------------------------------------------------------- /images/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/br.png -------------------------------------------------------------------------------- /images/darrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/darrowdown.gif -------------------------------------------------------------------------------- /images/darrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/darrowleft.gif -------------------------------------------------------------------------------- /images/darrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/darrowright.gif -------------------------------------------------------------------------------- /images/darrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/darrowup.gif -------------------------------------------------------------------------------- /images/itunes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/itunes.png -------------------------------------------------------------------------------- /images/rarrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/rarrowdown.gif -------------------------------------------------------------------------------- /images/rarrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/rarrowleft.gif -------------------------------------------------------------------------------- /images/rarrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/rarrowright.gif -------------------------------------------------------------------------------- /images/rarrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/rarrowup.gif -------------------------------------------------------------------------------- /images/tl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/tl.gif -------------------------------------------------------------------------------- /images/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/tl.png -------------------------------------------------------------------------------- /images/tr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/tr.gif -------------------------------------------------------------------------------- /images/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/tr.png -------------------------------------------------------------------------------- /images/wait.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kswedberg/jquery-cluetip/0cb2b10e8e1e0158e73d3d6a21788cf44946bbc3/images/wait.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | clueTip: A jQuery Tooltip Plugin 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 22 | 23 | 24 |

‹‹ homeclueTip: A jQuery Tooltip Plugin

25 |
26 | 27 | 36 | 37 |

Now ThemeRoller Ready (as of clueTip 1.1).

38 |
39 |

Important: This plugin is no longer being maintained.

40 | 41 |

I originally wrote clueTip back in 2006 as my first attempt at a jQuery plugin. If I were to write it now, I would do it completely differently. However, I don't have the time or energy to work on it. The good news is that you can use any one of a number of better tooltip plugins. Here are a few:

42 | 47 |

Overview

48 |

The clueTip plugin allows you to easily show a fancy tooltip when the user's mouse hovers over (or, optionally, clicks on) any element you designate in your script. If the element includes a title attribute, its text becomes the heading of the clueTip.

49 |

If you like this plugin and you're feeling generous, perhaps you'd also like to visit my amazon.com wish list?

50 |

Quick Start Guide

51 | Showing the most basic clueTip can be achieved in two easy steps. 52 |
Add HTML markup to your page for elements that you want to invoke a clueTip. By default, the clueTip plugin will use the rel attribute to load contents into the tooltip body via AHAH.
53 |

 54 |   <!-- use ajax/ahah to pull content from fragment.html: -->
 55 |   <p><a class="tips" href="fragment.html" rel="fragment.html">show me the cluetip!</a></p>
 56 | 
 57 |   <!-- use title attribute for clueTip contents, but don't include anything in the clueTip's heading -->
 58 |   <p><a id="houdini" href="houdini.html" title="|Houdini was an escape artist.|He was also adept at prestidigitation.">Houdini</a></p>
 59 | 
60 |
Include the jQuery core file and the clueTip plugin in the <head> of your document. You may optionally include the hoverIntent plugin as well. After these scripts are referenced, you can reference a custom script file to invoke your clueTips (preferred) or enter the script directly in the <head> (shown below). You should also include the clueTip stylesheet (jquery.cluetip.css) after the scripts.
61 |
62 |
<script src="jquery.js" type="text/javascript"></script>
 63 | <script src="jquery.hoverIntent.js" type="text/javascript"></script> <!-- optional -->
 64 | <script src="jquery.cluetip.js" type="text/javascript"></script>
 65 | 
 66 | <script type="text/javascript">
 67 | $(document).ready(function() {
 68 |   $('a.tips').cluetip();
 69 | 
 70 |   $('#houdini').cluetip({
 71 |     splitTitle: '|', // use the invoking element's title attribute to populate the clueTip...
 72 |                      // ...and split the contents into separate divs where there is a "|"
 73 |     showTitle: false // hide the clueTip's heading
 74 |   });
 75 | });
 76 | </script>
 77 | <link rel="stylesheet" href="jquery.cluetip.css" type="text/css" />
 78 | 
79 |

You can change the default style and behavior in many ways. See API / Options for details.

80 |
81 |
82 |
83 |

This plugin is no longer being maintained.

84 |

See the overview for a list of alternative tooltip plugins.

85 |

clueTip Plugin Features

86 |
87 | 93 | 94 |
95 |

Multiple Content Sources

96 |

The contents of the clueTip can come from one of these sources:

97 |
    98 |
  1. a separate file, via AHAH / AJAX
  2. 99 |
  3. an element on the same page, typically hidden
  4. 100 |
  5. the title attribute, parsed by a user-defined delimiter (if the "splitTitle" option is set). The text before the first delimiter becomes the clueTip title, and the rest of the text parts are placed in <div class="split-body"></div> elements and appended to the clueTip body
  6. 101 |
  7. the return value of a function referenced in the first argument of .cluetip().
  8. 102 |
103 |
104 |
105 |

Smart Positioning

106 | The clueTip Plugin has 4 positioning modes, which you can change via the "positionBy" option. 107 |
    108 |
  1. positionBy: 'auto' (default) 109 |
      110 |
    • places the tooltip just to the right of the invoking element, but...
    • 111 |
    • if there is not enough room for the tooltip to be fully visible between the right edge of the invoking element and the right edge of the browser window, switches from the right side to the left side, but...
    • 112 |
    • if the invoking element is too close to the bottom edge of the browser window, adjusts the tooltip upwards until the whole tooltip is visible, but...
    • 113 |
    • if the tooltip is taller than the window (i.e. the viewable area), adjusts the tooltip back down until the tooltip's top is at the top edge of the browser window, but...
    • 114 |
    • position if the invoking element is so wide that the tooltip can't completely fit to the left or the right of it, places the tooltip to the right or left of the mouse, but...
    • 115 |
    • if the tooltip itself can't fit to the right or left of the mouse position, places the tooltip below the mouse position (centered horizontal if enough room), but...
    • 116 |
    • if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, puts the tooltip above the mouse position
    • 117 |
    118 |
  2. 119 |
  3. positionBy: 'mouse' 120 |
      121 |
    • places the tooltip to the right of the mouse position, but...
    • 122 |
    • if there is not enough room to the right, places the tooltip to the left of the mouse position, but...
    • 123 |
    • if the tooltip itself can't fit to the right or left of the mouse position, places the tooltip below the mouse position (centered horizontally if enough room), but...
    • 124 |
    • if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, puts the tooltip above the mouse position
    • 125 |
    126 |
  4. 127 |
  5. positionBy: 'bottomTop' 128 |
      129 |
    • places the tooltip below the mouse position (centered horizontally if enough room), but...
    • 130 |
    • if (a) there isn't enough room below without being cut off, and (b) there is enough room between the top of the viewable area and the mouse, puts the tooltip above the mouse position
    • 131 |
    132 |
  6. 133 |
  7. positionBy: 'fixed' 134 |
      135 |
    • places the tooltip in the same location relative to the invoking element, regardless of where it appears on the page.
    • 136 |
    • the fixed position can be adjusted by modifying the number of pixels in the topOffset and leftOffset options
    • 137 |
    138 |
  8. 139 |
140 |
141 |
142 |

Flexible Behavior

143 |
    144 |
  1. The clueTip takes advantage of Brian Cherne's hoverIntent plugin if it's available. (Just include it in a <script> tag if you want the clueTip to use it.)
  2. 145 |
  3. It can be activated on hover or on click.
  4. 146 |
  5. It can fade in, slide down, etc.
  6. 147 |
  7. It can close when the invoking element is moused out or when the tooltip is moused out or when the user clicks a "close" link.
  8. 148 |
  9. It can cache the results of ajax requests—or not.
  10. 149 |
  11. It can be turned off
  12. 150 |
151 |
152 |
153 |

Variety of Styles

154 |

The clueTip Plugin comes with three themes: default, jTip, and rounded corners. Additional themes can be created by following the naming patterns in the stylesheet, jquery.cluetip.css. To apply one of the alternative themes, just indicate it in the cluetipClass option as 'jtip' or 'rounded'.

155 |

The "loading" image comes from this rule in the stylesheet:

156 |
#cluetip-waitimage {
157 |       width: 43px;
158 |       height: 11px;
159 |       position: absolute;
160 |       background-image: url(wait.gif);
161 |     }
162 |

It can be turned off with the following option: waitImage: false

163 |

Other options that affect the visual appearance include hoverClass, arrows, dropShadow, and dropShadowSteps. Please see API / Options for more information.

164 |
165 |
166 |
167 |
168 |

This plugin is no longer being maintained.

169 |

See the overview for a list of alternative tooltip plugins.

170 | 171 |

clueTip Plugin API / Options

172 | The clueTip Plugin API provides two methods, with many options. It also provides a custom event for closing the tooltip programmatically 173 |
174 |
$.cluetip.setup(options)
175 |
Global defaults for clueTips. Will apply to all calls to the clueTip plugin.
176 |
177 |
{
178 |           insertionType:    'appendTo', // how the clueTip is inserted into the DOM
179 |                                         // possible values: 'appendTo', 'prependTo', 'insertBefore', 'insertAfter'
180 |           insertionElement: 'body'      // where in the DOM the clueTip is to be inserted
181 |         }
182 |
183 |
.cluetip(options)
184 |
Displays a highly customizable tooltip via ajax (default) or local content or the title attribute of the invoking element
185 |
186 |
$.fn.cluetip.defaults = {  // default options; override as needed
187 |     multiple:         false,    // Allow a new tooltip to be created for each .cluetip() call
188 |     width:            275,      // The width of the clueTip
189 |     height:           'auto',   // The height of the clueTip. more info below [1]
190 |     cluezIndex:       97,       // Sets the z-index style property of the clueTip
191 |     positionBy:       'auto',   // Sets the type of positioning. more info below [2]
192 |     topOffset:        15,       // Number of px to offset clueTip from top of invoking element. more info below [3]
193 |     leftOffset:       15,       // Number of px to offset clueTip from left of invoking element. more info below [4]
194 |     local:            false,    // Whether to use content from the same page for the clueTip's body
195 |                                 // (treats the attribute used for accessing the tip as a jQuery selector,
196 |                                 // but only selects the first element if the selector matches more than one). more info below [5]
197 |     hideLocal:        true,     // If local option is set to true, this determines whether local content
198 |                                 //  to be shown in clueTip should be hidden at its original location
199 |     localPrefix:      null,       // string to be prepended to the tip attribute if local is true
200 |     localIdSuffix:    null,     // string to be appended to the cluetip content element's id if local is true
201 |     attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
202 |     titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
203 |     splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
204 |                                 // within the clueTip body. more info below [6]
205 |     escapeTitle:      false,    // whether to html escape the title attribute
206 |     showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
207 |     cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass. more info below [7]
208 |     hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
209 |     waitImage:        true,     // whether to show a "loading" img, which is set in jquery.cluetip.css
210 |     cursor:           'help',
211 |     arrows:           false,    // if true, displays arrow on appropriate side of clueTip. more info below [8]
212 |     dropShadow:       true,     // set to false if you don't want the drop-shadow effect on the clueTip
213 |     dropShadowSteps:  6,        // adjusts the size of the drop shadow
214 |     sticky:           false,    // keep visible until manually closed
215 |     mouseOutClose:    false,    // close when clueTip is moused out: false, 'cluetip', 'link', 'both'
216 |     delayedClose:     50,        // close clueTip on a timed delay
217 |     activation:       'hover',  // set to 'click' to force user to click to show clueTip
218 |     clickThrough:     true,    // if true, and activation is not 'click', then clicking on a clueTipped link will take user to
219 |                                 // the link's href, even if href and tipAttribute are equal
220 |     tracking:         false,    // if true, clueTip will track mouse movement (experimental)
221 |     closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
222 |     closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
223 |     truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs
224 | 
225 |     // effect and speed for opening clueTips
226 |     fx: {
227 |                       open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
228 |                       openSpeed:  ''
229 |     },
230 | 
231 |     // settings for when hoverIntent plugin is used
232 |     hoverIntent: {
233 |                       sensitivity:  3,
234 |                       interval:     50,
235 |                       timeout:      0
236 |     },
237 | 
238 |     // function to run just before clueTip is shown.
239 |     // If the function returns false, the clueTip is NOT shown
240 |     // It can take a single argument: the event object
241 |     // Inside the function, this refers to the element that invoked the clueTip
242 |     onActivate:       function(event) {return true;},
243 | 
244 |     // function to run just after clueTip is shown. It can take two arguments:
245 |     // the first is a jQuery object representing the clueTip element;
246 |     // the second a jQuery object represeting the clueTip inner div.
247 |     // Inside the function, this refers to the element that invoked the clueTip
248 |     onShow:           function(ct, ci){},
249 | 
250 |     // function to run just after clueTip is hidden. It can take two arguments:
251 |     // the first is a jQuery object representing the clueTip element;
252 |     // the second a jQuery object represeting the clueTip inner div.
253 |     // Inside the function, this refers to the element that invoked the clueTip
254 |     onHide:           function(ct, ci){},
255 | 
256 |     // whether to cache results of ajax request to avoid unnecessary hits to server
257 |     ajaxCache:        true,
258 | 
259 |     // process data retrieved via xhr before it's displayed
260 |     ajaxProcess:      function(data) {
261 |                         data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,'');
262 |                         return data;
263 |     },
264 |     // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend,
265 |     // will be queued first within the default callbacks.
266 |     ajaxSettings: {
267 |       // error: function(ct, ci) { /* override default error callback */ },
268 |       // beforeSend: function(ct, ci) { /* called first within default beforeSend callback */ },
269 |       dataType: 'html'
270 |     }
271 |   };
272 |
273 |
$(document).trigger('hideCluetip')
274 |
Hides any currently visible cluetip.
275 |

276 | // example for how you might do this with touch devices
277 | $('body').bind('touchstart', function(event) {
278 |  event = event.originalEvent;
279 |  var tgt = event.touches[0] && event.touches[0].target,
280 |      $tgt = $(tgt);
281 | 
282 |  if (tgt.nodeName !== 'A' && !$tgt.closest('div.cluetip').length ) {
283 |    $(document).trigger('hideCluetip');
284 |  }
285 | });
286 | 
287 |
$('some-already-initialized-link').trigger('showCluetip')
288 |
Triggers the cluetip to be shown for a particular element on which .cluetip() has already been called.
289 | 290 |
291 |
    292 |
  1. height: Setting a specific height also sets <div id="cluetip-outer"> to "overflow:auto"
  2. 293 |
  3. positionBy: Available options are 'auto', 'mouse', 'bottomTop', 'topBottom', fixed'. Change to 'mouse' if you want to override positioning by element and position the clueTip based on where the mouse is instead. Change to 'bottomTop' if you want positioning to begin below the mouse when there is room or above if not (and 'topBottom' for vice versa) — rather than right or left of the elemnent and flush with element's top. Change to 'fixed' if you want the clueTip to appear in exactly the same location relative to the linked element no matter where it appears on the page. Use 'fixed' at your own risk.
  4. 294 |
  5. topOffset:For all but positionBy: 'fixed', the number will be added to the clueTip's "top" value if the clueTip appears below the invoking element and subtracted from it if the clueTip appears above. For positionBy "fixed", the number will always be added to the "top" value, offsetting the clueTip from the top of the invoking element.
  6. 295 |
  7. leftOffset: For all but positionBy: 'fixed', the number will be added to clueTip's "left" value if the clueTip appears to the right of the invoking element and subtracted if the clueTip appears to the left. For positionBy "fixed", the number will always be added to the "left" value of the clueTip, offsetting it from the right side of the invoking element.
  8. 296 |
  9. local: for example, using the default tip attribute, "rel", you could have a link — <a href="somewhere.htm" rel="#someID"> — that would show the contents of the element in the DOM that has an ID of "someID." 297 |
    Important: If you use any selector other than a simple ID, the plugin will match the index of the element with the index of the invoking element among all selected elements. For example, if you call $('a').cluetip({local: true}) and you have two links with rel="div.foo", the first link will display the contents of the first div class="foo" and the second link will display the contents of the second div class="foo". 298 |
    299 |
  10. 300 |
  11. splitTitle: if used, the clueTip will be populated only by the title attribute
  12. 301 |
  13. cluetipClass: this is also used for a "directional" class on the same div, depending on where the clueTip is in relation to the invoking element. The class appears in the form of 'cluetip-' + direction + cluetipClass. this allows you to create your own clueTip theme in a separate CSS file or use one of the three pre-packaged themes: default, jtip, or rounded.
  14. 302 |
  15. arrows: UPDATE: this option displays a div containing an arrow background image. Arrow images are set using the background-image property in the CSS. The direction of the arrow changes depending on which side of the invoking element the clueTip appears. The arrows option sets the background-position of the cluetip div so that the arrow will accurately point to the invoking element, regardless of where it appears in relation to it.
  16. 303 |
304 |
305 | 306 |
307 |

Frequently Asked Questions

308 |
309 |
Is clueTip still being maintained?
310 |
No. It had a good run, but it's old and tired and in need of rest. Take a look at the overview for a list of alternative tooltip plugins. 311 |
312 |
How is clueTip licensed?
313 |
314 |

The clueTip plugin is licensed the same way as the jQuery core file: under the MIT license. The top of the jquery.cluetip.js file has this notice:

315 |

Licensed under the MIT license:
316 | * http://www.opensource.org/licenses/mit-license.php

317 |
318 |
What versions of jQuery is the clueTip Plugin compatible with?
319 |
As of clueTip version 1.06, the plugin is compatible with version 1.3.2 or later. Previous clueTip versions are compatible with jQuery 1.2.6, though 1.3.2 or later is recommended.
320 |
Does the clueTip Plugin have any dependencies on other plugins?
321 |
No. However, optional plugins that can be used in conjunction with the clueTip plugin include hoverIntent and bgIframe.
322 |
How do I get clueTip to work on elements that have been inserted via ajax after the page loads?
323 |
You can call the .cluetip() method on those elements from within the ajax method's callback function. For example: 324 |
$.get('/path/to/file', function(html) {
325 |   var newHtml = $(html);
326 |   newHtml.appendTo('#some-elememnt');
327 |   newHtml.find('a').cluetip();
328 | });
329 |
330 |
How do I get clueTip to show ajaxed content that has changed on the server?
331 |
There are a number of options available for working with dynamic content. By default, the ajaxCache function is set to true. This reduces the number of http requests made to the server. However, it doesn't account for possible changes to the ajaxed data. If the contents of a particular clueTip will be updated on the server between invocations, you may want to set ajaxCache: false. 332 |
333 |
How do I programmatically close (hide) a clueTip?
334 |
If you want to trigger a clueTip to close, based on some other interaction, you can use the following code: $(document).trigger('hideCluetip');
335 |
Why don't the styles that I've applied to my local content carry over once they're inside a clueTip?
336 |
When using an element on the same page to populate the clueTip's content, the plugin clones that element. Because of potential problems caused by duplicate IDs within a page, the plugin also, by default, adds a suffix to the ID of the cloned element. If you have tied styles to the original ID, they won't be carried over. You can either give the localIdSuffix an empty string ( '' ) for its value or add the ID to your stylesheet rule.
337 |
Why don't form elements within a clueTip update when I tell them to?
338 |
If you attempt to update an element based on its ID,
339 |
How do I add a delay before showing or closing the clueTip?
340 |
While the clueTip plugin itself doesn't have a mechanism for delaying responses, it can take advantage of the optional hoverIntent plugin. To delay the showing of a clueTip, use the interval property of the hoverIntent option; to delay its hiding, use the timeout property. Both properties are measured in milliseconds. For example, the following sets both the show and the hide delays to 750 milliseconds (3/4 second): 341 |
$('a').cluetip({
342 |   hoverIntent: {
343 |     sensitivity:  1,
344 |     interval:     750,
345 |     timeout:      750
346 |   }
347 | });
348 | 
349 | See hoverIntent plugin's documentation for details.
350 |
Why are the clueTips hidden behind my Flash elements?
351 |

This is a common problem when trying to layer a DOM element over a Flash object. To avoid it, you need to set <param name="wmode" value="transparent" /> inside the <object></object> tags and/or wmode="transparent" as an attribute of the <embed /> tag. For example, your HTML might look like this:

352 | 353 |
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
354 |   codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"
355 |   width="500" height="300">
356 |   <param name="movie" value="test.swf" />
357 |   <param name="quality" value="high" />
358 |   <param name="wmode" value="transparent" />
359 | 
360 |   <embed src="test.swf" quality="high" wmode="transparent"
361 |     pluginspage="http://www.macromedia.com/go/getflashplayer"
362 |     type="application/x-shockwave-flash" width="500" height="300" />
363 | </object>
364 | 
365 |
366 |
367 |
368 |
369 |

clueTip Plugin Credits

370 | 371 | 375 |
376 |
377 |

This plugin is no longer being supported.

378 |

See the overview for a list of alternative tooltip plugins.

379 | 380 |

Download

381 |

The plugin is available on Github, where it is updated more frequently with incremental improvements and bug fixes: clueTip on Github

382 |

Bug Reports

383 | If you discover a bug in the clueTip plugin, please report the bug here. 384 |

385 | 388 |
389 |
390 | 391 | 392 | -------------------------------------------------------------------------------- /jquery.cluetip.css: -------------------------------------------------------------------------------- 1 | /* global */ 2 | div.ui-cluetip { 3 | font-size: 1em; 4 | } 5 | .ui-cluetip-header, 6 | .ui-cluetip-content { 7 | padding: 12px; 8 | } 9 | .ui-cluetip-header { 10 | font-size: 1em; 11 | margin: 0; 12 | overflow: hidden; 13 | } 14 | 15 | .cluetip-title .cluetip-close { 16 | float: right; 17 | position: relative; 18 | } 19 | .cluetip-close img { 20 | border: 0; 21 | } 22 | 23 | #cluetip-waitimage { 24 | width: 43px; 25 | height: 11px; 26 | position: absolute; 27 | background-image: url(images/wait.gif); 28 | } 29 | .cluetip-arrows { 30 | display: none; 31 | position: absolute; 32 | top: 0; 33 | left: -11px; 34 | width: 11px; 35 | height: 22px; 36 | background-repeat: no-repeat; 37 | background-position: 0 0; 38 | border-width: 0; 39 | } 40 | .cluetip-extra { 41 | display: none; 42 | } 43 | 44 | /*************************************** 45 | =cluetipClass: 'default' 46 | -------------------------------------- */ 47 | 48 | .cluetip-default, 49 | .cluetip-default .cluetip-outer { 50 | background-color: #d9d9c2; 51 | } 52 | .cluetip-default .ui-cluetip-header { 53 | background-color: #87876a; 54 | } 55 | 56 | 57 | /* 58 | .cluetip-default #cluetip-outer { 59 | position: relative; 60 | margin: 0; 61 | background-color: #d9d9c2; 62 | } 63 | .cluetip-default h3#cluetip-title { 64 | margin: 0 0 5px; 65 | padding: 8px 10px 4px; 66 | font-size: 1.1em; 67 | font-weight: normal; 68 | background-color: #87876a; 69 | color: #fff; 70 | } 71 | .cluetip-default #cluetip-title a { 72 | color: #d9d9c2; 73 | font-size: 0.95em; 74 | } 75 | .cluetip-default #cluetip-inner { 76 | padding: 10px; 77 | } 78 | .cluetip-default div#cluetip-close { 79 | text-align: right; 80 | margin: 0 5px 5px; 81 | color: #900; 82 | } 83 | */ 84 | /* default arrows */ 85 | div.cluetip-default .cluetip-arrows { 86 | border-width: 0; 87 | background: transparent none; 88 | } 89 | div.clue-right-default .cluetip-arrows { 90 | background-image: url(images/darrowleft.gif); 91 | } 92 | div.clue-left-default .cluetip-arrows { 93 | background-image: url(images/darrowright.gif); 94 | left: 100%; 95 | margin-right: -11px; 96 | } 97 | div.clue-top-default .cluetip-arrows { 98 | background-image: url(images/darrowdown.gif); 99 | top: 100%; 100 | left: 50%; 101 | margin-left: -11px; 102 | width: 22px; 103 | height: 11px; 104 | } 105 | div.clue-bottom-default .cluetip-arrows { 106 | background-image: url(images/darrowup.gif); 107 | top: -11px; 108 | left: 50%; 109 | margin-left: -11px; 110 | width: 22px; 111 | height: 11px; 112 | } 113 | 114 | /*************************************** 115 | =cluetipClass: 'jtip' 116 | -------------------------------------- */ 117 | .cluetip-jtip { 118 | background-color: #fff; 119 | } 120 | .cluetip-jtip .cluetip-outer { 121 | border: 2px solid #ccc; 122 | position: relative; 123 | /*background-color: #fff;*/ 124 | } 125 | 126 | .cluetip-jtip .cluetip-inner { 127 | padding: 5px; 128 | display: inline-block; 129 | } 130 | .cluetip-jtip div.cluetip-close { 131 | text-align: right; 132 | margin: 0 5px 0; 133 | color: #900; 134 | } 135 | 136 | .cluetip-jtip .ui-cluetip-header { 137 | background-color: #ccc; 138 | padding: 6px; 139 | /* margin-bottom: 1em;*/ 140 | } 141 | 142 | /* jtip arrows */ 143 | div.cluetip-jtip .cluetip-arrows { 144 | border-width: 0; 145 | background: transparent none; 146 | } 147 | div.clue-right-jtip .cluetip-arrows { 148 | background-image: url(images/arrowleft.gif); 149 | } 150 | div.clue-left-jtip .cluetip-arrows { 151 | background-image: url(images/arrowright.gif); 152 | left: 100%; 153 | margin-right: -11px; 154 | } 155 | div.clue-top-jtip .cluetip-arrows { 156 | background-image: url(images/arrowdown.gif); 157 | top: 100%; 158 | left: 50%; 159 | width: 22px; 160 | height: 11px; 161 | margin-left: -11px; 162 | } 163 | div.clue-bottom-jtip .cluetip-arrows { 164 | background-image: url(images/arrowup.gif); 165 | top: -11px; 166 | left: 50%; 167 | width: 22px; 168 | height: 11px; 169 | margin-left: -11px; 170 | } 171 | 172 | /*************************************** 173 | =cluetipClass: 'rounded' 174 | -------------------------------------- */ 175 | .cluetip-rounded { 176 | -webkit-border-radius: 6px; 177 | -moz-border-radius: 6px; 178 | border-radius: 6px; 179 | background-color: #fff; 180 | border: 1px solid #ccc; 181 | } 182 | 183 | .cluetip-rounded .cluetip-outer { 184 | -webkit-border-radius: 6px; 185 | -moz-border-radius: 6px; 186 | border-radius: 6px; 187 | background-color: #fff; 188 | } 189 | 190 | .cluetip-rounded .cluetip-arrows { 191 | border-color: #ccc; 192 | } 193 | 194 | /* need to be more specific here to override ThemeRoller defaults */ 195 | div.cluetip-rounded .cluetip-arrows { 196 | font-size: 0; 197 | line-height: 0%; 198 | width: 0; 199 | height: 0; 200 | border-style: solid; 201 | background: transparent none; 202 | } 203 | div.clue-right-rounded .cluetip-arrows { 204 | border-width: 11px 11px 11px 0; 205 | border-top-color: transparent; 206 | border-bottom-color: transparent; 207 | border-left-color: transparent; 208 | } 209 | div.clue-left-rounded .cluetip-arrows { 210 | left: 100%; 211 | margin-right: -11px; 212 | border-width: 11px 0 11px 11px; 213 | border-top-color: transparent; 214 | border-right-color: transparent; 215 | border-bottom-color: transparent; 216 | 217 | } 218 | div.clue-top-rounded .cluetip-arrows { 219 | top: 100%; 220 | left: 50%; 221 | border-width: 11px 11px 0 11px; 222 | border-right-color: transparent; 223 | border-bottom-color: transparent; 224 | border-left-color: transparent; 225 | } 226 | .clue-bottom-rounded .cluetip-arrows { 227 | top: -11px; 228 | left: 50%; 229 | border-width: 0 11px 11px 11px; 230 | border-top-color: transparent; 231 | border-right-color: transparent; 232 | border-left-color: transparent; 233 | 234 | } 235 | /* stupid IE6 HasLayout hack */ 236 | .cluetip-rounded .cluetip-title, 237 | .cluetip-rounded .cluetip-inner { 238 | zoom: 1; 239 | } 240 | -------------------------------------------------------------------------------- /jquery.cluetip.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clueTip - v1.2.10 - 2013-09-29 3 | * http://plugins.learningjquery.com/cluetip/ 4 | * Copyright (c) 2013 Karl Swedberg 5 | * Licensed MIT (http://www.opensource.org/licenses/mit-license.php) 6 | */ 7 | 8 | (function($) { 9 | 10 | $.cluetip = { 11 | version: '1.2.10', 12 | 13 | // the HTML that will be used for the tooltip 14 | template: ['
', 15 | '
', 16 | '

', 17 | '
', 18 | '
', 19 | '
', 20 | '
'].join(''), 21 | 22 | /* clueTip setup 23 | * the setup options are applied each time .cluetip() is called, 24 | * BUT only if
is not already in the document 25 | */ 26 | setup: { 27 | // method to be used for inserting the clueTip into the DOM. 28 | // Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter' 29 | insertionType: 'appendTo', 30 | // element in the DOM the plugin will reference when inserting the clueTip. 31 | insertionElement: 'body' 32 | }, 33 | 34 | /* 35 | * clueTip options 36 | * 37 | * each one can be explicitly overridden by changing its value. 38 | * for example: $.cluetip.defaults.width = 200; 39 | * or: $.fn.cluetip.defaults.width = 200; // for compatibility with previous clueTip versions 40 | * would change the default width for all clueTips to 200. 41 | * 42 | * each one can also be overridden by passing an options map to the cluetip method. 43 | * for example: $('a.example').cluetip({width: 200}); 44 | * would change the default width to 200 for clueTips invoked by a link with class of "example" 45 | * 46 | */ 47 | defaults: { 48 | multiple: false, // Allow a new tooltip to be created for each .cluetip() call 49 | width: 275, // The width of the clueTip 50 | height: 'auto', // The height of the clueTip 51 | cluezIndex: 97, // Sets the z-index style property of the clueTip 52 | positionBy: 'auto', // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'topBottom', fixed' 53 | topOffset: 15, // Number of px to offset clueTip from top of invoking element 54 | leftOffset: 15, // Number of px to offset clueTip from left of invoking element 55 | snapToEdge: false, // For bottomTop and topBottom, snap to the top or bottom of the element. 56 | local: false, // Whether to use content from the same page for the clueTip's body 57 | localPrefix: null, // string to be prepended to the tip attribute if local is true 58 | localIdSuffix: null, // string to be appended to the cluetip content element's id if local is true 59 | hideLocal: true, // If local option is set to true, this determines whether local content 60 | // to be shown in clueTip should be hidden at its original location 61 | attribute: 'rel', // the attribute to be used for fetching the clueTip's body content 62 | titleAttribute: 'title', // the attribute to be used for fetching the clueTip's title 63 | splitTitle: '', // A character used to split the title attribute into the clueTip title and divs 64 | // within the clueTip body. more info below [6] 65 | escapeTitle: false, // whether to html escape the title attribute 66 | showTitle: true, // show title bar of the clueTip, even if title attribute not set 67 | cluetipClass: 'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass. 68 | hoverClass: '', // class applied to the invoking element onmouseover and removed onmouseout 69 | waitImage: true, // whether to show a "loading" img, which is set in jquery.cluetip.css 70 | cursor: 'help', 71 | arrows: false, // if true, displays arrow on appropriate side of clueTip 72 | dropShadow: true, // set to false if you don't want the drop-shadow effect on the clueTip 73 | dropShadowSteps: 6, // adjusts the size of the drop shadow 74 | sticky: false, // keep visible until manually closed 75 | mouseOutClose: false, // close when clueTip is moused out: false, 'cluetip', 'link', 'both' 76 | delayedClose: 50, // close clueTip on a timed delay 77 | activation: 'hover', // set to 'click' to force user to click to show clueTip 78 | // set to 'focus' to show on focus of a form element and hide on blur 79 | clickThrough: true, // if true, and activation is not 'click', then clicking on link will take user to the link's href, 80 | // even if href and tipAttribute are equal 81 | tracking: false, // if true, clueTip will track mouse movement (experimental) 82 | closePosition: 'top', // location of close text for sticky cluetips; can be 'top', 'bottom', 'title' or 'none' 83 | closeText: 'Close', // text (or HTML) to to be clicked to close sticky clueTips 84 | truncate: 0, // number of characters to truncate clueTip's contents. if 0, no truncation occurs 85 | 86 | // effect and speed for opening clueTips 87 | fx: { 88 | open: 'show', // can be 'show' or 'slideDown' or 'fadeIn' 89 | openSpeed: '' 90 | }, 91 | 92 | // settings for when hoverIntent plugin is used 93 | hoverIntent: { 94 | sensitivity: 3, 95 | interval: 50, 96 | timeout: 0 97 | }, 98 | 99 | // short-circuit function to run just before clueTip is shown. 100 | onActivate: function(e) {return true;}, 101 | // function to run just after clueTip is shown. 102 | onShow: function(ct, ci){}, 103 | // function to run just after clueTip is hidden. 104 | onHide: function(ct, ci){}, 105 | // whether to cache results of ajax request to avoid unnecessary hits to server 106 | ajaxCache: true, 107 | 108 | // process data retrieved via xhr before it's displayed 109 | ajaxProcess: function(data) { 110 | data = data.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm, '').replace(/<(link|meta)[^>]+>/g,''); 111 | return data; 112 | }, 113 | 114 | // can pass in standard $.ajax() parameters. Callback functions, such as beforeSend, 115 | // will be queued first within the default callbacks. 116 | // The only exception is error, which overrides the default 117 | ajaxSettings: { 118 | // error: function(ct, ci) { /* override default error callback */ }, 119 | // beforeSend: function(ct, ci) { /* called first within default beforeSend callback */ }, 120 | dataType: 'html' 121 | }, 122 | debug: false 123 | 124 | } 125 | }; 126 | var $cluetipWait, 127 | standardClasses = 'cluetip ui-widget ui-widget-content ui-cluetip', 128 | caches = {}, 129 | counter = 0, 130 | imgCount = 0; 131 | 132 | var encodeString = function(str) { 133 | return str.replace(/&/g,'&').replace(/>/g,'>').replace(/
').attr('id', 'cluetip-waitimage').css({position: 'absolute'}); 199 | $cluetipWait.insertBefore($cluetip).hide(); 200 | } 201 | 202 | 203 | var cluetipPadding = (parseInt($cluetip.css('paddingLeft'), 10) || 0) + (parseInt($cluetip.css('paddingRight'), 10) || 0); 204 | 205 | 206 | this.each(function(index) { 207 | var jsContent, 208 | link = this, 209 | $link = $(this), 210 | // support metadata plugin (v1.0 and 2.0) 211 | opts = $.extend(true, {}, options, $.metadata ? $link.metadata() : $.meta ? $link.data() : $link.data('cluetip') || {}), 212 | // start out with no contents (for ajax activation) 213 | cluetipContents = false, 214 | isActive = false, 215 | closeOnDelay = null, 216 | tipAttribute = opts[opts.attribute] || 217 | ( opts.attribute == 'href' ? $link.attr(opts.attribute) : $link.attrProp(opts.attribute) || $link.attr(opts.attribute) ), 218 | ctClass = opts.cluetipClass; 219 | 220 | cluezIndex = +opts.cluezIndex; 221 | $link.data('cluetip', {title: link.title, zIndex: cluezIndex, selector: cluetipSelector, cursor: link.style.cursor || ''}); 222 | 223 | if (opts.arrows && !$cluetip.find('.cluetip-arrows').length) { 224 | $cluetip.append('
'); 225 | } 226 | 227 | if (!tipAttribute && !opts.splitTitle && !js) { 228 | return true; 229 | } 230 | // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip 231 | if (opts.local && opts.localPrefix) {tipAttribute = opts.localPrefix + tipAttribute;} 232 | if (opts.local && opts.hideLocal && tipAttribute) { $(tipAttribute + ':first').hide(); } 233 | 234 | var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10); 235 | // vertical measurement variables 236 | var tipHeight, wHeight, 237 | defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px'; 238 | var sTop, linkTop, linkBottom, posY, tipY, mouseY, baseline; 239 | // horizontal measurement variables 240 | var tipInnerWidth = parseInt(opts.width, 10) || 275, 241 | tipWidth = tipInnerWidth + cluetipPadding + opts.dropShadowSteps, 242 | linkWidth = this.offsetWidth, 243 | linkLeft, posX, tipX, mouseX, winWidth; 244 | 245 | // parse the title 246 | var tipParts; 247 | var tipTitle = (opts.attribute != 'title') ? $link.attr(opts.titleAttribute) || '' : ''; 248 | if (opts.escapeTitle) { 249 | tipTitle = encodeString(tipTitle); 250 | } 251 | if (opts.splitTitle) { 252 | tipParts = tipTitle.split(opts.splitTitle); 253 | tipTitle = opts.showTitle || tipParts[0] === '' ? tipParts.shift() : ''; 254 | } 255 | 256 | 257 | 258 | var localContent; 259 | function returnFalse() { return false; } 260 | 261 | // Keep track of mouse entered state on link 262 | $link.bind('mouseenter mouseleave', function(event) { 263 | var data = $link.data('cluetip'); 264 | data.entered = event.type === 'entered'; 265 | $link.data('cluetip', data); 266 | }); 267 | 268 | /*************************************** 269 | * ACTIVATION 270 | ****************************************/ 271 | 272 | //activate clueTip 273 | var activate = function(event) { 274 | var pY, ajaxMergedSettings, cacheKey, 275 | continueOn = opts.onActivate.call(link, event); 276 | 277 | if (continueOn === false) { 278 | return false; 279 | } 280 | 281 | isActive = true; 282 | 283 | // activate function may get called after an initialization of a 284 | // different target so need to re-get the Correct Cluetip object here 285 | $cluetip = $(cluetipSelector).css({position: 'absolute'}); 286 | $cluetipOuter = $cluetip.find(prefix + 'cluetip-outer'); 287 | $cluetipInner = $cluetip.find(prefix + 'cluetip-inner'); 288 | $cluetipTitle = $cluetip.find(prefix + 'cluetip-title'); 289 | $cluetipArrows = $cluetip.find(prefix + 'cluetip-arrows'); 290 | $cluetip.removeClass().css({width: tipInnerWidth}); 291 | if (tipAttribute == $link.attr('href')) { 292 | $link.css('cursor', opts.cursor); 293 | } 294 | if (opts.hoverClass) { 295 | $link.addClass(opts.hoverClass); 296 | } 297 | linkTop = posY = $link.offset().top; 298 | linkBottom = linkTop + $link.innerHeight(); 299 | linkLeft = $link.offset().left; 300 | if ( $(insertionElement).css('position') === 'relative' ) { 301 | linkLeft -= $(insertionElement)[0].getBoundingClientRect().left; 302 | } 303 | 304 | // FIX: (bug 4412) 305 | linkWidth = $link.innerWidth(); 306 | if ( event.type == focus || (opts.positionBy == 'mouse' && !event.pageX) ) { 307 | // in focus event, no mouse position is available; this is needed with bottomTop: 308 | mouseX = linkLeft + ( linkWidth / 2 ) + lOffset; 309 | $cluetip.css({left: posX}); 310 | mouseY = posY + tOffset; 311 | } else { 312 | mouseX = event.pageX; 313 | mouseY = event.pageY; 314 | } 315 | //END OF FIX 316 | 317 | if (link.tagName.toLowerCase() != 'area') { 318 | sTop = $(document).scrollTop(); 319 | winWidth = $(window).width(); 320 | } 321 | // position clueTip horizontally 322 | if (opts.positionBy == 'fixed') { 323 | posX = linkWidth + linkLeft + lOffset; 324 | $cluetip.css({left: posX}); 325 | } else { 326 | posX = (linkWidth > linkLeft && linkLeft > tipWidth) || 327 | linkLeft + linkWidth + tipWidth + lOffset > winWidth ? 328 | linkLeft - tipWidth - lOffset : 329 | linkWidth + linkLeft + lOffset; 330 | if (link.tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse 331 | if (mouseX + 20 + tipWidth > winWidth) { 332 | $cluetip.addClass('cluetip-' + ctClass); 333 | posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) : mouseX - (tipWidth/2); 334 | } else { 335 | posX = mouseX + lOffset; 336 | } 337 | } 338 | pY = posX < 0 ? event.pageY + tOffset : event.pageY; 339 | if (posX < 0 || opts.positionBy == 'bottomTop' || opts.positionBy == 'topBottom') { 340 | posX = (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0); 341 | } 342 | } 343 | 344 | $cluetipArrows.css({zIndex: $link.data('cluetip').zIndex+1}); 345 | $cluetip.css({ 346 | left: posX, 347 | zIndex: $link.data('cluetip').zIndex 348 | }); 349 | wHeight = $(window).height(); 350 | 351 | /*************************************** 352 | * load a string from cluetip method's first argument 353 | ***************************************/ 354 | if (js) { 355 | if (typeof js == 'function') { 356 | jsContent = js.call(link); 357 | } else { 358 | jsContent = js; 359 | } 360 | $cluetipInner.html(jsContent); 361 | cluetipShow(pY); 362 | } 363 | /*************************************** 364 | * load the title attribute only (or user-selected attribute). 365 | * clueTip title is the string before the first delimiter 366 | * subsequent delimiters place clueTip body text on separate lines 367 | ***************************************/ 368 | 369 | else if (tipParts) { 370 | var tpl = tipParts.length; 371 | $cluetipInner.html(tpl ? tipParts[0] : ''); 372 | if (tpl > 1) { 373 | for (var i=1; i < tpl; i++) { 374 | $cluetipInner.append('
' + tipParts[i] + '
'); 375 | } 376 | } 377 | cluetipShow(pY); 378 | } 379 | /*************************************** 380 | * load external file via ajax 381 | ***************************************/ 382 | 383 | else if ( !opts.local && tipAttribute.indexOf('#') !== 0 ) { 384 | if (/\.(jpe?g|tiff?|gif|png)(?:\?.*)?$/i.test(tipAttribute)) { 385 | $cluetipInner.html('' + tipTitle + ''); 386 | cluetipShow(pY); 387 | } else { 388 | var optionBeforeSend = opts.ajaxSettings.beforeSend, 389 | optionError = opts.ajaxSettings.error, 390 | optionSuccess = opts.ajaxSettings.success, 391 | optionComplete = opts.ajaxSettings.complete; 392 | 393 | cacheKey = getCacheKey(tipAttribute, opts.ajaxSettings.data); 394 | 395 | var ajaxSettings = { 396 | cache: opts.ajaxCache, // force requested page not to be cached by browser 397 | url: tipAttribute, 398 | beforeSend: function(xhr, settings) { 399 | if (optionBeforeSend) {optionBeforeSend.call(link, xhr, $cluetip, $cluetipInner, settings);} 400 | $cluetipOuter.children().empty(); 401 | if (opts.waitImage) { 402 | $cluetipWait 403 | .css({top: mouseY+20, left: mouseX+20, zIndex: $link.data('cluetip').zIndex-1}) 404 | .show(); 405 | } 406 | }, 407 | error: function(xhr, textStatus) { 408 | if ( options.ajaxCache && !caches[cacheKey] ) { 409 | caches[cacheKey] = {status: 'error', textStatus: textStatus, xhr: xhr}; 410 | } 411 | 412 | if (isActive) { 413 | if (optionError) { 414 | optionError.call(link, xhr, textStatus, $cluetip, $cluetipInner); 415 | } else { 416 | $cluetipInner.html('sorry, the contents could not be loaded'); 417 | } 418 | } 419 | }, 420 | success: function(data, textStatus, xhr) { 421 | if ( options.ajaxCache && !caches[cacheKey] ) { 422 | caches[cacheKey] = {status: 'success', data: data, textStatus: textStatus, xhr: xhr}; 423 | } 424 | 425 | cluetipContents = opts.ajaxProcess.call(link, data); 426 | 427 | // allow for changing the title based on data returned by xhr 428 | if ( typeof cluetipContents == 'object' && cluetipContents !== null ) { 429 | tipTitle = cluetipContents.title; 430 | cluetipContents = cluetipContents.content; 431 | } 432 | 433 | if (isActive) { 434 | if (optionSuccess) { 435 | optionSuccess.call(link, data, textStatus, $cluetip, $cluetipInner); 436 | } 437 | $cluetipInner.html(cluetipContents); 438 | 439 | } 440 | }, 441 | complete: function(xhr, textStatus) { 442 | if (optionComplete) { 443 | optionComplete.call(link, xhr, textStatus, $cluetip, $cluetipInner); 444 | } 445 | var imgs = $cluetipInner[0].getElementsByTagName('img'); 446 | imgCount = imgs.length; 447 | for (var i=0, l = imgs.length; i < l; i++) { 448 | if (imgs[i].complete) { 449 | imgCount--; 450 | } 451 | } 452 | if (imgCount) { 453 | $(imgs).bind('load.ct error.ct', function() { 454 | imgCount--; 455 | if (imgCount === 0) { 456 | $cluetipWait.hide(); 457 | $(imgs).unbind('.ct'); 458 | if (isActive) { cluetipShow(pY); } 459 | } 460 | }); 461 | } else { 462 | $cluetipWait.hide(); 463 | if (isActive) { cluetipShow(pY); } 464 | } 465 | } 466 | }; 467 | 468 | ajaxMergedSettings = $.extend(true, {}, opts.ajaxSettings, ajaxSettings); 469 | 470 | if ( caches[cacheKey] ) { 471 | cachedAjax( caches[cacheKey], ajaxMergedSettings ); 472 | } else { 473 | $.ajax(ajaxMergedSettings); 474 | } 475 | } 476 | } 477 | /*************************************** 478 | * load an element from the same page 479 | ***************************************/ 480 | else if (opts.local) { 481 | var $localContent = $(tipAttribute + (/^#\S+$/.test(tipAttribute) ? '' : ':eq(' + index + ')')).clone(true).show(); 482 | if (opts.localIdSuffix) { 483 | $localContent.attr('id', $localContent[0].id + opts.localIdSuffix); 484 | } 485 | $cluetipInner.html($localContent); 486 | cluetipShow(pY); 487 | } 488 | }; 489 | 490 | $link.unbind('showCluetip.cluetip', activate).bind('showCluetip.cluetip', activate); 491 | 492 | // get dimensions and options for cluetip and prepare it to be shown 493 | var cluetipShow = function(bpY) { 494 | var $closeLink, dynamicClasses, heightDiff, 495 | titleHTML = tipTitle || opts.showTitle && ' ', 496 | bgY = '', direction = '', insufficientX = false; 497 | var stickyClose = { 498 | bottom: function($cLink) { 499 | $cLink.appendTo($cluetipInner); 500 | }, 501 | top: function($cLink) { 502 | $cLink.prependTo($cluetipInner); 503 | }, 504 | title: function($cLink) { 505 | $cLink.prependTo($cluetipTitle); 506 | } 507 | }; 508 | 509 | $cluetip.addClass('cluetip-' + ctClass); 510 | if (opts.truncate) { 511 | var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...'; 512 | $cluetipInner.html($truncloaded); 513 | } 514 | 515 | if (titleHTML) { 516 | $cluetipTitle.show().html(titleHTML); 517 | } else { 518 | $cluetipTitle.hide(); 519 | } 520 | 521 | if (opts.sticky) { 522 | if (stickyClose[opts.closePosition]) { 523 | $closeLink = $('
' + opts.closeText + '
'); 524 | stickyClose[opts.closePosition]( $closeLink ); 525 | $closeLink.bind('click.cluetip', function() { 526 | cluetipClose(); 527 | return false; 528 | }); 529 | } 530 | if (opts.mouseOutClose) { 531 | $link.unbind('mouseleave.cluetipMoc'); 532 | $cluetip.unbind('mouseleave.cluetipMoc'); 533 | if (opts.mouseOutClose == 'both' || opts.mouseOutClose == 'cluetip' || opts.mouseOutClose === true) { // true implies 'cluetip' for backwards compatability 534 | $cluetip.bind('mouseleave.cluetipMoc', mouseOutClose); 535 | } 536 | if (opts.mouseOutClose == 'both' || opts.mouseOutClose == 'link') { 537 | $link.bind('mouseleave.cluetipMoc', mouseOutClose); 538 | } 539 | } 540 | } 541 | 542 | // now that content is loaded, finish the positioning 543 | $cluetipOuter.css({zIndex: $link.data('cluetip').zIndex, overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight}); 544 | tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10); 545 | tipY = posY; 546 | baseline = sTop + wHeight; 547 | insufficientX = (posX < mouseX && (Math.max(posX, 0) + tipWidth > mouseX)); 548 | if (opts.positionBy == 'fixed') { 549 | tipY = posY - opts.dropShadowSteps + tOffset; 550 | } else if (opts.positionBy == 'topBottom' || opts.positionBy == 'bottomTop' || insufficientX) { 551 | if (opts.positionBy == 'topBottom') { 552 | if (posY + tipHeight + tOffset < baseline && mouseY - sTop < tipHeight + tOffset) { 553 | direction = 'bottom'; 554 | } else { 555 | direction = 'top'; 556 | } 557 | } else if (opts.positionBy == 'bottomTop' || insufficientX) { 558 | if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 559 | direction = 'top'; 560 | } else { 561 | direction = 'bottom'; 562 | } 563 | } 564 | // We should now have a direction. Compute tipY 565 | if (opts.snapToEdge) { 566 | if (direction == 'top') { 567 | tipY = linkTop - tipHeight - tOffset; 568 | } else if (direction == 'bottom') { 569 | tipY = linkBottom + tOffset; 570 | } 571 | } else { 572 | if (direction == 'top') { 573 | tipY = mouseY - tipHeight - tOffset; 574 | } else if (direction == 'bottom') { 575 | tipY = mouseY + tOffset; 576 | } 577 | } 578 | } else if ( posY + tipHeight + tOffset > baseline ) { 579 | tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset; 580 | } else if ($link.css('display') == 'block' || link.tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") { 581 | tipY = bpY - tOffset; 582 | } else { 583 | tipY = posY - opts.dropShadowSteps; 584 | } 585 | if (direction === '') { 586 | direction = posX < linkLeft ? 'left' : 'right'; 587 | } 588 | // add classes 589 | dynamicClasses = ' clue-' + direction + '-' + ctClass + ' cluetip-' + ctClass; 590 | if (ctClass == 'rounded') { 591 | dynamicClasses += ' ui-corner-all'; 592 | } 593 | $cluetip.css({top: tipY + 'px'}).attrProp({'className': standardClasses + dynamicClasses}); 594 | // set up arrow positioning to align with element 595 | if (opts.arrows) { 596 | if ( /(left|right)/.test(direction) ) { 597 | heightDiff = $cluetip.height() - $cluetipArrows.height(); 598 | bgY = posX >= 0 && bpY > 0 ? (posY - tipY - opts.dropShadowSteps) : 0; 599 | bgY = heightDiff > bgY ? bgY : heightDiff; 600 | bgY += 'px'; 601 | } 602 | $cluetipArrows.css({top: bgY}).show(); 603 | } else { 604 | $cluetipArrows.hide(); 605 | } 606 | 607 | // (first hide, then) ***SHOW THE CLUETIP*** 608 | // handle dropshadow divs first 609 | $dropShadow = createDropShadows($cluetip, opts); 610 | if ($dropShadow && $dropShadow.length) { 611 | $dropShadow.hide().css({height: tipHeight, width: tipInnerWidth, zIndex: $link.data('cluetip').zIndex-1}).show(); 612 | } 613 | 614 | if (!closeOnDelay) { 615 | $cluetip.hide(); 616 | } 617 | clearTimeout(closeOnDelay); 618 | closeOnDelay = null; 619 | 620 | // show the cluetip 621 | $cluetip[opts.fx.open](opts.fx.openSpeed || 0); 622 | 623 | if ($.fn.bgiframe) { $cluetip.bgiframe(); } 624 | 625 | // trigger the optional onShow function 626 | opts.onShow.call(link, $cluetip, $cluetipInner); 627 | }; 628 | 629 | /*************************************** 630 | =INACTIVATION 631 | -------------------------------------- */ 632 | var inactivate = function(event) { 633 | isActive = false; 634 | $cluetipWait.hide(); 635 | if (!opts.sticky || (/click|toggle/).test(opts.activation) ) { 636 | // delayed close (not fully tested) 637 | if (opts.delayedClose > 0) { 638 | clearTimeout(closeOnDelay); 639 | closeOnDelay = null; 640 | closeOnDelay = setTimeout(cluetipClose, opts.delayedClose); 641 | } else { 642 | cluetipClose(); 643 | clearTimeout(closeOnDelay); 644 | } 645 | } 646 | 647 | if (opts.hoverClass) { 648 | $link.removeClass(opts.hoverClass); 649 | } 650 | }; 651 | 652 | // close cluetip and reset some things 653 | var cluetipClose = function(el) { 654 | var $closer = el && el.data('cluetip') ? el : $link, 655 | ct = $closer.data('cluetip') && $closer.data('cluetip').selector, 656 | ctSelector = ct || 'div.cluetip', 657 | $cluetip = $(ctSelector), 658 | $cluetipInner = $cluetip.find(prefix + 'cluetip-inner'), 659 | $cluetipArrows = $cluetip.find(prefix + 'cluetip-arrows'); 660 | 661 | $cluetip.hide().removeClass(); 662 | opts.onHide.call($closer[0], $cluetip, $cluetipInner); 663 | 664 | if (ct) { 665 | $closer.removeClass('cluetip-clicked'); 666 | $link.css('cursor', $link.data('cluetip').cursor); 667 | } 668 | if (ct && tipTitle) { 669 | $closer.attrProp(opts.titleAttribute, tipTitle); 670 | } 671 | 672 | if (opts.arrows) { 673 | $cluetipArrows.css({top: ''}); 674 | } 675 | if ($dropShadow) { 676 | $dropShadow.hide(); 677 | } 678 | }; 679 | 680 | // Check to see if we should be closing by checking where the user is hovering. 681 | // We do a short 50ms delay for two reasons: to prevent flicker, and to allow the user time to hover on other element 682 | var mouseOutClose = function() { 683 | var el = this; 684 | clearTimeout(closeOnDelay); 685 | closeOnDelay = setTimeout(function() { 686 | var linkOver = $link.data('cluetip').entered, 687 | cluetipOver = $cluetip.data('entered'), 688 | entered = false; 689 | 690 | if ( opts.mouseOutClose == 'both' && (linkOver || cluetipOver) ) { 691 | entered = true; 692 | } 693 | // true implies 'cluetip' for backwards compatibility 694 | else if ( (opts.mouseOutClose === true || opts.mouseOutClose == 'cluetip') && cluetipOver) { 695 | entered = true; 696 | } 697 | else if (opts.mouseOutClose == 'link' && linkOver) { 698 | entered = true; 699 | } 700 | 701 | if ( !entered ) { 702 | // All checks pass, close the cluetip 703 | cluetipClose.call(el); 704 | } 705 | 706 | }, opts.delayedClose); 707 | }; 708 | 709 | $(document).unbind('hideCluetip.cluetip').bind('hideCluetip.cluetip', function(e) { 710 | cluetipClose( $(e.target) ); 711 | }); 712 | /*************************************** 713 | =BIND EVENTS 714 | -------------------------------------- */ 715 | // activate by click 716 | if ( (/click|toggle/).test(opts.activation) ) { 717 | $link.bind('click.cluetip', function(event) { 718 | if ($cluetip.is(':hidden') || !$link.is('.cluetip-clicked')) { 719 | activate(event); 720 | $('.cluetip-clicked').removeClass('cluetip-clicked'); 721 | $link.addClass('cluetip-clicked'); 722 | } else { 723 | inactivate(event); 724 | } 725 | return false; 726 | }); 727 | // activate by focus; inactivate by blur 728 | } else if (opts.activation == 'focus') { 729 | $link.bind('focus.cluetip', function(event) { 730 | $link.attrProp('title',''); 731 | activate(event); 732 | }); 733 | $link.bind('blur.cluetip', function(event) { 734 | $link.attrProp('title', $link.data('cluetip').title); 735 | inactivate(event); 736 | }); 737 | // activate by hover 738 | } else { 739 | 740 | // clicking is returned false if clickThrough option is set to false 741 | $link[opts.clickThrough ? 'unbind' : 'bind']('click.cluetip', returnFalse); 742 | 743 | //set up mouse tracking 744 | var mouseTracks = function(evt) { 745 | if (opts.tracking) { 746 | var trackX = posX - evt.pageX; 747 | var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY; 748 | $link.bind('mousemove.cluetip', function(evt) { 749 | $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY }); 750 | }); 751 | } 752 | }; 753 | 754 | if ($.fn.hoverIntent && opts.hoverIntent) { 755 | $link.hoverIntent({ 756 | sensitivity: opts.hoverIntent.sensitivity, 757 | interval: opts.hoverIntent.interval, 758 | over: function(event) { 759 | activate(event); 760 | mouseTracks(event); 761 | }, 762 | timeout: opts.hoverIntent.timeout, 763 | out: function(event) { 764 | inactivate(event); 765 | $link.unbind('mousemove.cluetip'); 766 | } 767 | }); 768 | } else { 769 | $link.bind('mouseenter.cluetip', function(event) { 770 | activate(event); 771 | mouseTracks(event); 772 | }) 773 | .bind('mouseleave.cluetip', function(event) { 774 | inactivate(event); 775 | $link.unbind('mousemove.cluetip'); 776 | }); 777 | } 778 | 779 | $link.bind('mouseover.cluetip', function(event) { 780 | $link.attrProp('title',''); 781 | }).bind('mouseleave.cluetip', function(event) { 782 | $link.attrProp('title', $link.data('cluetip').title); 783 | }); 784 | } 785 | 786 | // trigger a cached Ajax response 787 | function cachedAjax(info, settings) { 788 | var status = info.status; 789 | settings.beforeSend(info.xhr, settings); 790 | if ( status == 'error' ) { 791 | settings[status](info.xhr, info.textStatus); 792 | } else if (status == 'success') { 793 | settings[status](info.data, info.textStatus, info.xhr); 794 | } 795 | settings.complete(info.xhr, settings.textStatus); 796 | } 797 | 798 | }); // end this.each 799 | 800 | /** =private functions 801 | ************************************************************/ 802 | //empty function 803 | function doNothing() {} 804 | 805 | // create a string to be used as an identifier for ajax caches 806 | function getCacheKey(url, data) { 807 | var cacheKey = url || ''; 808 | data = data || ''; 809 | 810 | if (typeof data == 'object') { 811 | $.each(data, function(key, val) { 812 | cacheKey += '-' + key + '-' + val; 813 | }); 814 | } else if (typeof data == 'string') { 815 | cacheKey += data; 816 | } 817 | 818 | return cacheKey; 819 | } 820 | 821 | /** =create dropshadow divs **/ 822 | 823 | function createDropShadows($cluetip, options, newDropShadow) { 824 | var dsStyle = '', 825 | dropShadowSteps = (options.dropShadow && options.dropShadowSteps) ? +options.dropShadowSteps : 0; 826 | 827 | if ($.cluetip.boxShadow) { 828 | if ( dropShadowSteps ) { 829 | dsStyle = '1px 1px ' + dropShadowSteps + 'px rgba(0,0,0,0.5)'; 830 | } 831 | var dsOffsets = dropShadowSteps === 0 ? '0 0 ' : '1px 1px '; 832 | $cluetip.css($.cluetip.boxShadow, dsStyle); 833 | return false; 834 | } 835 | var oldDropShadow = $cluetip.find('.cluetip-drop-shadow'); 836 | if (dropShadowSteps == oldDropShadow.length) { 837 | return oldDropShadow; 838 | } 839 | oldDropShadow.remove(); 840 | var dropShadows = []; 841 | for (var i=0; i < dropShadowSteps;) { 842 | dropShadows[i++] = '
'; 843 | } 844 | 845 | newDropShadow = $(dropShadows.join('')) 846 | .css({ 847 | position: 'absolute', 848 | backgroundColor: '#000', 849 | zIndex: cluezIndex -1, 850 | opacity: 0.1 851 | }) 852 | .addClass('cluetip-drop-shadow') 853 | .prependTo($cluetip); 854 | return newDropShadow; 855 | 856 | } 857 | 858 | return this; 859 | }; 860 | 861 | (function() { 862 | $.support = $.support || {}; 863 | 864 | // check support for CSS3 properties (currently only boxShadow) 865 | var div = document.createElement('div'), 866 | divStyle = div.style, 867 | styleProps = ['boxShadow'], 868 | prefixes = ['moz', 'Moz', 'webkit', 'o']; 869 | 870 | for (var i=0, sl = styleProps.length; i < sl; i++) { 871 | var prop = styleProps[i], 872 | uProp = prop.charAt(0).toUpperCase() + prop.slice(1); 873 | 874 | if ( typeof divStyle[ prop ] !== 'undefined' ) { 875 | $.cluetip[ prop ] = prop; 876 | } else { 877 | for (var j=0, pl = prefixes.length; j < pl; j++) { 878 | 879 | if (typeof divStyle[ prefixes[j] + uProp ] !== 'undefined') { 880 | $.cluetip[ prop ] = prefixes[j] + uProp; 881 | break; 882 | } 883 | } 884 | } 885 | 886 | if ( !$.support[ prop ] ) { 887 | $.support[ prop ] = $.cluetip[ prop ]; 888 | } 889 | } 890 | 891 | div = null; 892 | })(); 893 | 894 | $.fn.cluetip.defaults = $.cluetip.defaults; 895 | 896 | })(jQuery); 897 | -------------------------------------------------------------------------------- /jquery.cluetip.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clueTip - v1.2.10 - 2013-09-29 3 | * http://plugins.learningjquery.com/cluetip/ 4 | * Copyright (c) 2013 Karl Swedberg 5 | * Licensed MIT (http://www.opensource.org/licenses/mit-license.php) 6 | */ 7 | (function(t){t.cluetip={version:"1.2.10",template:["
",'
','

','
',"
",'
',"
"].join(""),setup:{insertionType:"appendTo",insertionElement:"body"},defaults:{multiple:!1,width:275,height:"auto",cluezIndex:97,positionBy:"auto",topOffset:15,leftOffset:15,snapToEdge:!1,local:!1,localPrefix:null,localIdSuffix:null,hideLocal:!0,attribute:"rel",titleAttribute:"title",splitTitle:"",escapeTitle:!1,showTitle:!0,cluetipClass:"default",hoverClass:"",waitImage:!0,cursor:"help",arrows:!1,dropShadow:!0,dropShadowSteps:6,sticky:!1,mouseOutClose:!1,delayedClose:50,activation:"hover",clickThrough:!0,tracking:!1,closePosition:"top",closeText:"Close",truncate:0,fx:{open:"show",openSpeed:""},hoverIntent:{sensitivity:3,interval:50,timeout:0},onActivate:function(){return!0},onShow:function(){},onHide:function(){},ajaxCache:!0,ajaxProcess:function(t){return t=t.replace(/<(script|style|title)[^<]+<\/(script|style|title)>/gm,"").replace(/<(link|meta)[^>]+>/g,"")},ajaxSettings:{dataType:"html"},debug:!1}};var e,i="cluetip ui-widget ui-widget-content ui-cluetip",o={},a=0,l=0,n=function(t){return t.replace(/&/g,"&").replace(/>/g,">").replace(/c;)s[c++]='
';return o=t(s.join("")).css({position:"absolute",backgroundColor:"#000",zIndex:g-1,opacity:.1}).addClass("cluetip-drop-shadow").prependTo(e)}var p,d,f,h,m,v;if("object"==typeof s&&(c=s,s=null),"destroy"==s)return this.each(function(){var e=t(this),i=e.data("cluetip");i&&(t(i.selector).remove(),t.removeData(this,"title"),t.removeData(this,"cluetip")),i.title&&e.attrProp("title",i.title),e.unbind(".cluetip").unbind("cluetipMoc")}),t('[id^="cluetip"]').length||t(document).unbind(".cluetip"),this;c=t.extend(!0,{},t.cluetip.defaults,c||{}),a++;var g,b=t.cluetip.backCompat||!c.multiple?"cluetip":"cluetip-"+a,x="#"+b,w=t.cluetip.backCompat?"#":".",y=t.cluetip.setup.insertionType,C=t.cluetip.setup.insertionElement||"body";y=/appendTo|prependTo|insertBefore|insertAfter/.test(y)?y:"appendTo",p=t(x),p.length||(p=t(t.cluetip.template)[y](C).attr("id",b).css({position:"absolute",display:"none"}),g=+c.cluezIndex,f=p.find(w+"cluetip-outer").css({position:"relative",zIndex:g}),d=p.find(w+"cluetip-inner"),h=p.find(w+"cluetip-title"),p.bind("mouseenter mouseleave",function(e){t(this).data("entered","mouseenter"===e.type)})),e=t("#cluetip-waitimage"),!e.length&&c.waitImage&&(e=t("
").attr("id","cluetip-waitimage").css({position:"absolute"}),e.insertBefore(p).hide());var S=(parseInt(p.css("paddingLeft"),10)||0)+(parseInt(p.css("paddingRight"),10)||0);return this.each(function(a){function b(){return!1}function y(t,e){var i=t.status;e.beforeSend(t.xhr,e),"error"==i?e[i](t.xhr,t.textStatus):"success"==i&&e[i](t.data,t.textStatus,t.xhr),e.complete(t.xhr,e.textStatus)}var I,T=this,k=t(this),j=t.extend(!0,{},c,t.metadata?k.metadata():t.meta?k.data():k.data("cluetip")||{}),B=!1,z=!1,P=null,O=j[j.attribute]||("href"==j.attribute?k.attr(j.attribute):k.attrProp(j.attribute)||k.attr(j.attribute)),M=j.cluetipClass;if(g=+j.cluezIndex,k.data("cluetip",{title:T.title,zIndex:g,selector:x,cursor:T.style.cursor||""}),j.arrows&&!p.find(".cluetip-arrows").length&&p.append('
'),!O&&!j.splitTitle&&!s)return!0;j.local&&j.localPrefix&&(O=j.localPrefix+O),j.local&&j.hideLocal&&O&&t(O+":first").hide();var A,L,N,E,Y,H,X,D,R,W,$,q,Q,U,F=parseInt(j.topOffset,10),G=parseInt(j.leftOffset,10),J=isNaN(parseInt(j.height,10))?"auto":/\D/g.test(j.height)?j.height:j.height+"px",K=parseInt(j.width,10)||275,V=K+S+j.dropShadowSteps,Z=this.offsetWidth,_="title"!=j.attribute?k.attr(j.titleAttribute)||"":"";j.escapeTitle&&(_=n(_)),j.splitTitle&&(U=_.split(j.splitTitle),_=j.showTitle||""===U[0]?U.shift():""),k.bind("mouseenter mouseleave",function(t){var e=k.data("cluetip");e.entered="entered"===t.type,k.data("cluetip",e)});var te=function(i){var n,r,v,g=j.onActivate.call(T,i);if(g===!1)return!1;if(z=!0,p=t(x).css({position:"absolute"}),f=p.find(w+"cluetip-outer"),d=p.find(w+"cluetip-inner"),h=p.find(w+"cluetip-title"),m=p.find(w+"cluetip-arrows"),p.removeClass().css({width:K}),O==k.attr("href")&&k.css("cursor",j.cursor),j.hoverClass&&k.addClass(j.hoverClass),E=H=k.offset().top,Y=E+k.innerHeight(),W=k.offset().left,"relative"===t(C).css("position")&&(W-=t(C)[0].getBoundingClientRect().left),Z=k.innerWidth(),i.type==focus||"mouse"==j.positionBy&&!i.pageX?(q=W+Z/2+G,p.css({left:$}),D=H+F):(q=i.pageX,D=i.pageY),"area"!=T.tagName.toLowerCase()&&(N=t(document).scrollTop(),Q=t(window).width()),"fixed"==j.positionBy?($=Z+W+G,p.css({left:$})):($=Z>W&&W>V||W+Z+V+G>Q?W-V-G:Z+W+G,("area"==T.tagName.toLowerCase()||"mouse"==j.positionBy||Z+V>Q)&&(q+20+V>Q?(p.addClass("cluetip-"+M),$=q-V-G>=0?q-V-G-parseInt(p.css("marginLeft"),10)+parseInt(d.css("marginRight"),10):q-V/2):$=q+G),n=0>$?i.pageY+F:i.pageY,(0>$||"bottomTop"==j.positionBy||"topBottom"==j.positionBy)&&($=q+V/2>Q?Q/2-V/2:Math.max(q-V/2,0))),m.css({zIndex:k.data("cluetip").zIndex+1}),p.css({left:$,zIndex:k.data("cluetip").zIndex}),L=t(window).height(),s)I="function"==typeof s?s.call(T):s,d.html(I),ee(n);else if(U){var b=U.length;if(d.html(b?U[0]:""),b>1)for(var S=1;b>S;S++)d.append('
'+U[S]+"
");ee(n)}else if(j.local||0===O.indexOf("#")){if(j.local){var P=t(O+(/^#\S+$/.test(O)?"":":eq("+a+")")).clone(!0).show();j.localIdSuffix&&P.attr("id",P[0].id+j.localIdSuffix),d.html(P),ee(n)}}else if(/\.(jpe?g|tiff?|gif|png)(?:\?.*)?$/i.test(O))d.html(''+_+''),ee(n);else{var A=j.ajaxSettings.beforeSend,X=j.ajaxSettings.error,R=j.ajaxSettings.success,J=j.ajaxSettings.complete;v=u(O,j.ajaxSettings.data);var te={cache:j.ajaxCache,url:O,beforeSend:function(t,i){A&&A.call(T,t,p,d,i),f.children().empty(),j.waitImage&&e.css({top:D+20,left:q+20,zIndex:k.data("cluetip").zIndex-1}).show()},error:function(t,e){c.ajaxCache&&!o[v]&&(o[v]={status:"error",textStatus:e,xhr:t}),z&&(X?X.call(T,t,e,p,d):d.html("sorry, the contents could not be loaded"))},success:function(t,e,i){c.ajaxCache&&!o[v]&&(o[v]={status:"success",data:t,textStatus:e,xhr:i}),B=j.ajaxProcess.call(T,t),"object"==typeof B&&null!==B&&(_=B.title,B=B.content),z&&(R&&R.call(T,t,e,p,d),d.html(B))},complete:function(i,o){J&&J.call(T,i,o,p,d);var a=d[0].getElementsByTagName("img");l=a.length;for(var s=0,c=a.length;c>s;s++)a[s].complete&&l--;l?t(a).bind("load.ct error.ct",function(){l--,0===l&&(e.hide(),t(a).unbind(".ct"),z&&ee(n))}):(e.hide(),z&&ee(n))}};r=t.extend(!0,{},j.ajaxSettings,te),o[v]?y(o[v],r):t.ajax(r)}};k.unbind("showCluetip.cluetip",te).bind("showCluetip.cluetip",te);var ee=function(e){var o,a,l,n=_||j.showTitle&&" ",s="",c="",u=!1,g={bottom:function(t){t.appendTo(d)},top:function(t){t.prependTo(d)},title:function(t){t.prependTo(h)}};if(p.addClass("cluetip-"+M),j.truncate){var b=d.text().slice(0,j.truncate)+"...";d.html(b)}n?h.show().html(n):h.hide(),j.sticky&&(g[j.closePosition]&&(o=t('
'+j.closeText+"
"),g[j.closePosition](o),o.bind("click.cluetip",function(){return oe(),!1})),j.mouseOutClose&&(k.unbind("mouseleave.cluetipMoc"),p.unbind("mouseleave.cluetipMoc"),("both"==j.mouseOutClose||"cluetip"==j.mouseOutClose||j.mouseOutClose===!0)&&p.bind("mouseleave.cluetipMoc",ae),("both"==j.mouseOutClose||"link"==j.mouseOutClose)&&k.bind("mouseleave.cluetipMoc",ae))),f.css({zIndex:k.data("cluetip").zIndex,overflow:"auto"==J?"visible":"auto",height:J}),A="auto"==J?Math.max(p.outerHeight(),p.height()):parseInt(J,10),X=H,R=N+L,u=q>$&&Math.max($,0)+V>q,"fixed"==j.positionBy?X=H-j.dropShadowSteps+F:"topBottom"==j.positionBy||"bottomTop"==j.positionBy||u?("topBottom"==j.positionBy?c=R>H+A+F&&A+F>D-N?"bottom":"top":("bottomTop"==j.positionBy||u)&&(c=H+A+F>R&&D-N>A+F?"top":"bottom"),j.snapToEdge?"top"==c?X=E-A-F:"bottom"==c&&(X=Y+F):"top"==c?X=D-A-F:"bottom"==c&&(X=D+F)):X=H+A+F>R?A>=L?N:R-A-F:"block"==k.css("display")||"area"==T.tagName.toLowerCase()||"mouse"==j.positionBy?e-F:H-j.dropShadowSteps,""===c&&(c=W>$?"left":"right"),a=" clue-"+c+"-"+M+" cluetip-"+M,"rounded"==M&&(a+=" ui-corner-all"),p.css({top:X+"px"}).attrProp({className:i+a}),j.arrows?(/(left|right)/.test(c)&&(l=p.height()-m.height(),s=$>=0&&e>0?H-X-j.dropShadowSteps:0,s=l>s?s:l,s+="px"),m.css({top:s}).show()):m.hide(),v=r(p,j),v&&v.length&&v.hide().css({height:A,width:K,zIndex:k.data("cluetip").zIndex-1}).show(),P||p.hide(),clearTimeout(P),P=null,p[j.fx.open](j.fx.openSpeed||0),t.fn.bgiframe&&p.bgiframe(),j.onShow.call(T,p,d)},ie=function(){z=!1,e.hide(),(!j.sticky||/click|toggle/.test(j.activation))&&(j.delayedClose>0?(clearTimeout(P),P=null,P=setTimeout(oe,j.delayedClose)):(oe(),clearTimeout(P))),j.hoverClass&&k.removeClass(j.hoverClass)},oe=function(e){var i=e&&e.data("cluetip")?e:k,o=i.data("cluetip")&&i.data("cluetip").selector,a=o||"div.cluetip",l=t(a),n=l.find(w+"cluetip-inner"),s=l.find(w+"cluetip-arrows");l.hide().removeClass(),j.onHide.call(i[0],l,n),o&&(i.removeClass("cluetip-clicked"),k.css("cursor",k.data("cluetip").cursor)),o&&_&&i.attrProp(j.titleAttribute,_),j.arrows&&s.css({top:""}),v&&v.hide()},ae=function(){var t=this;clearTimeout(P),P=setTimeout(function(){var e=k.data("cluetip").entered,i=p.data("entered"),o=!1;"both"==j.mouseOutClose&&(e||i)?o=!0:j.mouseOutClose!==!0&&"cluetip"!=j.mouseOutClose||!i?"link"==j.mouseOutClose&&e&&(o=!0):o=!0,o||oe.call(t)},j.delayedClose)};if(t(document).unbind("hideCluetip.cluetip").bind("hideCluetip.cluetip",function(e){oe(t(e.target))}),/click|toggle/.test(j.activation))k.bind("click.cluetip",function(e){return p.is(":hidden")||!k.is(".cluetip-clicked")?(te(e),t(".cluetip-clicked").removeClass("cluetip-clicked"),k.addClass("cluetip-clicked")):ie(e),!1});else if("focus"==j.activation)k.bind("focus.cluetip",function(t){k.attrProp("title",""),te(t)}),k.bind("blur.cluetip",function(t){k.attrProp("title",k.data("cluetip").title),ie(t)});else{k[j.clickThrough?"unbind":"bind"]("click.cluetip",b);var le=function(t){if(j.tracking){var e=$-t.pageX,i=X?X-t.pageY:H-t.pageY;k.bind("mousemove.cluetip",function(t){p.css({left:t.pageX+e,top:t.pageY+i})})}};t.fn.hoverIntent&&j.hoverIntent?k.hoverIntent({sensitivity:j.hoverIntent.sensitivity,interval:j.hoverIntent.interval,over:function(t){te(t),le(t)},timeout:j.hoverIntent.timeout,out:function(t){ie(t),k.unbind("mousemove.cluetip")}}):k.bind("mouseenter.cluetip",function(t){te(t),le(t)}).bind("mouseleave.cluetip",function(t){ie(t),k.unbind("mousemove.cluetip")}),k.bind("mouseover.cluetip",function(){k.attrProp("title","")}).bind("mouseleave.cluetip",function(){k.attrProp("title",k.data("cluetip").title)})}}),this},function(){t.support=t.support||{};for(var e=document.createElement("div"),i=e.style,o=["boxShadow"],a=["moz","Moz","webkit","o"],l=0,n=o.length;n>l;l++){var s=o[l],c=s.charAt(0).toUpperCase()+s.slice(1);if(i[s]!==void 0)t.cluetip[s]=s;else for(var u=0,r=a.length;r>u;u++)if(i[a[u]+c]!==void 0){t.cluetip[s]=a[u]+c;break}t.support[s]||(t.support[s]=t.cluetip[s])}e=null}(),t.fn.cluetip.defaults=t.cluetip.defaults})(jQuery); -------------------------------------------------------------------------------- /lib/jquery.bgiframe.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Version 2.1.3-pre 5 | */ 6 | 7 | (function($){ 8 | 9 | $.fn.bgiframe = ($.browser.msie && /msie 6\.0/i.test(navigator.userAgent) ? function(s) { 10 | s = $.extend({ 11 | top : 'auto', // auto == .currentStyle.borderTopWidth 12 | left : 'auto', // auto == .currentStyle.borderLeftWidth 13 | width : 'auto', // auto == offsetWidth 14 | height : 'auto', // auto == offsetHeight 15 | opacity : true, 16 | src : 'javascript:false;' 17 | }, s); 18 | var html = '