JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://cdn.ractivejs.org/releases/0.4.0/ractive.min.js"></script>
<div id='container'></div>
<script id='tpl' type='text/ractive'>
<h1>Tooltip decorator</h1>
<p>This text contains <span decorator='tooltip:A tooltip is a piece of helper text that appears when you mouseover a particular element'>tooltips</span>.</p>
</script>
CSS
body {
font-family: 'Helvetica Neue', 'Arial';
font-size: 16px;
color: #353535;
}
.ractive-tooltip {
display: block;
position: fixed;
max-width: 200px;
background-color: #f9f9f9;
border: 1px solid #eee;
box-shadow: 1px 1px 3px rgba(0,0,0,0.1);
padding: 0.5em;
font-size: 0.8em;
}
#container span {
border-bottom: 1px dashed #999;
}
JavaScript
var tooltipDecorator = function ( node, content ) {
var tooltip, handlers, eventName;
handlers = {
mouseover: function () {
tooltip = document.createElement( tooltipDecorator.elementName );
tooltip.className = tooltipDecorator.className;
tooltip.textContent = content;
node.parentNode.insertBefore( tooltip, node );
},
mousemove: function ( event ) {
tooltip.style.left = event.clientX + tooltipDecorator.offsetX + 'px';
tooltip.style.top = ( event.clientY - tooltip.clientHeight + tooltipDecorator.offsetY ) + 'px';
},
mouseleave: function () {
tooltip.parentNode.removeChild( tooltip );
}
};
for ( eventName in handlers ) {
if ( handlers.hasOwnProperty( eventName ) ) {
node.addEventListener( eventName, handlers[ eventName ], false );
}
}
return {
teardown: function () {
for ( eventName in handlers ) {
if ( handlers.hasOwnProperty( eventName ) ) {
node.removeEventListener( eventName, handlers[ eventName ], false );
}
}
}
}
};
tooltipDecorator.className = 'ractive-tooltip';
tooltipDecorator.element = 'p';
tooltipDecorator.offsetX = 0;
tooltipDecorator.offsetY = -20;
Ractive.decorators.tooltip = tooltipDecorator;
ractive = new Ractive({
el: 'container',
template: '#tpl'
});