pragt .info
VEENENDAAL   
 (c) Hein Pragt
Doorzoek deze site!
Google

Een voorbeeld van CSS / DOM en javascript in de vorm van een tooltip control.

Om technieken te leren kennen is een voorbeeld vaak vele malen duidelijker dan een aantal pagina's met uitleg. Op deze pagina staat een voorbeeld van een tooltip control in javascript. Ik maak gebruik van DOM voor het benaderen van de elementen en CSS voor de vormgeving. Dit script werkt zowel in Internet explorer als mozilla firefox en het is dus ook een aardig voorbeeld hoe u browser compatible kunt programmeren in Javascript.

Een tooltip is een soort venstertje met extra informatie die op uw pagina zal verschijnen wanneer u de muisaanwijzer boven een element plaatst. De control zal na het laden van de pagina alle elementen binnen deze pagina zoeken (in dit geval de A en de IMG elementen) en aan de betreffende elementen een mouseover event toekennen. Het title attribuut zal daarna geheel automatisch als tooltip verschijnen wanneer u de muisaanwijzer op het element plaatst.


Voorbeeld 1:   Dit is een link.

Wanneer u met de muisaanwijzer op deze link gaat staat ziet u een tooltip.

Voorbeeld 2:  

Wanneer u op het plaatje gaat staan ziet u ook een tooltip.

Voorbeeld 3:  

In de tooltip kunt u zelfs HTML code's en afbeeldingen opnemen.


  Download een zip bestand met de broncode en een voorbeeld pagina.

Vormgeving door middel van CSS.

div#toolTip  {
  position: absolute;
  z-index: 1000;
  width: 220px;
  background: #F0E68C;
  border: 1px solid black;
  text-align: left;
  padding: 5px;
  min-height: 1em;
}

div#toolTip p { 
  margin: 0px;
  padding: 0px;
  color: #000080; 
  font: 11px verdana; 
}

div#toolTip zal er voor zorgen dat elke div met de class tooltip deze vormgeving zal krijgen. Door het divje absoluut to positioneren krijgt het een plaats zonder dat rekening gehouden wordt met andere elementen. Door de z-index op 1000 te zetten zorgen we ervoor dat de tooltip altijd op de voorgrond staat. Door middel van de width bepalen we de breedte van de tooltip, background is de achtergrondkleur van de tooltip, border geeft aan wat voor rand er om de tooltip zit en door middel van text-align en padding zal de tekst in de tooltip gepositioneerd worden. Min-height bepaald hoe hoog een element minimaal mag worden weergegeven.

Binnen de tooltip gebruiken we een <p> tag die door en door div#toolTip p zal elke <p> binnen de tooltip deze vormgeving krijgen. De css attributen spreken voor zich en bepalen de layout, kleur en font van de tekst in de tooltip.

Voorbeeld van gebruik van deze tooltip control.

<HTML>
<HEAD>
<TITLE>Tooltip demo.</TITLE>
<LINK href="tooltips.css" rel="stylesheet" type="text/css">
</HEAD>
<BODY>
<script type="text/javascript" src="tooltips.js"></script>
<BR><BR>
<CENTER>
<H3>Dit is een demo van de tooltip conrol.</h3>
<A HREF="http://www.pragt.info" title="Dit is de tooltip voor deze link.">Dit is een link.</A> 
</BODY>
</HTML>

De javascript code van de tooltip control.

// -----------------------------------------------
// Tooltip control (c) H.M. Pragt  2006
// Show the title attribute in a tooltip popup div
// Internet explorer and mozilla compatible
// Just insert this script into the page and all 
// titles on img and a tags will show a tooltip.
// Adjust the layout of the toolkit with the css file.
// -----------------------------------------------

// ------------------------------------
// Find the absolute position in the window
// ------------------------------------

function findPosX(obj) {
var curleft = 0;

  if (obj.offsetParent)  {
    while (obj.offsetParent) {
      curleft += obj.offsetLeft
      obj = obj.offsetParent;
    }
  }
  else if (obj.x)
    curleft += obj.x;
  return curleft;
}

function findPosY(obj) {
var curtop = 0;

  if (obj.offsetParent)  {
    while (obj.offsetParent) {
      curtop += obj.offsetTop
      obj = obj.offsetParent;
    }
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}


// ------------------------------------
// Define a eventcache object
// ------------------------------------

function EventCacheObj() {
 this.listEvents = [];

  // ------------------------------------
  // Define an add methode to the eventcache object
  // ------------------------------------
  this.add = function(node, sEventName, fHandler){
    this.listEvents.push(arguments);
  }

  // ------------------------------------
  // Define a flush methode to the eventcache object
  // ------------------------------------

  this.flush = function () {
  var i, item;

    for (i = this.listEvents.length - 1; i &gt;= 0; i--) {
      item = this.listEvents[i];
      if (item[0].removeEventListener){
         item[0].removeEventListener(item[1], item[2], item[3]);
      }
      if (item[1].substring(0, 2) != "on") {
        item[1] = "on" + item[1];
      }
      if (item[0].detachEvent) {
        item[0].detachEvent(item[1], item[2]);
      }
      item[0][item[1]] = null;
    }
  }
}


  

// ------------------------------------
// Add any event to any object.
// ------------------------------------

function addEvent( obj, type, fn ) {
  if (obj.addEventListener) {     // Mozilla
    obj.addEventListener( type, fn, false );
    EventCache.add(obj, type, fn);
  }
  else if (obj.attachEvent) { // IE
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
    obj.attachEvent( "on"+type, obj[type+fn] );
    EventCache.add(obj, type, fn);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}


// ------------------------------------
// The tooltip object.
// ------------------------------------

function ToolTipObj() { 
  this.tipElements = ['a','img'];  // Array of allowable elements for toolTips
  this.obj = Object;              // Current element that youre hovering over
  this.tip = Object;              // The actual toolTip DIV itself
 
  this.init = function () {
    if (!document.getElementById || 
        !document.createElement || 
        !document.getElementsByTagName ) {
      return;
    }
    var i,j;
    this.tip = document.createElement('div');
    this.tip.id = 'toolTip';
    document.getElementsByTagName('body')[0].appendChild(this.tip);
    this.tip.style.top = '0';
    this.tip.style.visibility = 'hidden';
    var tipLen = this.tipElements.length;
    for ( i=0; i&lt;tipLen; i++ ) {
      var current = document.getElementsByTagName(this.tipElements[i]);
      var curLen = current.length;
      for ( j=0; j&lt;curLen; j++ ) {
        addEvent(current[j],'mouseover',this.tipOver);
        addEvent(current[j],'mouseout',this.tipOut);
        current[j].setAttribute('tip',current[j].title);
        current[j].removeAttribute('title');
      }
    }
  }

  this. tipOut = function () {
    ToolTip.tip.style.visibility = 'hidden';
  }

  this.tipOver = function (e) {
    ToolTip.obj = this;
    ToolTip.ShowTip();
  }
  
  
  this.ShowTip = function () {
    var Ttop,Tleft,ClientWidth,ClientHeight,ScrollTop;
    var TipWidth,TipHeight;

    if (this.obj.getAttribute('tip').length == 0) {
      return;
    }  
    Tleft = findPosX(this.obj);  // offsetLeft;
    Ttop = findPosY(this.obj);  //offsetTop;
    TipWidth = this.tip.offsetWidth;
    TipHeight = this.tip.offsetHeight;
    if (self.innerHeight) { // all except Explorer
      ClientWidth = self.innerWidth;
      ClientHeight = self.innerHeight;
      ScrollTop = self.scrollTop;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      ClientWidth = document.documentElement.clientWidth;
      ClientHeight = document.documentElement.clientHeight;
      ScrollTop = document.documentElement.scrollTop;
    }
    else if (document.body) { // other Explorers
      ClientWidth = document.body.clientWidth;
      ClientHeight = document.body.clientHeight;
      ScrollTop = document.body.scrollTop;
    }
    this.tip.innerHTML = "&lt;p&gt;"+this.obj.getAttribute('tip')+"&lt;/p&gt;"; 
    Ttop = Ttop - (TipHeight + 5);  
    if ((Tleft + TipWidth) &gt; ClientWidth) Tleft = ClientWidth - TipWidth;
    if (Tleft &lt; 1) Tleft = 1;
    if (Ttop &lt; 1) Ttop = 1;
    if (Ttop &lt; ScrollTop) Ttop = ScrollTop + (TipHeight + 5);
    this.tip.style.left = Tleft+'px';
    this.tip.style.top = Ttop+'px';
    this.tip.style.visibility = 'visible';
  }
}


// ------------------------------------
// Create wrapper functions
// ------------------------------------

function pageLoader() {
  ToolTip.init();
}
function pageFlusher() {
  EventCache.flush();
}

// ------------------------------------
// Create the objects
// ------------------------------------
var EventCache = new EventCacheObj();
var ToolTip = new ToolTipObj();

addEvent(window,'load',pageLoader);
addEvent(window,'unload',pageFlusher);


Uitleg bij de Javascript code.

De functie findPosX en findPosY bepalen de waarde van de x en y positie van het object binnen het scherm. De methode offsetLeft geeft de offset ten opzichte van het parent element en dat is niet wat we willen. Om de offset tot het top document te weten te komen gaan we net zo lang terug tot het element geen parent meer heeft en onderweg tellen we de offsets bij elkaar. Door deze waarde te gebruiken hoeven we ook geen rekening meer te houden met de scroll positie van het scherm.

Het volgende object is een eventcache waarin we alle events opslaan via de methode add. Bij het unloaden van de pagina kunnen we dan alle events netjes opruimen waardoor vooral Internet explorer netjes zal blijven werken. Dit object is universeel toepasbaar.

Door middel van de functie addEvent kunnen we een event aan een object op het scherm koppelen voor zowel mozilla als internet explorer.

Het hart van deze code is het tooltip object. De init methode zal een verborgen divje toevoegen aan het document en vervolgens het hele document scannen voor bepaalde tags en hier mousover events aan koppelen. De methodes tipout en tipover zijn wrapper functies om de events af te vangen en de methode showtip zal de tooltip tonen wanneer het element dat de mousover genereerde een title attribuut heeft. Eerst zal de positie bepaald worden en dan innerhtml in de tooltip gestopt worden. Hierna kan de tooltip zichtbaar gemaakt worden.

De functie pageLoader en pageFlusher zijn weer wrappers die door addEvent aangeroepen kunnen worden.

Hierna creëren we een instantie van de objecten en voegen de load en unload events toe aan onze event queue.

Veel succes met deze code en wanneer er opmerkingen zijn voor verbetering hoor ik dit graag. Vriendelijke groet, Hein Pragt




Disclaimer.

De beheerder van deze site betracht uiterste zorgvuldigheid bij het vervaardigen, samenstellen en verspreiden van de informatie op deze website, maar kan op geen enkele wijze instaan voor de juistheid of volledigheid hiervan. De beheerder van deze site aanvaardt geen enkele verantwoordelijkheid voor schade op welke manier dan ook ontstaan door gebruik, onvolledigheid of onjuistheid van de aangeboden informatie op deze website.

De informatie op deze website kan zonder voorafgaande waarschuwing of kennisgeving worden gewijzigd.

Het auteursrecht op deze website berust bij de beheerder van deze site of bij derden die met toestemming dit (beeld)materiaal beschikbaar hebben gesteld. Vermenigvuldiging in wat voor vorm dan ook is alleen toegestaan na voorafgaande toestemming.