Toon posts:

[JS] Unobtrusive tooltips

Pagina: 1
Acties:
  • 102 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik wil op mijn website eigen tooltips kunnen toevoegen aan links of plaatjes. Dit moet wel unobtrusive (wat is hier eigenlijk de nederlandse naam voor?).

Wat is in dat geval de beste aanpak?
code:
1
2
3
4
5
6
<img src="plaatje.gif" id="plaatje_1" tip="extra info over het plaatje">

// of

<div class="plaatje"><img src="plaatje" id="plaatje_1"></div>
<div class="tip">extra info over het plaatje</div>

De eerste methode spreekt mij het meeste aan: het document doorlopen op elementen met een "tip" property en dan een onmouseover event koppelen aan dat element. Nadeel is dat ik dan geen HTML kan gebruiken, want volgens mij wordt dit een puinhoop:

code:
1
<img src="plaatje.gif" id="plaatje_1" tip="<b>dit</b>is mijn <br> tooltip">

Nog een andere mogelijkheid is om de tooltips in de head te definieren en deze onload aan de elementen te hangen:
JavaScript:
1
2
3
4
5
var tooltips = [
  ['plaatje_1', 'extra info over het plaatje'],
  ['plaatje_2', 'ook hier een tooltip'],
  ['link_1', '<b>extra info</b> over de <br> link'] /* nu wel html mogelijk */
];

En zo zijn er nog wel meer mogelijkheden. Mijn vraag is: wat zijn best-practices hierbij? Wat is het meest gangbaar?

  • Xiliath
  • Registratie: Oktober 2003
  • Laatst online: 30-10-2022
Zelf gebruik ik <span></span> als ik extra info of css opmaak kwijt wil in een href.
Weet niet of het gebruikelijk is, maar functioneert voor mij prima.

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 12-12-2025
Ik denk dat je het beste de title of alt-tag kunt gebruiken, die zijn namelijk gestandaardiseerd, en schoppen je validatie dus niet in de war. Je kunt met JS al die alt- of title-tags uitlezen en daarna er acties aan hangen, waaronder het uitwissen van die tags.

HTML erinhangen is ook simpel, dit doe je door de HTML te encoden (&lt; ipv <)

We are shaping the future


Verwijderd

Wbt unobtrusive. Ik zou gaan voor onopvallend of niet storend.

Verwijderd

Alex) schreef op dinsdag 23 oktober 2007 @ 13:46:
Ik denk dat je het beste de title of alt-tag kunt gebruiken, die zijn namelijk gestandaardiseerd, en schoppen je validatie dus niet in de war. Je kunt met JS al die alt- of title-tags uitlezen en daarna er acties aan hangen, waaronder het uitwissen van die tags.

HTML erinhangen is ook simpel, dit doe je door de HTML te encoden (&lt; ipv <)
Waarbij je natuurlijk alt- en title-attributen bedoelt ;)

Maar voor de rest heeft Alex) helemaal gelijk. Veel meer unobtrusive dan dat wordt het niet. Non-JS browsers gebruiken gewoon netjes de title, JS-browsers krijgen de fancy shit.

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 12-12-2025
Attributen, dat was het ja, ik was het even kwijt ;)

Meestal klop ik ze gewoon in en denk ik er verder niet eens meer over na... :+

We are shaping the future


  • Pendaco
  • Registratie: Augustus 2003
  • Laatst online: 17:04

Pendaco

Vogon Poetry FTW!

Kijk anders ook eens naar Mootools Tips; http://demos.mootools.net/Tips
Zelfde opbouw als hierboven en netjes beschreven :)

Verwijderd

Topicstarter
Ik heb nu de volgende javascripts in de head van mijn document:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function addLoadEvent(func) {
  var oldOnload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  }
  else {
    window.onload = function() {
      oldOnload();
      func();
    }
  }
}

function hasClass(node, className) {
  if (node.className == className) {
    return true;
  }
  var reg = new RegExp('(^| )' + className + '($| )')
  if (reg.test(node.className)) {
    return true;
  }
  return false;
}

function addEvent(element, eventType, handler) {
    if (element.addEventListener) {
        element.addEventListener(eventType, handler, false);
  }
    else if (element.attachEvent) {
        element.attachEvent('on' + eventType, handler);
  }
}

function findTooltips() {
  var image, images = document.getElementsByTagName('img');
  for (var i = 0; image = images[i]; i++) {
    if (hasClass(image, 'tooltip')) {
      addEvent(image, 'mouseover', doAlert);
    }
  }
}

function doAlert() {
  alert('gelukt!');
}

addLoadEvent(findTooltips);

En daarbij de volgende html:
HTML:
1
2
3
4
5
6
7
8
<html>
  <head>
    <script>/* hier dus de javascripts */</script>
  </head>
  <body>
    <img class="tooltip" src="http://www.google.nl/intl/nl_nl/images/logo.gif" title="google logo">
  </body>
</html>

Ik probeer dus een onmouseover actie aan images met class "tooltip" toe te kennen. Maar als ik deze code in de browser afspeel, verdwijnt het google logo en gebeurt er verder niets. Kan iemand mij vertellen waarom dit gebeurt?

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 12-12-2025
De lengte van een array vraag je op met array.length, dus waarom je image en images gebruikt die je dezelfde inhoud geeft, om daarna daarover te iteraten is me onduidelijk en lijkt me de bron van je problemen.

JavaScript:
1
for(var i = 0; i < image.length; i++)


Probeer dat eens? ;)

We are shaping the future


  • Martinspire
  • Registratie: Januari 2003
  • Laatst online: 15:19

Martinspire

Awesomeness

Je kunt het ook met een plugin van jQuery doen:
http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/

Hiermee kun je een titletag aan iets toekennen waarna je hem in de tooltip kunt laten zien. Als je dan bv een speciale class ervoor maakt dan zal hij alleen de tooltip laten zien bij de class.

Bekijk de demo maar eventjes:
http://jquery.bassistance.de/tooltip/

Martinspire - PC, PS5, XSX


Verwijderd

Topicstarter
@a(ex) - het probleem zat hem in een stukje css dat ik niet gepost had maar wel in het document stond. Ik had hier een visibility: hidden staan. STOM!! maar wel bedankt voor je antwoord :)

Inmiddels is het me gelukt om een tooltip te laten verschijnen en verdwijnen, met daarin de tekst uit de image-alt:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function findTooltips() {
  var images = document.getElementsByTagName('img');
  for (var i = 0; i < images.length; i++) {
    var image = images[i];
    if (hasClass(image, 'tooltip')) {
      addEvent(image, 'mouseover', function() {toggleTooltip.apply(this, [image]);});
      addEvent(image, 'mouseout' , function() {toggleTooltip.apply(this, [image]);});
    }
  }
}

function toggleTooltip(el) {
  var tooltip = document.getElementById('tip_' + el.id);
  if (tooltip != null) {
    var style = tooltip.style.visibility;
    tooltip.style.visibility = (style == 'visible') ? 'hidden' : 'visible';
  }
  else {
    var div = document.createElement('div');
    div.id = 'tip_' + el.id;
    div.className = 'tooltip';
    div.style.position = 'absolute';
    div.style.visibility = 'visible';
    
    // div.style.left = ...px;
    // div.style.top  = ...px;
    
    div.innerHTML = el.alt;
    document.body.appendChild(div);
  }
}

Maar nu loop ik tegen een groot probleem op: zo'n plaatje waar een tooltip bij moet verschijnen, kan overal op de (web)pagina staan. Ik wil dat de tooltip altijd 10 pixels onder het plaatje verschijnt. Hiervoor moet ik dus een left en top meegeven aan de tooltip-div (zie code).

Mijn vraag is: hoe kan ik (binnen findTooltips of toogleTooltip) uitlezen op welke positie het plaatje (mbv. coordinaten?) staat, zodat ik de left en right van de tooltip-div kan uitrekenen?

[ Voor 129% gewijzigd door Verwijderd op 24-10-2007 00:43 ]


  • t-x-m
  • Registratie: November 2003
  • Laatst online: 05-01 18:35

t-x-m

.NET Nerd

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function toggleTooltip(el) {
  var tooltip = document.getElementById('tip_' + el.id);
  if (tooltip != null) {
    var style = tooltip.style.visibility;
    tooltip.style.visibility = (style == 'visible') ? 'hidden' : 'visible';
  }
  else {
    var div = document.createElement('div');
    div.id = 'tip_' + el.id;
    div.className = 'tooltip';
    div.style.position = 'absolute';
    div.style.visibility = 'visible';
    
    div.style.left = el.offsetLeft;
    div.style.top  = el.offsetTop + 10;
    
    div.innerHTML = el.alt;
    document.body.appendChild(div);
  }
}
???

GC.Collect();


  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 12:05

sopsop

[v] [;,,;] [v]

Verwijderd schreef op dinsdag 23 oktober 2007 @ 13:47:
Wbt unobtrusive. Ik zou gaan voor onopvallend of niet storend.
Ik denk dat in deze context 'niet verstorend' beter past.

Verwijderd

Topicstarter
@t-x-m: thanks! Ik zat al moeilijk te denken dat ik de coordinaten van de het muispijltje moest uitlezen op het moment van klikken, en daar iets mee doen |:(

Verwijderd

Topicstarter
Ik heb nu de volgende functies:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function toggleTooltip(el) {
  // alert(el);
  var tooltip = document.getElementById('tip_' + el.id);
  if (tooltip != null) {
    var style = tooltip.style.visibility;
    tooltip.style.visibility = (style == 'visible') ? 'hidden' : 'visible';
  }
  else {
    var div = document.createElement('div');
    div.id = 'tip_' + el.id;
    div.className = 'tooltip';
    div.style.position = 'absolute';
    div.style.visibility = 'visible';
    
    div.style.left = el.offsetLeft + 'px';
    div.style.top  = el.offsetTop + el.height + 5 + 'px';
    
    div.innerHTML = tooltipContent(el.alt);
    document.body.appendChild(div);
  }
}

function findTooltips() {
  var images = document.getElementsByTagName('img');
  for (var i = 0; i < images.length; i++) {
    var image = images[i];
    // alert(image.id);
    if (hasClass(image, 'tooltip')) {
      addEvent(image, 'mouseover', function() {toggleTooltip.apply(this, [image]);});
      addEvent(image, 'mouseout' , function() {toggleTooltip.apply(this, [image]);});
    }
  }
}

Met in het document de volgende plaatjes:
HTML:
1
2
<img id="img_1" class="tooltip" src="plaatje.gif" alt="extra info">
<img id="img_2" class="tooltip" src="beeld.png" alt="nog meer uitleg">

Dit werkte eerst wel (op een lokale html pagina), maar niet meer nu ik het in mijn (online) website gebruik. De alert(el) in regel 2 levert wel een "object HTMLImageElement" op, maar de properties (zoals el.id en el.alt) zijn leeg. Bij de alert in regel 27 bestaan die properties nog wel. Er gaat dus iets fout bij het plaatsen van de eventListener. Kan iemand mij vertellen wat? Heeft dit iets te maken met het gebruik van this wat niet klopt? En wat klopt er dan niet?

[ Voor 7% gewijzigd door Verwijderd op 24-10-2007 17:52 ]


Verwijderd

Alex) schreef op dinsdag 23 oktober 2007 @ 20:23:
De lengte van een array vraag je op met array.length, dus waarom je image en images gebruikt die je dezelfde inhoud geeft, om daarna daarover te iteraten is me onduidelijk en lijkt me de bron van je problemen.

JavaScript:
1
for(var i = 0; i < image.length; i++)


Probeer dat eens? ;)
of je nou
JavaScript:
1
2
3
4
for (i=0; i<images.length; i++) {
  image = images[i];
  //meer
}
of
JavaScript:
1
2
3
for (i=0; image = images[i]; i++) {
  //meer
}
doet, maakt (hier) niet heel veel uit. Je kan hoogstens zeggen dat de eerste wat minder efficient is omdat je de hele tijd de length van de collection aanvraagt (die nog iets duurder is dan de length van een array).

  • equationunequal
  • Registratie: Oktober 2001
  • Laatst online: 21:02
Verwijderd schreef op woensdag 24 oktober 2007 @ 18:51:
[...]

of je nou
JavaScript:
1
2
3
4
for (i=0; i<images.length; i++) {
  image = images[i];
  //meer
}
of
JavaScript:
1
2
3
for (i=0; image = images[i]; i++) {
  //meer
}
doet, maakt (hier) niet heel veel uit. Je kan hoogstens zeggen dat de eerste wat minder efficient is omdat je de hele tijd de length van de collection aanvraagt (die nog iets duurder is dan de length van een array).
Ik doe het altijd zo:
JavaScript:
1
2
3
4
5
var numImages = images.length;
for (var i = 0; i < numImages; i++) {
  image = images[i];
  //meer
}


Daarbij hoeft images.length ook maar 1 keer opgevraagd te worden, maar stopt de loop wel automatisch na de lengte van de array bereikt te hebben...

[ equationunequal.nl - portret & model fotografie ] [ newskin.nl - socials ]


Verwijderd

Topicstarter
Maar kan iemand mij ook helpen bij mijn vraag (zie twee posts boven)? Ik denk dat het nu duidelijk is hoe je zo'n for-loop zou kunnen bouwen ;)

[ Voor 8% gewijzigd door Verwijderd op 25-10-2007 12:13 ]


  • Muscrerior
  • Registratie: September 2005
  • Laatst online: 24-12-2025
Ik vind persoonlijk Cooltips erg makkelijk. Makkelijk implementeren en klaar.

Verwijderd

Topicstarter
@Muscrerior - ik bouw graag mijn eigen scriptje, niet in de laatste plaats om ervan te leren :)

  • equationunequal
  • Registratie: Oktober 2001
  • Laatst online: 21:02
Verwijderd schreef op donderdag 25 oktober 2007 @ 12:13:
Maar kan iemand mij ook helpen bij mijn vraag (zie twee posts boven)? Ik denk dat het nu duidelijk is hoe je zo'n for-loop zou kunnen bouwen ;)
Overheen gelezen. IE heeft de vreemde gewoonte dat this niet refereert naar de eigenaar van het event als je attachEvent gebruikt (IE bug nummer zoveel). Hiervoor zal je een addEvent alternatief moeten implementeren waarbij this wel ondersteund wordt.

Zie: http://www.quirksmode.org...5/08/addevent_consid.html

Een goed alternatief is de addEvent variant van Dean / Crisp:

http://therealcrisp.xs4all.nl/upload/addEvent_dean.html

[ equationunequal.nl - portret & model fotografie ] [ newskin.nl - socials ]

Pagina: 1