I am writing my own tooltip plugin for my portfolio website that I am currently working on.  It works rather well, however, I feel that there is a lot I could improve.  This is one of my bigger jQuery plugins that I have written.(function($) {// Used as a template for addTooltip()var tooltipDefaults = {    'class': null,    'showOn': 'mouseenter',    'hideOn': 'mouseleave',    'direction': 'top',    'offset': null}// Store generated IDs to avoid conflicting IDsvar tooltipIds = new Array();// Keep track of displayed popupsvar displayedTooltips = new Array();function generateUniqueId(){    var id;    do {        id = Math.floor(Math.random()*90000) + 10000;    } while ($.inArray(id, tooltipIds) !== -1);    tooltipIds.push(id);    return id;}function getUniqueId(id){    return parseInt(id.substr(0, 5));}function isUniqueId(id){    return !NaN(getUniqueId(id));}function removeUniqueId(id){        var id = getUniqueId(id);        var idIndex = $.inArray(id, tooltipIds);        if (idIndex !== -1) {            tooltipIds.splice(idIndex);        }}$.fn.displayTooltip = function(){    var element = $(this);    var tooltip = $('#' + element.attr('data-tooltip-id'));    var config = element.data('config');    var offset = element.offset();    var left;       var top;    switch (config.direction) {        case 'left':            top = offset.top + px;            left = offset.left - tooltip.outerWidth() - config.offset + px;            break;        case 'top':            top = offset.top - element.outerHeight() - config.offset + px;            left = offset.left + ((element.outerWidth() / 2) - (tooltip.outerWidth() / 2)) + px;            break;        case 'right':            top = offset.top + px;            left = offset.left + element.outerWidth() + config.offset + px;            break;        case 'bottom':            top = offset.top + element.outerHeight() + config.offset + px;            left = offset.left + ((element.outerWidth() / 2) - (tooltip.outerWidth() / 2)) + px;            break;    }    tooltip.css({        'position': 'absolute',        'left': left,        'top': top,        'z-index': 5000    });    if (element.isTooltipDisplayed()) {        return;    }    tooltip.show();    displayedTooltips.push(element.attr('id'));}$.fn.hideTooltip = function(){    var element = $(this);    var idIndex = $.inArray(element.attr('id'), displayedTooltips);    if (idIndex !== -1) {        displayedTooltips.splice(idIndex);    }    $('#' + element.attr('data-tooltip-id')).hide();}$.fn.addTooltip = function(content, params){    var config = $.extend(tooltipDefaults, params);    return this.each(function() {        var element = $(this);        // If the element already has a tooltip change the content inside of it        if (element.hasTooltip()) {            $('#' + element.attr('data-tooltip-id')).html(content);            return;        }        var tooltipId = (element.is('[id]') ? element.attr('id') : generateUniqueId()) + '-tooltip';        element.attr('data-tooltip-id', tooltipId);        var tooltip = $('<div>', {            id: tooltipId,            role: 'tooltip',            class: config.class        }).html(content);        $('body').append(tooltip);        /**         * If showOn and hideOn are the same events bind a toggle         * listener else bind the individual listeners         */        if (config.showOn === config.hideOn) {            element.on(config.showOn, function() {                if (!element.isTooltipDisplayed()) {                    element.displayTooltip();                } else {                    element.hideTooltip();                }            });        } else {            element.on(config.showOn, function() {                element.displayTooltip();            }).on(config.hideOn, function() {                element.hideTooltip();            });        }        // Store config for other functions use        element.data('config', config);        // Saftey check incase the element recieved focus from the code running above        element.hideTooltip();    });}$.fn.hasTooltip = function(){    return $(this).is('[data-tooltip-id]');}$.fn.isTooltipDisplayed = function(){    var element = $(this);    if (!element.hasTooltip()) {        return false;    }    return ($.inArray(element.attr('id'), displayedTooltips) === -1) ? false : true;}$.fn.removeTooltip= function(){    return this.each(function() {        var element = $(this);        var tooltipId = element.attr('data-tooltip-id');        var config = element.data('config');        $('#' + tooltipId).remove();        if (isUniqueId(tooltpId)) {            removeUniqueId(tooltipId);        }        element.removeAttr('data-tooltip-id');        if (config.showOn === config.hideOn) {            element.off(config.showOn);        } else {            element.off(config.showOn);            element.off(config.hideOn);        }        element.removeData('config');    });}// Reposition tooltip on window resize$(window).on('resize', function() {    if (displayedTooltips.length < 1) {        return;    }    for (var i = 0; i < displayedTooltips.length; i++) {        $('#' + displayedTooltips[i]).displayTooltip();        console.log(displayedTooltips);    }});}(jQuery));
Tooltip plugin for portfolio website
javascript;jquery;html;plugin