Josh Krauth-Harding
Josh Krauth-Harding

Reputation: 39

Disable eventListener for 1 second after invocation

I have an eventListener added to the window that activates code that takes 1000ms to run. Because of this, if you click again in less than 1000ms, it breaks. How can I disable the eventListener from running again within 1000ms of its previous invocation? I have a feeling it may have something to do with Date() but I'm not sure how to implement it.

Here's my code:

window.addEventListener("mousedown", event => {
  let rememberContent = event.target.innerHTML;

  if (event.target.classList.contains('color')) {
    navigator.clipboard.writeText(event.target.dataset.hex);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
    }, 1000)
  } else {
    navigator.clipboard.writeText(event.target.innerHTML);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
    }, 1000)
  }
})

I realize this question has been asked in multiple forms around the internet but I'm struggling to find a vanilla JS solution that works for me. That said, if an answer exists somewhere that I missed, feel free to point me in that direction!

Upvotes: 0

Views: 36

Answers (4)

Corey B
Corey B

Reputation: 449

You can set a global variable that controls whether or not clicks will fire your entire function. Then, you can pause events at the start of your function, and unpause events at the end of the wait period.

let pauseWindowEvent = false;
window.addEventListener("mousedown", event => {
  if (pauseWindowEvent) return false;
  pauseWindowEvent = true

  let rememberContent = event.target.innerHTML;
  if (event.target.classList.contains('color')) {
    navigator.clipboard.writeText(event.target.dataset.hex);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      pauseWindowEvent = false;
    }, 1000)
  } else {
    navigator.clipboard.writeText(event.target.innerHTML);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      pauseWindowEvent = false;
    }, 1000)
  }
})

Upvotes: 0

Konrad
Konrad

Reputation: 24661

It's called throttling, might be useful to search with that word

let working = false

window.addEventListener("mousedown", event => {
  if (working) return
  working = true
  let rememberContent = event.target.innerHTML;

  if (event.target.classList.contains('color')) {
    navigator.clipboard.writeText(event.target.dataset.hex);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      working = false
    }, 1000)
  } else {
    navigator.clipboard.writeText(event.target.innerHTML);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      working = false
    }, 1000)
  }
})

Upvotes: 1

m51
m51

Reputation: 2010

Maybe just add new variable that stores information about state of the process.

For example:

let isRunning = false;
window.addEventListener("mousedown", event => {
  if (isRunning) return;
  isRunning = true;
  let rememberContent = event.target.innerHTML;

  if (event.target.classList.contains('color')) {
    navigator.clipboard.writeText(event.target.dataset.hex);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      isRunning = false;
    }, 1000)
  } else {
    navigator.clipboard.writeText(event.target.innerHTML);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
      isRunning = false;
    }, 1000)
  }
})

If isRunning is true, exit early.

Upvotes: 0

Tom4nt
Tom4nt

Reputation: 112

You can remove the listener and add it back after 1 second.

window.addEventListener("mousedown", handleClick)

function handleClick(event) {
  let rememberContent = event.target.innerHTML;

  if (event.target.classList.contains('color')) {
    navigator.clipboard.writeText(event.target.dataset.hex);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
    }, 1000)
  } else {
    navigator.clipboard.writeText(event.target.innerHTML);
    event.target.innerHTML = "<span>copied!</span>";
    setTimeout(() => {
      event.target.innerHTML = rememberContent;
    }, 1000)
  }
  
  window.removeEventListener("mousedown", handleClick);
  setTimeout(() => window.addEventListener("mousedown", handleClick), 1000)
}

If you have a button, I recommend visually disabling it while the event listener is removed.

Upvotes: 0

Related Questions