I've been working on overhauling the UI experience in the back end systems we use at work and decided that I wanted some tool tips to help tell users what things do without them having to ask us. The only decent tool tip library I've ever found was Prototip by Nick Stakenburg but I knew I wouldn't be able to get away with buying a license for it so I needed to create my own. After my experiences doing the emile.js version of zebedee I decided to give myself a bit of a challenge and go completely frameworkless to create a standalone widget.
Once I had that that figured out it was down to creating the various methods and setting up the event listeners. The main requirement was handling the positioning of the tool tip in relation to it's trigger element. As the position could either be fixed to a point on the trigger or follow the mouse, I ended up creating an object with either the element properties or the mouse coordinates and using that as the starting reference to perform the calculations from, then scanned the position option for one of the y position possibilities and set the top and did the same for the x position options. I later expanded this to have an optional element passed through which would be positioned instead of the tooltip, for use with the animations.
I spent a lot of time going through prototype and zepto to find out how to do the various things I needed to do without the frameworks and ended up stealing various little bits of code, like the user agent regular expressions from zepto so I could determine whether the browser was running webkit, I also tweaked this to check for gecko 2 as well. This was so I could use css animations where available for the transitions. When it came to dealing with the animation, emile.js ended up being my main source of reference, to the point that when I needed to expand my original animation function to be more flexible I ended up taking emile's animation code and a few of it's helpers and tweaking them for my own purposes.
I ended up namespacing the tool tip function inside a tipBox object, so I could add the scan method and keep them together. This means that while the calls are a bit longer, the functions are kept neat and secure, and shouldn't conflict with anything.
The scan method enables you to have a load of elements on a page (preferably a tags for semantic reasons) with a given class name that you can turn into tipBox triggers with one function call. All you need to do is pass the class name and the options you want to use to the method and it will scan the page and set up the tipBox for each one, using the title attribute to supply the text.
Code and demos are available on GitHub: