I have developed some sample of Javascript that creates a JIRA tool tip (using the Tipsy AUI guide - https://docs.atlassian.com/aui/5.4.0/docs/tooltips.html) of the Ticket status, Summary, Assignee and fixVersion when you hover over an issue-link. Mainly to be used on the issue search page to prevent continuous Right Click -> Open in New Tab -> Check... which becomes extremely tedious, but can also be used for most other issue links.
It is meant to work on hover of a link however it doesn't always go to plan. When I first hover over ANY issue-link, it produces a tooltip 'undefined'. When I hover over ANY issue-link the second time, it then generates the accurate tooltip as expected. Copy it into your console and I'm pretty sure you will see the same behavior.
I'm not a Javascript Guru so it could be the mechanics of Javascript that I am not aware of so if anyone has any idea why this might be happening please let me know!
I have also packaged it into a JIRA plugin and see the same results.
AJS.toInit(function () {
var url,
issue_id,
offset,
x,
y,
jira_data,
html,
fixVersions,
assignee,
domain = document.location;
// build url whatever it might be
url = domain.protocol +'//'+ domain.hostname
if (domain.port !== "") {
    url += ':'+domain.port
}
AJS.$(".issue-link, td.issuelinks > a, #ghx-issues-in-epic-table > tbody > tr > td > a").tooltip({
    title: function () {
        // GETS THE ISSUE ID FROM THE HREF ELEMENT
        issue_id = (AJS.$(this).attr("href")).slice((AJS.$(this).attr("href")).lastIndexOf("/"), (AJS.$(this).attr("href")).length);
        // QUERIES JIRA API - ALREADY AUTHENTICATED WITH SESSION
        jira_data = AJS.$.getJSON(url+'/rest/api/2/issue' + issue_id, function (json) {
        })
            // AJAX COMPLETE FUNCTION
            jira_data.done(function (jira_data) {
            // CHECK FOR FixVersoin and Multiple FixVersions
            fixVersions = ""
            if (jira_data['fields']['fixVersions'] === undefined) {
                fixVersions = "None";
            } else {
            AJS.$.each(jira_data['fields']['fixVersions'], function(index, value) {
                fixVersions += value['name'] + " ";
            });};
            // CHECK FOR UNASSIGNED
            if (jira_data['fields']['assignee'] === undefined) {
                assignee = "Unassigned";
            } else {
                assignee = jira_data['fields']['assignee']['displayName'];
            };            
            // BUILD STRING OUTPUT
            html = "<span style='text-align:left'>";
            html += "<strong>Status: </strong>" + jira_data['fields']['status']['name'] + "</br>"
            html +="<strong>Assignee: </strong>" + assignee + "</br>";
            html += "<strong>Fix Version:  </strong>" +fixVersions+ "</br>";
            html += "<strong>Summary: </strong>" + jira_data['fields']['summary'];
            html += "</span>"
        });
        return html;
    }, live: true, gravity: AJS.$.fn.tipsy.autoWE, html:true, delayIn: 400, delayOut: 50});
        // REMOVE TITLE TAG TO PREVENT OBSTURCTION
AJS.$(".issue-link, td.issuelinks > a, #ghx-issues-in-epic-table > tbody > tr > td > a").removeAttr('title');    
AJS.$(".issue-link, td.issuelinks > a, #ghx-issues-in-epic-table > tbody > tr > td > a").parent().removeAttr('title');
});