Hi,
I’m working through the Sitepoint book Simply Javascript and I’m having problems understanding the code execution in the section on event listeners, specifically the use of the keyword this and the results of the getElementsByTagName method.
The js code is here - most of the comments are my attempts at understanding the code. The Core methods are a library given in the book to deal with cross-browser issues regarding to event listeners.
var Tooltips = {
init: function() {
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
var title = links[i].getAttribute("title");
// debug block
targetUrl = links[i].getAttribute("href");
alert("links[i]:" + links[i]); // gives url - why not <a>?
alert("target: " + targetUrl); // gives url
// end debug
if (title && title.length > 0) {
Core.addEventListener(links[i], "mouseover", Tooltips.showTipListener); // element?, "event", listener
Core.addEventListener(links[i], "focus", Tooltips.showTipListener);
Core.addEventListener(links[i], "mouseout", Tooltips.hideTipListener);
Core.addEventListener(links[i], "blur", Tooltips.hideTipListener);
}
}
},
showTip: function(link) {
Tooltips.hideTip(link);
var tip = document.createElement("span"); // tip = span
tip.className = "tooltip"; // now have span with class tooltip
var tipText = document.createTextNode(link.title); // create new textnode with the title text from the orig html
tip.appendChild(tipText); // place the new textnode in the DOM as child of span
link.appendChild(tip); // add the whole span inside the <a>
link._tooltip = tip;
link.title = "";
// fix for safari2/opera9 repaint issue
document.documentElement.style.position = "relative";
},
hideTip: function(link) {
if (link._tooltip) {
link.title = link._tooltip.childNodes[0].nodeValue;
link.removeChild(link._tooltip);
link._tooltip = null;
// fix for safari2/opera9 repaint issue
document.documentElement.style.position = "static";
}
},
showTipListener: function(event) {
//alert(this); // showing url
Tooltips.showTip(this); //
Core.preventDefault(event);
},
hideTipListener: function(event) {
Tooltips.hideTip(this);
}
};
Core.start(Tooltips);
The html file is:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Richer tooltips</title>
<link rel="stylesheet" type="text/css" href="tooltips.css">
<script type="text/javascript" src="../core.js"></script>
<script type="text/javascript" src="tooltips.js"></script>
</head>
<body>
<h1>Heading</h1>
<p>some useful web sites are:</p>
<ul>
<li><a class="richTip" href="http://www.google.co.uk/"
title="This is more information about Google, who promised to do no evil.">Google</a></li>
<li><a class="richTip" href="http://www.twitter.com/"
title="Twitter is a social networking site that allows you to waste time while occasionally receiving useful information.">Twitter</a></li>
<li><a class="richTip" href="http://www.flickr.com" title="I have my photos on my Flickr account.">Flickr</a></li>
</ul>
</body>
</html>
A number of points:
I understood getElementsByTagName to give an array of that element so why does links[i] refer to the url and not the <a> element. Surely the url should be retrieved in a similar way to the title?
In the init function ‘this’ would refer to the window object - yes I get this. I thought that ‘this’ referred to the parent object of the current scope so why does it refer to the url in the showTipListener function?
Can anyone point me in the right direction here?
Regards,
Duncan