DEV Community

Tawhid
Tawhid

Posted on • Edited on

7 2

How to customize right click with javascript?

Have you used web apps that doesn't show default browser thingy when you

right click,rather a custom pop up or menu where you clicked?
well you can do that with vanilla js.
so basically the structure is we attach a 'context menu' event listener to the whole document for global click and to a div for local right click.
You can even customize it with vanilla css.
so our HTML is:

<div class="position">
    <div class="container" align="center">
        <table style="text-align: left; width: 99%; margin-left: auto; margin-right: auto;" border="0" cellpadding="2" cellspacing="2">
            <tbody>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 1<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 2<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 3<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 4<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 5<br>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

css:

.position {
    position: absolute;
    width: 1px;
    height: 1px;
    z-index: 2;
    display: none;
}

.container {
    width: 220px;
    height: auto;
    border: 1px solid black;
    background: rgb(245, 243, 243);
}

.container p {
    height: 30px;
    font-size: 18px;
    font-family: arial;
    width: 99%;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgb(245, 243, 243);
    color: black;
    transition: 0.2s;
}

.container p:hover {
    background: lightblue;
}

td {
    font-family: arial;
    font-size: 20px;
}

td:hover {
    background: lightblue;
    transition: 0.2s;
    cursor: pointer;
}
Enter fullscreen mode Exit fullscreen mode

js:

var cls = true;
var ops;

window.onload = function() {
    document.querySelector(".container").addEventListener("mouseenter", function() {
        cls = false;
    });
    document.querySelector(".container").addEventListener("mouseleave", function() {
        cls = true;
    });
    ops = document.querySelectorAll(".container td");
    for (let i = 0; i < ops.length; i++) {
        ops[i].addEventListener("click", function() {
            document.querySelector(".position").style.display = "none";
        });
    }

    ops[0].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 1!");
        }, 50);
    });

    ops[1].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 2!");
        }, 50);
    });

    ops[2].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 3!");
        }, 50);
    });

    ops[3].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 4!");
        }, 50);
    });

    ops[4].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 5!");
        }, 50);
    });
}

document.addEventListener("contextmenu", function() {
    var e = window.event;
    e.preventDefault();
    document.querySelector(".container").style.padding = "0px";

   var x = e.clientX;
    var y = e.clientY;

    var docX = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || document.body.offsetWidth;
    var docY = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || document.body.offsetHeight;

   var border = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('border-width'));

    var objX = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('width')) + 2;
    var objY = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('height')) + 2;

    if (x + objX > docX) {
        let diff = (x + objX) - docX;
        x -= diff + border;
    }

    if (y + objY > docY) {
        let diff = (y + objY) - docY;
        y -= diff + border;
    }

    document.querySelector(".position").style.display = "block";


    document.querySelector(".position").style.top = y + "px";
    document.querySelector(".position").style.left = x + "px";
});

window.addEventListener("resize", function() {
    document.querySelector(".position").style.display = "none";
});

document.addEventListener("click", function() {
    if (cls) {
      document.querySelector(".position").style.display = "none";
    }
});

document.addEventListener("wheel", function() {
    if (cls) {
        document.querySelector(".position").style.display= "none";
      static = false;
    }
});
Enter fullscreen mode Exit fullscreen mode

and done!
see working demo here: Demo

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (3)

Collapse
 
theawesomeguy47 profile image
TheAwesomeGuy47

Can't answer the question, but just a helpful guide.

Use code blocks rather than making a single line of code. Use them with three of ` together. I believe you can put a language next to it like this:

dev-to-uploads.s3.amazonaws.com/up...

Also with long pieces of code you can put it in a place like GitHub Gists, Paste in/Hastebin or other sites.

Thanks!

Collapse
 
jonrandy profile image
Jon Randy 🎖️

There are very few situations in which this is a good idea. Removing access to the standard context menus in a web browser will mostly only serve to irritate the user

Collapse
 
dumboprogrammer profile image
Tawhid

yea,although in some cases it is amazing
like in discord for example

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series