user18342812
user18342812

Reputation:

Remove the ability to hold down a keyboard key

I have a small page. Circles appear here, when you click on them they disappear.

I added here the possibility that in addition to clicking on the LMB, you can also click on a keyboard key, in my case it is "A".

But I noticed the problem that if you hold down the "A" button, then drive in circles, then the need for clicks disappears, and this is the main goal.

Can I somehow disable the ability to hold this button so that only clicking on it works?

I tried pasting this code, but all animations stopped working for me.

var down = false;
document.addEventListener('keydown', function () {
    if(down) return;
    down = true;

    // your magic code here
}, false);

document.addEventListener('keyup', function () {
    down = false;
}, false);

Get error:

"message": "Uncaught ReferenceError: mouseOverHandler is not defined"

//create circle

var clickEl = document.getElementById("clicks");

var spawnRadius = document.getElementById("spawnRadius");
var spawnArea = spawnRadius.getBoundingClientRect();
const circleSize = 95; // Including borders

function createDiv(id, color) {
    let div = document.createElement('div');
    div.setAttribute('class', id);
    if (color === undefined) {
        let colors = ['#ebc6df', '#ebc6c9', '#e1c6eb', '#c6c9eb', '#c6e8eb', '#e373fb', '#f787e6', '#cb87f7', '#87a9f7', '#87f7ee'];
        randomColor = colors[Math.floor(Math.random() * colors.length)];
        div.style.borderColor = randomColor;
    }
    else {
        div.style.borderColor = color;
    }
    
    // Randomly position circle within spawn area
    div.style.top = `${Math.floor(Math.random() * (spawnArea.height - circleSize))}px`;
    div.style.left = `${Math.floor(Math.random() * (spawnArea.width - circleSize))}px`;
    div.classList.add("circle", "animation");

    // Add click handler
    let clicked = false;
    div.addEventListener('mouseover', mouseOverHandler );
    div.addEventListener('mouseout', mouseOutHandler );
    div.addEventListener('click', (event) => {
        if (clicked) { return; } // Only allow one click per circle
        clicked = true;
        
        div.style.animation = 'Animation 200ms linear forwards';
        setTimeout(() => { spawnRadius.removeChild(div); }, 220);
    });
    
    spawnRadius.appendChild(div);
}

let i = 0;

const rate = 1000;

setInterval(() => {
    i += 1;
    createDiv(`circle${i}`);
}, rate);

    let focusedEl = null;
    const keyDownHandler = (evt) => { 
      if(evt.keyCode === 65 && focusedEl) focusedEl.click(); 
    }
  const mouseOutHandler = (evt) => focusedEl = null;
  const mouseOverHandler = (evt) => focusedEl = evt.currentTarget;

  document.addEventListener('keydown', keyDownHandler );
  window.focus();
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  background: #0f0f0f;
}

.circle {
  width: 80px;
  height: 80px;
  border-radius: 80px;
  background-color: #0f0f0f;
  border: 3px solid #000;
  position: absolute;
}

#spawnRadius {
    top: 55%;
    height: 250px;
    width: 500px;
    left: 50%;
    white-space: nowrap;
    position: absolute;
    transform: translate(-50%, -50%);
    background: #0f0f0f;
    border: 2px solid #ebc6df;
}

@keyframes Animation {
    0% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(.8);
    }
    100% {
        transform: scale(1);
        opacity: 0;
    }
}
<html>
<body>

<div id="spawnRadius"></div>

</body>
</html>

Upvotes: 0

Views: 69

Answers (1)

Bergi
Bergi

Reputation: 664528

You can check the repeat property of the event, which

… is true if the given key is being held down such that it is automatically repeating.

(but notice the compatibility notes on auto-repeat handling)

const keyDownHandler = (evt) => {
    if (!evt.repeat && evt.keyCode === 65) {
//      ^^^^^^^^^^^
        focusedEl?.click();
    }
}

//create circle

var clickEl = document.getElementById("clicks");

var spawnRadius = document.getElementById("spawnRadius");
var spawnArea = spawnRadius.getBoundingClientRect();
const circleSize = 95; // Including borders

function createDiv(id, color) {
    let div = document.createElement('div');
    div.setAttribute('class', id);
    if (color === undefined) {
        let colors = ['#ebc6df', '#ebc6c9', '#e1c6eb', '#c6c9eb', '#c6e8eb', '#e373fb', '#f787e6', '#cb87f7', '#87a9f7', '#87f7ee'];
        randomColor = colors[Math.floor(Math.random() * colors.length)];
        div.style.borderColor = randomColor;
    }
    else {
        div.style.borderColor = color;
    }
    
    // Randomly position circle within spawn area
    div.style.top = `${Math.floor(Math.random() * (spawnArea.height - circleSize))}px`;
    div.style.left = `${Math.floor(Math.random() * (spawnArea.width - circleSize))}px`;
    div.classList.add("circle", "animation");

    // Add click handler
    let clicked = false;
    div.addEventListener('mouseover', mouseOverHandler );
    div.addEventListener('mouseout', mouseOutHandler );
    div.addEventListener('click', (event) => {
        if (clicked) { return; } // Only allow one click per circle
        clicked = true;
        
        div.style.animation = 'Animation 200ms linear forwards';
        setTimeout(() => { spawnRadius.removeChild(div); }, 220);
    });
    
    spawnRadius.appendChild(div);
}

let i = 0;

const rate = 1000;

setInterval(() => {
    i += 1;
    createDiv(`circle${i}`);
}, rate);

let focusedEl = null;
const mouseOutHandler = (evt) => focusedEl = null;
const mouseOverHandler = (evt) => focusedEl = evt.currentTarget;

document.addEventListener('keydown', keyDownHandler );
window.focus();
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  background: #0f0f0f;
}

.circle {
  width: 80px;
  height: 80px;
  border-radius: 80px;
  background-color: #0f0f0f;
  border: 3px solid #000;
  position: absolute;
}

#spawnRadius {
    top: 55%;
    height: 250px;
    width: 500px;
    left: 50%;
    white-space: nowrap;
    position: absolute;
    transform: translate(-50%, -50%);
    background: #0f0f0f;
    border: 2px solid #ebc6df;
}

@keyframes Animation {
    0% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(.8);
    }
    100% {
        transform: scale(1);
        opacity: 0;
    }
}
<html>
<body>

<div id="spawnRadius"></div>

</body>
</html>

Upvotes: 1

Related Questions