DEV Community

Discussion on: Front-end Challenge: Prevent Clicks

Collapse
 
abhishekcghosh profile image
Abhishek Ghosh • Edited

I was tempted to do something like this initially, with event capturing and cancelling:

const blocker = (e) => {
    console.log({ target: e.target, x: e.clientX, y: e.clientY});
    e.stopImmediatePropagation();
    e.preventDefault();
};

const addBlocker = () => { document.documentElement.addEventListener('click', blocker, true); }
const removeBlocker = () => { document.documentElement.removeEventListener('click', blocker, true); }

Which is a bit similar in construct to Jonathan's answer below. But there's some scenarios this will not work, for example, HTML form elements (see comment box on this page) and IFrames (see embed youtube video on this page).

So, here's a little different approach :)

The idea is to put a viewport "mask" that captures clicks to everything in view, but to get the element beneath uses the elementFromPoint API by temporarily hiding the mask and re-enabling it again (so as to not capture itself) :)

const addBlocker = () => {
    const el = document.createElement('div');
    el.id = 'blocker';
    el.style.position = 'fixed';
    el.style.top = 0;
    el.style.bottom = 0;
    el.style.left = 0;
    el.style.right = 0;
    el.style.zIndex = 2147483647;
    document.documentElement.appendChild(el);

    el.addEventListener('click', (e) => {
        el.style.display = 'none';
        console.log({ target: document.elementFromPoint(e.clientX, e.clientY), x: e.clientX, y: e.clientY});
        el.style.display = 'block';
    });
};

const removeBlocker = () => {
    document.documentElement.removeChild(document.getElementById('blocker'));
};

I didn't really put this code in different pages and test though, but it should hopefully work :)

Collapse
 
plavookac profile image
Jelena Jovanovic

This is such super cool solution!

Collapse
 
entrptaher profile image
Md Abu Taher • Edited

Great answer.

I have two questions,

  • How did you come up with this idea of putting a viewport "mask"?
  • Approximately how long did it take to find and write the above two solutions?
Collapse
 
abhishekcghosh profile image
Abhishek Ghosh • Edited

Thanks!

Well.. I believe this is textbook clickjacking :P

I think about 5 minutes of trying out stuff on the dev tools. I didn't actually have to go searching for answer somewhere. I should tell that I was lucky though, to actually detect on this page with the youtube link and input box and that the first method does not work, so I naturally shifted attention trying out the alternate.

Thread Thread
 
entrptaher profile image
Md Abu Taher • Edited

5 minutes and textbook clickjacking 👍 .

Those who searched for blocking events would get "event.preventDefault" no matter how much they want to search.

Just a little different search term, specially a common term that they never thought of, would result in a obviously common way.

I will post my solution used in the video later on :D .

I highly suggest others to try out different solutions other than these two already submitted.

Thread Thread
 
abhishekcghosh profile image
Abhishek Ghosh

Nice! Eager to see other approaches that you may have had :)