EDIT: Replaced my version of the point 1 code example with that supplied by TheMadExile.
NOTE: The code of the follow solution is heavily based on the source code of the SugarCube 2 <<linkappend>> related macros, you should thank TheMaxExile for all the good parts, and blame me for any bugs that I have introduced due to any lacking in my Javascript knowledge.
1. The following Javascript example creates three new custom macros named: <<hoverappend>>, <<hoverprepend>>, and <<hoverreplace>>. This code should be placed within your Story Javascript area.
The three new macros work very similar to the associated <<linkappend>> related macros except that the TwineScript contain within their body is executed the first time the mouse cursor is moved over the related "Link Text" instead of upon selection of it.
/*
<<hoverappend>>, <<hoverprepend>>, & <<hoverreplace>>
*/
Macro.add(['hoverappend', 'hoverprepend', 'hoverreplace'], {
isAsync : true,
tags : null,
handler : function () {
if (this.args.length === 0) {
return this.error('no hover text specified');
}
// Custom debug view setup.
if (Config.debug) {
this.createDebugView(
this.name,
this.source + this.payload[0].contents + '<</' + this.name + '>>''
);
}
const $hover = jQuery(document.createElement('span'));
const $insert = jQuery(document.createElement('span'));
const transition = this.args.length > 1 && /^(?:transition|t8n)$/.test(this.args[1]);
$hover
.wikiWithOptions({ profile : 'core' }, this.args[0])
.addClass('link-hover macro-' + this.name)
.one('mouseenter', (function (macroName, contents) {
return this.createShadowWrapper(function (event) {
if (macroName === 'hoverreplace') {
$hover.remove();
}
else {
$hover.removeClass('link-hover');
}
if (contents !== '') {
const frag = document.createDocumentFragment();
new Wikifier(frag, contents);
$insert.append(frag);
}
if (transition) {
setTimeout(function () {
$insert.removeClass('macro-' + macroName + '-in');
}, Engine.minDomActionDelay);
}
});
})(this.name, handler.payload[0].contents))
.appendTo(this.output);
$insert.addClass('macro-' + this.name + '-insert');
if (transition) {
$insert.addClass('macro-' + this.name + '-in');
}
if (this.name === 'hoverprepend') {
$insert.insertBefore($hover);
}
else {
$insert.insertAfter($hover);
}
}
});
2. The following CSS is used to style the Link Text of the new macros, it should be placed within your Story Stylesheet area. You should change this CSS to suit your needs.
.link-hover {
cursor: pointer;
color: orange;
text-decoration: none;
-webkit-transition-duration: .2s;
-o-transition-duration: .2s;
transition-duration: .2s;
}
3. The following TwineScript demonstrates how to use the new macros within a Passage.
Some text with a <<hoverappend "link">> that displays this text ''after'' the link once hovered over.<</hoverappend>>
Some text with a <<hoverprepend "link">> that displays this text ''before'' the link once hovered over.<</hoverprepend>>
Some text with a <<hoverreplace "link">> that displays this text ''instead of'' the link once hovered over.<</hoverreplace>>