Search code examples
javascripteventsdrag-and-dropevent-handling

JavaScript: Event Listener Function Not Recognizing an Event Past Certain Point on Screen


I have a game built in JavaScript where you drag coins from underneath a dragon into a vault to score points.

Game for reference: https://codeeverydamnday.com/projects/dragondrop/dragondrop.html

You only get the points if you drop the coin within the bounds of the vault. The vault bounds are within these absolute positions:

Left edge of vault: 645px from left side of screen
Right edge of vault: 915px from left side of screen
Top edge of vault: 290px from top edge of screen
Bottom edge of vault: 540px from top edge of screen

On the function that runs when you drop the coin, I have an "if" statement that adds up your score only if the coin you drop has new x-y coordinates that fall within the vault bounds (only relevant code shown, can provide more if needed):

function moveDrop(e) {
  e.preventDefault ();
  coin.style.left = e.pageX - myX + 'px';
  coin.style.top = e.pageY - myY + 'px';
    // myX and myY are the coin's original x-y coordinates. This line resets their new x-y coordinates after the drop
    if (
      coin.style.left > "645" && 
      coin.style.left < "915" && 
      coin.style.top > "290" && 
      coin.style.top < "540") {
        // Function that adds your score each time you drop a coin in the vault
    }
}

The function above works perfectly as-is. To be honest I'm not sure how, since coin.style.left would have a value like 700px and I am asking it to check if that is greater than 645 (without px), but it works.

However, I am trying to simply move the vault 200px more to the right, so that its new x-coordinate bounds are from 845 to 1115 px from the left side of the screen (instead of 645 and 915).

When I update the absolute position of the vault image to 845px, it moves over just fine. When I update the coin.style.left > "645" to coin.style.left > "845" in the if statement above, it works fine.

However, when I update the coin.style.left < "915" to coin.style.left < "1115", I can drag a coin over to the vault but the drop listener is not recognizing that the coin has landed within the vault bounds and is therefore not adding up your score.

I did some testing and it turns out it works until I change the left edge property to coin.style.left < "999". Once I change it to 1000 or more, it breaks. I'm not sure if it has to do with the number 1000 itself, or the fact that it's 4 characters now instead of 3.

The movedrop event handler is listening for actions on the body element, so I thought maybe the document body was only 1000px. However, I've got it set to 1200px in the css.

body {
  width: 1200px;
  height: 650px;
}

I tried inspecting the elements with Chrome dev tools to see if there was some hidden margin after 1000px. Nothing I could see. There is a right margin, but only past 1200px.

I searched "1000" everywhere in my index.html, style.css and script.js files to see if anything else was set to 1000, but there was nothing. Is there anything I'm missing that could be preventing the function to run properly past 1000px?

I can provide the full code if needed.


Solution

  • I figured out the answer to my problem. I was trying to compare two string values instead of two number values.

    In the code below (shortened to relevant code from description above), the coin.style.left value might end up being something like "760px", for example.

    function moveDrop(e) {
      coin.style.left = e.pageX - myX + 'px';
      if (
        coin.style.left > "645" {
          // Do some stuff
      }
    }
    

    Then, in the if statement, I'm asking if "760px" is greater than "645". Since I'm using quotations around the values, I'm comparing strings instead of numbers. I might as well be asking if "dog" is greater than "chair." The function doesn't know exactly how to handle that.

    I fixed this by first converting the coin.style.left value to a number without the "px" after it, by using this substring method:

    function moveDrop(e) {
      coin.style.left = e.pageX - myX + 'px';
      var finalLeft = coin.style.left.substr(0, coin.style.left.length-2);
      if (
        finalLeft > 645 {
          // Do some stuff
      }
    }
    

    The variable finalLeft takes the value from coin.style.left, say "760px", finds the length of the string (5 in this case), and subtract 2 characters from the end to leave you with just "760". Then, the if statement can compare whether 760 is greater than 645.

    Once I made this update, I was able to successfully increase the width to 1200px without issue.