Search code examples
javascripthtmlcssresponsivecontextmenu

Can someone help me make my custom Context Menu position next to my curser?


As said, i'd need some help on my custom context menu, maybe some litle tweeks here and there, or a new idea of how to solve the problem Or a better approach to this problem. (The HTML and CSS sould stay somewhat the same if its possible).

[I don't know, what I should type, but stack overflow said, I should write more because there is so much code, so just ignore this text here in the square brackets.]

HTML:

    <!-- ----------------------------------------- [CONTEXT MENU] ----------------------------------------- -->
    <div id="context-menu">
        <div class="item-title" id="context-menu-title">
            <i></i>
            <h1>Schnellwahl:</h1>
        </div>
        <div class="item" id="context-menu-home" onmouseleave="contextMenuHome_notActive()"
            onmouseenter="contextMenuHome_active()">
            <a href="/index.html"><i class="fa-solid fa-house"></i>Home</a>
        </div>
        <div class="item" id="context-menu-contact" onmouseleave="contextMenuContact_notActive()"
            onmouseenter="contextMenuContact_active()">
            <a href="/kontakt.html"><i class="fa-solid fa-address-book"></i>Kontakt</a>
        </div>
        <div class="item" id="context-menu-link" onmouseleave="contextMenuLinks_notActive()"
            onmouseenter="contextMenuLinks_active()">
            <a href="/link.html"><i class="fa-solid fa-link"></i>Links</a>
        </div>
        <div id="context-menu-datenschutz" class="item">
            <a id="item-datasafety-lock-open" href="/datenschutz.html"><i
                    class="fa-solid fa-lock-open"></i>Datenschutz</a>
            <a id="item-datasafety-lock-closed" href="/datenschutz.html"><i class="fa-solid fa-lock"></i>Datenschutz</a>
        </div>
    </div>

CSS:

/*--------------- [CONTEXT MENU] ---------------*/

#context-menu {
    position: fixed;
    z-index: 10000;
    width: 150px;
    background: #494949;
    transform: scale(0);
    transform-origin: top left;
    margin-top: 50px;
    margin-left: 2.5px;
}

#context-menu h1 {
    font-size: 1.5rem;
    margin: 0;
    margin-left: 5px;
    font-weight: 600;
}

#context-menu h1::before {
    content: " ";
    position: absolute;
    left: 0;
    bottom: 145px;
    background-color: #e91e63;
    height: 2px;
    box-sizing: border-box;
    width: 150px;
    margin-top: 5px;
}

#context-menu.active {
    transform: scale(1);
    transition: transform 200ms ease-in-out;
}

#context-menu .item {
    padding: 8px 10px;
    font-size: 15px;
    color: #eee;
}

.item-title {
    padding: 8px 10px;
    font-size: 15px;
    color: #eee;
}


#item-datasafety-lock-closed {
    display: none;
    transition: all 0.5s ease;
}

#item-datasafety-lock-open {
    transition: all 0.5s ease;
}

#context-menu-datenschutz:hover #item-datasafety-lock-closed {
    display: block;
}

#context-menu-datenschutz:hover #item-datasafety-lock-open {
    display: none;
}

#context-menu .item:hover {
    background: #555;
}

#context-menu .item a {
    color: #ffffff;
    text-decoration: none;
}

#context-menu .item i {
    display: inline-block;
    margin-right: 5px;
    margin-left: 10px;
}

#context-menu hr {
    margin: 2px;
    border-color: #555;
}

JS:

//----------------------------------------- [CONTEXT MENU] -----------------------------------------

const hoverContacts = document.getElementById("contextMenuContact")

window.addEventListener("contextmenu", function (event) {
    event.preventDefault();
    var contextElement = document.getElementById("context-menu");
    contextElement.style.top = event.offsetY + "px";
    contextElement.style.left = event.offsetX + "px";
    contextElement.classList.add("active");
});



window.addEventListener("click", function () {
    this.document.getElementById("context-menu").classList.remove("active")
});

function contextMenuHome_active() {
    document.getElementById("context-menu-home").innerHTML = '<a href="/index.html"><i class="fa-solid fa-house fa-beat" ></i>Home</a>'
}

function contextMenuHome_notActive() {
    document.getElementById("context-menu-home").innerHTML = '<a href="/index.html"><i class="fa-solid fa-house" ></i>Home</a>'
}

function contextMenuContact_active() {

    document.getElementById("context-menu-contact").innerHTML = `            <a onmouseout="contextMenuContact_notActive" onmouseover="contextMenuContact_active" href="/kontakt.html"><i class="fa-solid fa-address-book fa-bounce" style=" --fa-bounce-start-scale-x: 1; --fa-bounce-start-scale-y: 1; --fa-bounce-jump-scale-x: 1; --fa-bounce-jump-scale-y: 1; --fa-bounce-land-scale-x: 1; --fa-bounce-land-scale-y: 1; --fa-bounce-rebound: 0;" ></i>Kontakt</a>`


}

function contextMenuContact_notActive() {


    document.getElementById("context-menu-contact").innerHTML = `            <a onmouseout="contextMenuContact_notActive" onmouseover="contextMenuContact_active" href="/kontakt.html"><i class="fa-solid fa-address-book"></i>Kontakt</a>`

}

function contextMenuLinks_active() {
    document.getElementById("context-menu-link").innerHTML = '<a href="/link.html"><i class="fa-solid fa-link fa-flip"></i>Links</a>'
}

function contextMenuLinks_notActive() {
    document.getElementById("context-menu-link").innerHTML = '<a href="/link.html"><i class="fa-solid fa-link"></i>Links</a>'
}

Thank you for your Support!


Solution

  • Updated, try something like this maybe. Just a warning, it's most likely not very compatible across browsers.

    See answers: How to disable right-click context-menu in JavaScript

    // html
    <body oncontextmenu="handleOnContextMenu()">...</div>
    
    // maybe you can set it on oyur div as well, im not sure to be honest 
    <div class="your-div" oncontextmenu="handleOnContextMenu()">...</div>
    
    // js
    function openCustomContext(x, y) {
      const yourCtxElement = document.getElementById('ctx-menu')
      yourCtxElement.style.top = y + 'px';
      yourCtxElement.style.left = x + 'px';
    }
    
    function handleOnContextMenu(e) {
      e.preventDefault();
    
      const x = e.clientX;
      const y = e.clientY;
    
      openCustomContext(x, y)
    }
    

    Or you could add it like this as a listener:

    window.addEventListener('contextmenu', function (e) { 
      e.preventDefault(); 
    
      // get your X/Y here...
      const x = e.clientX;
      const y = e.clientY;
      openCustomContext(x, y);
    }, false);