0

Is it possible to get the event of a item in the contextmenu?

The undo function for the input box in Chrome is no good, I wrote about it earlier today. Instead I use a custom undo function that gets triggered by the keydown event of the input box and I have blocked the CTRL+Z keydown event of the document itself (otherwise it interferes).

But the context menu still exist with the old Chrome undo.

I'm looking for something like this. Does it exist?

document.getElementById("input1").addEventListener('contextMenuUndoClicked', function(evt){customUndoFunction(evt, this);}, false);

function customUndoFunction(evt, caller)
{
    evt.preventDefault();    
    < undo stuff >
}
Community
  • 1
  • 1
wubbewubbewubbe
  • 711
  • 1
  • 9
  • 20

1 Answers1

1

I'm not 100% sure what you are trying to do, is it just to prevent the browsers built-in context menu and have your own? If so then something like this perhaps? I don't think you can capture items clicked on the built in context menu, except in certain browsers from their extensions. This code and Undo and Redo worked in Chromium but did not work in FireFox or Opera for me.

#info {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 230px;
    height: auto;
    border-style: solid;
    border-radius: 5px;
    border-width: 1px;
    box-shadow: 10px 10px 5px #888888;
    padding: 20px;
    background-color: #F3F3F3;
}
.menu {
    position: fixed;
    width: 180px;
    height: auto;
    border-style: solid;
    border-radius: 5px;
    border-width: 1px;
    box-shadow: 10px 10px 5px #888888;
    background-color: #F3F3F3;
    visibility: hidden;
}
.menutitle {
    text-align: center;
    font-weight: bold;
    color: white;
    background-color: black;
}
.menuitem {
    text-indent: 10px;
}
.menuitem:hover {
    cursor: pointer;
    width: 100%;
    height: auto;
    background-color: blue;
}
.fadein, .fadeout {
    overflow: hidden;
    /* This container should not have padding, borders, etc. */
}
.fadein {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity 2s linear;
    -moz-transition: opacity 2s linear;
    transition: opacity 2s linear;
}
.fadeout {
    visibility: hidden;
    opacity: 0;
    -webkit-transition: visibility 0s 2s, opacity 2s linear;
    -moz-transition: visibility 0s 2s, opacity 2s linear;
    transition: visibility 0s 2s, opacity 2s linear;
}
.fadein > div, .fadeout > div {
    /* Put any padding, border, min-height, etc. here. */
}
.fadeout > div {
    margin-top: -10000px;
    -webkit-transition: margin-top 0s 2s;
    -moz-transition: margin-top 0s 2s;
    transition: margin-top 0s 2s;
}

<div id="info">
    <div>Hold CTRL for original context menu</div>
</div>
<input id="input1" class="customContext customTextContext" type="text"></input>
<input id="input2" class="customContext customTextContext" type="datetime"></input>
<input id="input3" class="customContext customTextContext" type="number"></input>
<input id="input4" class="customContext customOtherContext" type="color"></input>

/*jslint sub: true, maxerr: 50, indent: 4, browser: true */
/*global */

(function () {
    "use strict";

    var customTextContexts = document.getElementsByClassName("customTextContext"),
        info = document.getElementById("info"),
        inputTextContextMenu,
        inputOtherContextMenu;

    function hideMenus() {
        var menus = document.getElementsByClassName("menu");

        Array.prototype.forEach.call(menus, function (menu) {
            menu.style.visibility = "hidden";
        });
    }

    function toggleMenu(element) {
        var menus = document.getElementsByClassName("menu");

        Array.prototype.forEach.call(menus, function (menu) {
            if (menu.style.visibility === "visible") {
                menu.style.visibility = "hidden";
            } else if (element === menu) {
                menu.style.visibility = "visible";
            }
        });
    }

    function fadeout(element) {
        if (element.className.indexOf("fadein") !== -1) {
            element.className = element.className.replace("fadein", "fadeout");
        } else if (element.className.indexOf("fadeout") === -1) {
            element.className += "  fadeout";
        }
    }

    setTimeout(function () {
        fadeout(info);
    }, 3000);

    function context(evt) {
        var position;

        if (evt.target.className.indexOf("customContext ") !== -1) {
            if (!evt.ctrlKey) {
                evt.preventDefault();
                position = evt.target.getBoundingClientRect();

                if (evt.target.className.indexOf("customTextContext") !== -1) {
                    inputTextContextMenu.style.top = position.bottom + "px";
                    inputTextContextMenu.style.left = position.left + "px";
                    toggleMenu(inputTextContextMenu);
                } else if (evt.target.className.indexOf("customOtherContext") !== -1) {
                    inputOtherContextMenu.style.top = position.bottom + "px";
                    inputOtherContextMenu.style.left = position.left + "px";
                    toggleMenu(inputOtherContextMenu);
                } else {
                    hideMenus();
                }
            } else {
                hideMenus();
            }
        } else {
            hideMenus();
        }
    }

    function undoStuff() {
        hideMenus();
        document.execCommand('undo', false, null);
    }

    function redoStuff() {
        hideMenus();
        document.execCommand('redo', false, null);
    }

    function backStuff() {
        hideMenus();
        window.history.back();
    }

    function forwardStuff() {
        hideMenus();
        window.history.forward();
    } 

    function reloadStuff() {
        window.location.reload();
    }

    function createInputTextContextMenu() {
        var menu = document.createElement("div"),
            rich = document.createElement("div"),
            title = document.createElement("div"),
            undo = document.createElement("div"),
            redo = document.createElement("div"),
            back = document.createElement("div"),
            forward = document.createElement("div"),
            reload = document.createElement("div"),
            line = document.createElement("hr");

        menu.id = "customTextContextMenu";
        menu.className = "menu";
        title.textContent = "Text context menu";
        title.className = "menutitle";
        undo.textContent = "Undo";
        undo.className = "menuitem";
        undo.addEventListener("click", undoStuff, false);
        redo.textContent = "Redo";
        redo.className = "menuitem";
        redo.addEventListener("click", redoStuff, false);
        back.textContent = "Back";
        back.className = "menuitem";
        back.addEventListener("click", backStuff, false);
        forward.textContent = "Forward";
        forward.className = "menuitem";
        forward.addEventListener("click", forwardStuff, false);
        reload.textContent = "Reload";
        reload.className = "menuitem";
        reload.addEventListener("click", reloadStuff, false);

        rich.appendChild(title);
        rich.appendChild(undo);
        rich.appendChild(redo);
        rich.appendChild(line);
        rich.appendChild(back);
        rich.appendChild(forward);
        rich.appendChild(reload);
        menu.appendChild(rich);

        return menu;
    }

    function createInputOtherContextMenu() {
        var menu = document.createElement("div"),
            rich = document.createElement("div"),
            title = document.createElement("div"),
            back = document.createElement("div"),
            forward = document.createElement("div"),
            reload = document.createElement("div");

        menu.id = "customOtherContextMenu";
        menu.className = "menu";
        title.textContent = "Other context menu";
        title.className = "menutitle";
        back.textContent = "Back";
        back.className = "menuitem";
        back.addEventListener("click", backStuff, false);
        forward.textContent = "Forward";
        forward.className = "menuitem";
        forward.addEventListener("click", forwardStuff, false);
        reload.textContent = "Reload";
        reload.className = "menuitem";
        reload.addEventListener("click", reloadStuff, false);

        rich.appendChild(title);
        rich.appendChild(back);
        rich.appendChild(forward);
        rich.appendChild(reload);
        menu.appendChild(rich);

        return menu;
    }

    inputTextContextMenu = createInputTextContextMenu();
    document.body.appendChild(inputTextContextMenu);
    inputOtherContextMenu = createInputOtherContextMenu();
    document.body.appendChild(inputOtherContextMenu);    

    // right clicked context menu
    document.addEventListener("contextmenu", context, false);

    // other click hide context
    document.addEventListener("click", function () {
        hideMenus();
    }, false);
}());

on jsfiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • I like your solution and I'm thinking of using it, only problem is that I now need to implement all other features of the menu, too. I think the event I'm looking for does not exists and therefore I'll close the question by accepting your answer. – wubbewubbewubbe Apr 25 '13 at 10:17