Skip to main content

Executes a function only once, even after a refresh of the page.

/**
 * Do something only once - a general library.
 * Executes a function only once, even after the refresh of the page.
 *
 * https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
 *
 * Syntax:
 * executeOnce(callback[, thisObject[, argumentToPass1[,
 *     argumentToPass2[, ...[, argumentToPassN]]]]], identifier[, onlyHere])
 *
 * Parameters
 *
 * callback
 *     The function to be executed (function).
 *
 * thisObject (Optional)
 *     The this object (object or null).
 *
 * argumentToPass1, argumentToPass2, argumentToPassN Optional
 *     The arguments of the callback function.
 *
 * identifier
 *     The identifier to check, i.e. the name of the cookie (string)
 *
 * onlyHere (Optional)
 *     A boolean expressing whether the cookie will use the
 *     local path (true) instead of the global one (false or undefined) (boolean
 *     or undefined)
 */
function executeOnce() {
    var argc = arguments.length,
        bImplGlob = typeof arguments[argc - 1] === "string";

    if (bImplGlob) {
        argc++;
    }

    if (argc < 3) {
        throw new TypeError("executeOnce - not enough arguments");
    }

    var fExec = arguments[0],
        sKey = arguments[argc - 2];

    if (typeof fExec !== "function") {
        throw new TypeError("executeOnce - first argument must be a function");
    }

    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) {
        throw new TypeError("executeOnce - invalid identifier");
    }

    if (decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) === "1") {
        return false;
    }

    fExec.apply(argc > 3 ? arguments[1] : null, argc > 4 ? Array.prototype.slice.call(arguments, 2, argc - 2) : []);
    document.cookie = encodeURIComponent(sKey) + "=1; expires=Fri, 31 Dec 9999 23:59:59 GMT" + (bImplGlob || !arguments[argc - 1] ? "; path=/" : "");

    return true;
}

//
// Usage:
//

function alertSomething(sMsg) {
    alert(sMsg);
}

executeOnce(alertSomething, null, "Hello world!!!!", "alert_something");