tooltips.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Tooltips Class
  2. // A superclass to work with simple CSS selectors
  3. var Tooltips = Class.create();
  4. Tooltips.prototype = {
  5. initialize: function(selector, options) {
  6. var tooltips = $$(selector);
  7. tooltips.each( function(tooltip) {
  8. new Tooltip(tooltip, options);
  9. });
  10. }
  11. };
  12. // Tooltip Class
  13. var Tooltip = Class.create();
  14. Tooltip.prototype = {
  15. initialize: function(el, options) {
  16. this.el = $(el);
  17. this.initialized = false;
  18. this.setOptions(options);
  19. // Event handlers
  20. this.showEvent = this.show.bindAsEventListener(this);
  21. this.hideEvent = this.hide.bindAsEventListener(this);
  22. this.updateEvent = this.update.bindAsEventListener(this);
  23. Event.observe(this.el, "mouseover", this.showEvent );
  24. Event.observe(this.el, "mouseout", this.hideEvent );
  25. // Content for Tooltip is either given through
  26. // 'content' option or 'title' attribute of the trigger element. If 'content' is present, then 'title' attribute is ignored.
  27. // 'content' is an element or the id of an element from which the innerHTML is taken as content of the tooltip
  28. if (options && options['content']) {
  29. this.content = $(options['content']).innerHTML;
  30. } else {
  31. this.content = this.el.title.stripScripts().strip();
  32. }
  33. // Removing title from DOM element to avoid showing it
  34. this.content = this.el.title.stripScripts().strip();
  35. this.el.title = "";
  36. // If descendant elements has 'alt' attribute defined, clear it
  37. this.el.descendants().each(function(el){
  38. if(Element.readAttribute(el, 'alt'))
  39. el.alt = "";
  40. });
  41. },
  42. setOptions: function(options) {
  43. this.options = {
  44. backgroundColor: '#999', // Default background color
  45. borderColor: '#666', // Default border color
  46. textColor: '', // Default text color (use CSS value)
  47. textShadowColor: '', // Default text shadow color (use CSS value)
  48. maxWidth: 250, // Default tooltip width
  49. align: "left", // Default align
  50. delay: 250, // Default delay before tooltip appears in ms
  51. mouseFollow: true, // Tooltips follows the mouse moving
  52. opacity: .75, // Default tooltips opacity
  53. appearDuration: .25, // Default appear duration in sec
  54. hideDuration: .25 // Default disappear duration in sec
  55. };
  56. Object.extend(this.options, options || {});
  57. },
  58. show: function(e) {
  59. this.xCord = Event.pointerX(e);
  60. this.yCord = Event.pointerY(e);
  61. if(!this.initialized)
  62. this.timeout = window.setTimeout(this.appear.bind(this), this.options.delay);
  63. },
  64. hide: function(e) {
  65. if(this.initialized) {
  66. this.appearingFX.cancel();
  67. if(this.options.mouseFollow)
  68. Event.stopObserving(this.el, "mousemove", this.updateEvent);
  69. new Effect.Fade(this.tooltip, {duration: this.options.hideDuration, afterFinish: function() { Element.remove(this.tooltip) }.bind(this) });
  70. }
  71. this._clearTimeout(this.timeout);
  72. this.initialized = false;
  73. },
  74. update: function(e){
  75. this.xCord = Event.pointerX(e);
  76. this.yCord = Event.pointerY(e);
  77. this.setup();
  78. },
  79. appear: function() {
  80. // Building tooltip container
  81. this.tooltip = new Element("div", { className: "tooltip", style: "display: none" });
  82. var arrow = new Element("div", { className: "xarrow" }).insert('<b class="a1"></b><b class="a2"></b><b class="a3"></b><b class="a4"></b><b class="a5"></b><b class="a6"></b>');
  83. var top = new Element("div", { className: "xtop" }).insert(
  84. new Element("div", { className: "xb1", style: "background-color:" + this.options.borderColor + ";" })
  85. ).insert(
  86. new Element("div", { className: "xb2", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  87. ).insert(
  88. new Element("div", { className: "xb3", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  89. ).insert(
  90. new Element("div", { className: "xb4", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  91. );
  92. var bottom = new Element("div", { className: "xbottom" }).insert(
  93. new Element("div", { className: "xb4", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  94. ).insert(
  95. new Element("div", { className: "xb3", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  96. ).insert(
  97. new Element("div", { className: "xb2", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";" })
  98. ).insert(
  99. new Element("div", { className: "xb1", style:"background-color:" + this.options.borderColor + ";" })
  100. );
  101. var content = new Element("div", { className: "xboxcontent", style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor +
  102. ((this.options.textColor != '') ? "; color:" + this.options.textColor : "") +
  103. ((this.options.textShadowColor != '') ? "; text-shadow:2px 2px 0" + this.options.textShadowColor + ";" : "") }).update(this.content);
  104. // Building and injecting tooltip into DOM
  105. this.tooltip.insert(arrow).insert(top).insert(content).insert(bottom);
  106. $(document.body).insert({'top':this.tooltip});
  107. // Coloring arrow element
  108. this.tooltip.select('.xarrow b').each(function(el){
  109. if(!el.hasClassName('a1'))
  110. el.setStyle({backgroundColor: this.options.backgroundColor, borderColor: this.options.borderColor });
  111. else
  112. el.setStyle({backgroundColor: this.options.borderColor });
  113. }.bind(this));
  114. Element.extend(this.tooltip); // IE needs element to be manually extended
  115. this.options.width = this.tooltip.getWidth() + 1; // Quick fix for Firefox 3
  116. this.tooltip.style.width = this.options.width + 'px'; // IE7 needs width to be defined
  117. this.setup();
  118. if(this.options.mouseFollow)
  119. Event.observe(this.el, "mousemove", this.updateEvent);
  120. this.initialized = true;
  121. this.appearingFX = new Effect.Appear(this.tooltip, {duration: this.options.appearDuration, to: this.options.opacity });
  122. },
  123. setup: function(){
  124. // If content width is more then allowed max width, set width to max
  125. if(this.options.width > this.options.maxWidth) {
  126. this.options.width = this.options.maxWidth;
  127. this.tooltip.style.width = this.options.width + 'px';
  128. }
  129. // Tooltip doesn't fit the current document dimensions
  130. if(this.xCord + this.options.width >= Element.getWidth(document.body)) {
  131. this.options.align = "right";
  132. this.xCord = this.xCord - this.options.width + 20;
  133. this.tooltip.down('.xarrow').setStyle({left: this.options.width - 24 + 'px'});
  134. } else {
  135. this.options.align = "left";
  136. this.tooltip.down('.xarrow').setStyle({left: 12 + 'px'});
  137. }
  138. this.tooltip.style.left = this.xCord - 7 + "px";
  139. this.tooltip.style.top = this.yCord + 12 + "px";
  140. },
  141. _clearTimeout: function(timer) {
  142. clearTimeout(timer);
  143. clearInterval(timer);
  144. return null;
  145. }
  146. };