reptile7's JavaScript blog
Thursday, February 20, 2014
 
Retooling the Tool Tip, Part 1
Blog Entry #310

Mousing over a renderable body element with a title="Relevant info..." attribute pops up a "tool tip": a small, close-to-the-element box holding the Relevant info... text. Our focus today is a "Tip Box" Scripts that Display Text script that generates custom tool tips.

The Tip Box script was authored by Ryan "Dignified" Detert in November 1998. Joe warns that the script is MSIE 4.0 only and it does in fact contain a bunch of features that Netscape 4.x does not support. On my computer, the script behaves dysfunctionally with IE 5.2.3 and isn't run at all by Firefox, Opera, and Safari. Our task, as always, is to bring the script into the modern era by getting it to work with modern browsers.

The script's demo page is here - if you're an IE user, mouseover the Dignified's Domain link* and see what happens. (Go here for a corresponding demo at a non-https:// page.) At the demo page Joe offers a tipbox/ .zip package that comprises
(1) a complete tipBox.html document for working with the script and
(2) a tipbox.js file that holds tipBox.html's script element code.
Click here to download the package.

*The Dignified's Domain link's href target, http://members.xoom.com/dignified, is supposed to provide commentary on the script but is no longer available.

That which is tooltipped

The following anchor element is the business end of the tipBox.html HTML:

<a href="http://members.xoom.com/dignified/" tip="<center>TipBox Script by dignified<br>For use with MSIE4+</center>">Dignified's Domain</a>

The anchor's noteworthy feature is its tip attribute, which is not standard; the tip value will serve as the (hyper)text for a customized tool tip. For now the browser ignores the tip attribute; per the Notes on invalid documents section of the HTML 4.01 Specification:
If a user agent encounters an attribute it does not recognize, it should ignore the entire attribute specification (i.e., the attribute and its value).
While we're at it...

The to-be-tooltipped anchor's unvisited/active/visited colors are set by the body element's start-tag:

<body bgcolor="white" text="blue" link="red" alink="#00ff00" vlink="red">

Deprecated all, the body attributes will be traded in for style declarations in due course.

The anchor is horizontally centered with a center element, which is immediately preceded by a <base target="_parent"> base element that
(a) if the anchor were clicked and
(b) if we were in a frames situation
would replace the parent frameset with the anchor's href resource.
FYI: The base element should be placed in the document head, and would require a href attribute for a strict validation.

A tip for our tool

Before the document body loads, a toolTip( ) function that listens for mouseover events is registered on the document object:

<script language="JScript"><!--
document.onmouseover = toolTip;
...
</script></head>


IE 4.x allows a direct onmouseover-document association but Netscape 4.x doesn't. (For Netscape 4.x an indirect onmouseover-document association is possible via the captureEvents( ) method, but this being the year 2014, let's not go down that road, shall we?) With IE 4.x, mousing over any element in the document body calls the toolTip( ) function because
(a) IE 4.x supports event bubbling and
(b) the mouseover event bubbles.

The toolTip( ) function begins by setting the window's status property to an empty string:

function toolTip( ) { window.status = ""; ... }

The window.status assignment is irrelevant to tool-tip generation and can be thrown out. Next, the toolTip( ) function gets the object that 'fired' the mouseover event:

var src = event.srcElement;

Netscape 4.x supports neither event as a property of the window object nor the srcElement property. For reasonably complete discussions of the IE and Netscape event models, see WebReference.com's "The Internet Explorer Event Model" and "The Navigator Event Model".

The rest of the toolTip( ) function consists of an if statement that is operative if the src object has a tip property:

if (src.tip) { ... }

The src.tip if condition returns true with IE upon mousing over the Dignified's Domain link. As far as I am aware, IE is the only browser that will automatically convert a nonstandard element attribute to a corresponding object property and is consequently the only browser that can get past the src.tip gate.

The if statement first adds src.offsetTop and src.offsetHeight to get the y-axis coordinate of the bottom of the Dignified's Domain link (more precisely, the bottom of the link's border box) and assigns the sum to a y variable:

var y = src.offsetTop + src.offsetHeight; // Set top of tip to bottom of src

Go here for concise definitions of the offsetTop and offsetHeight properties; Netscape support for these properties began with Netscape 6. Contra the // Set top of tip to bottom of src comment, the top edge of the custom tool tip will not be set at y but slightly below that.

The y assignment is followed by the script's key operation: an insertAdjacentHTML( ) command that creates and displays the custom tool tip.

document.body.insertAdjacentHTML("beforeEnd",
"<div id='zTip' style='visibility: visible; z-index: 10; background-color: #ffffff; position: absolute; font-Size: 8pt; border: 1 solid blue; color: blue; background-color: yellow'>"
+ src.tip + "</div>");


The almost-self-explanatory insertAdjacentHTML( ) method is somewhat like the DOM's Node.insertBefore( ), Node.firstChild, Node.appendChild( ), and Node.nextSibling members all rolled into one. It takes two parameters:
(1) a where first parameter that specifies a location at which to insert some HTML and
(2) an html second parameter that specifies the HTML to be inserted.
Implemented by Microsoft, the insertAdjacentHTML( ) method is today supported by IE, Google Chrome, Opera, and Safari, but not by Mozilla's browsers.

The preceding command's calling object is the document.body object and its where parameter is set to beforeEnd, meaning that the html HTML is placed at the very end of the document body, as though we were executing a document.body.appendChild(html) command.

The command's html argument defines a div element container for the custom tool tip. The div is charged with the src anchor's tip value, has an id='zTip' identifier, and is given various styles.

Style notes

• The visibility:visible; declaration can be thrown out as visible is the initial value of the visibility property.

• The div's background-color is set twice, first to white and then to yellow; as determined by the CSS cascading order, the latter is what we see.

• The div is absolutely positioned but not given top and left settings; as a result, the div is (per the beforeEnd insertAdjacentHTML( ) setting) vertically placed just below the document body's concluding center element

<center>&lt;a href="http://members.xoom.com/dignified/" tip="Please Click Here"&gt;Click Here&lt;/a&gt;<p>
<!-- There's no </center> in the source. -->


and is given a normal-flow left (margin-left:8px;) position.

• The z-index:10; declaration can also be removed: more specifically, a z-index setting is unnecessary unless the div is moved to a position at which there's another absolutely positioned element that itself has a "positive stack level", i.e., whose z-index > 0, which is possible but unlikely.

Before moving on:
The insertAdjacentHTML( ) method has an afterBegin where value that puts the html HTML at the very beginning of an element (just before its firstChild). We could have used afterBegin in place of beforeEnd for the insertAdjacentHTML( ) command given that the zTip div is absolutely positioned and thereby removed from the normal flow of the document anyway.

We'll continue our deconstruction of the Tip Box script in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)