LeonaTheSun
LeonaTheSun

Reputation: 45

clearTimeout on mouseup doesnt work right

I want to click on a point and delete it, but when i press my mouse button down for 3 seconds, i want to do something else with this point. My problem is, that the code doesnt clear the timer, it just deletes the point after 3 seconds, no matter how long i clicked it on the point. Im working with setTimeout and clearTimeout.

    function click(event,d){
        timer= setTimeout(function(){
       /* do something */
    },3000)
        }
        function clickRelease(timer){
            clearTimeout(timer)
      }
      divMag1=d3.selectAll(".scatterlayer .trace .points path ")
      divMag1.on("mousedown", click)
      divMag1.on("mouseup",clickRelease)```

Upvotes: 0

Views: 147

Answers (3)

jmuhammad
jmuhammad

Reputation: 1

For my use sometimes on touch screen device I added a few things:

  1. Implemented long button press using setTimeout()/clearTimeout();
  2. Used pointerup/pointerdown instead of mouseup/mousedown;
  3. Used addEventListener("scroll")/addEventListener("scrollend") to calculate if screen has been moved 100px (my button height) to execute clearTimeout(timer) so the button press can only be recognized when screen is not moving i.e. dragging screen with finger on button and/or when pointerup was reacting too slow.

Upvotes: 0

Stav Noy
Stav Noy

Reputation: 519

V3 - I think you're deleting the target before you can execute what you want.
Note that setTimout may take more than 3 seconds to execute.
Try:

function click(event) {
  const currentTarget = event.currentTarget; // for some reason event.target is null in the timer handler, this fixes it 🤷 

  const timer = setTimeout(() => {
    currentTarget.removeEventListener('mouseup', deleteTarget);
    console.log('stuff');
    // do stuff
  }, 3000);

  function deleteTarget() {
    clearTimeout(timer);
    console.log('deleted');
    currentTarget.removeEventListener('mouseup', deleteTarget); // not required if you're actually deleting the target
    // remove target
  }

  currentTarget.addEventListener('mouseup', deleteTarget);
}

document.querySelector('#but').addEventListener('mousedown', click)
<button id="but">Click</button>


V1:

let timer;
function click(event,d){
    timer= setTimeout(function(){
       /* do something */
    },3000);
}
function clickRelease(){
    clearTimeout(timer)
}
divMag1=d3.selectAll(".scatterlayer .trace .points path ")
divMag1.on("mousedown", click)
divMag1.on("mouseup",clickRelease)

Upvotes: 1

Michael
Michael

Reputation: 11914

You should first declare timer variable. Then to make your mouseup event works on you should wrap clickRelease to event funtion again or use it simply:

...
.addEventListener("mouseup", function() { clearTimeout(timer) })

Working example with button:

var timer
function click(event, d) {
    timer = setTimeout(function () {
        console.log('do something')
    }, 1000)
}
function clickRelease(timer){
    clearTimeout(timer)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clickRelease(timer) })
<button id="but">Click</button>

If you want event to doing something repeatedly while button is down you need to use setInterval not setTimeout like this:

var timer
function click(event, d) {
    timer = setInterval(function () {
        console.log('do something')
    }, 1000)
}
var divMag1 = document.querySelector('#but')
divMag1.addEventListener("mousedown", click)
document.addEventListener("mouseup", function() { clearInterval(timer) })

Note for clearing interval uses clearInterval not clearTimeout. Also the mouseup event handler attached on whole document in my solution not on button.

Upvotes: 0

Related Questions