Home > Back-end >  When I drag an element to another location, it drops the wrong element
When I drag an element to another location, it drops the wrong element

Time:12-03

I'm working on a card game and when I try to drop an element to a zone, it drops not only the wrong element, but it drops them in order of their creation no matter which one I drag or where I drop it to. I've been stuck on this for a few hours now, and I've hit a wall. Help pls.

I'll mark where the drag code is.

JS

/*----- constants -----*/
// Sp = Star Power
const p1Deck = []
const p2Deck = []
const p1Shuffle = []
const p2Shuffle = []
const globalShuffle = []
const p1Life = document.querySelector('.p1Life')
const p2Life = document.querySelector('.p2Life')
const p1Hand = document.querySelectorAll('#p1Hand')
const p2Hand = document.querySelectorAll('#p2Hand')

class Card {
    constructor(name, atk, def, spcost, accuracy, dodge, ability, abilityText) {
        this.name = name
        this.atk = atk
        this.def = def
        this.spcost = spcost
        this.accuracy = accuracy
        this.dodge = dodge
        this.ability = ability
        this.abilityText = abilityText
    }
    takeDamage(num) {
        return this.def -= num
    }
    healDamage(num) {
        return this.def  = num
    }
    gainAttack(num) {
        return this.atk  = num
    }
    loseAttack(num) {
        return this.atk -= num
    }
    changeAccuracy(num) {
        this.accuracy -= num
    }
    changeDodge(num) {
        this.dodge  = num
    }
    removeAbility() {
        this.ability = false
    }

}
const celebs = {
cardib: new Card("Cardi B.",3,3,10,100,0,false,"No ability"),
nicki: new Card("Nicki Minaj",4,5,20,100,0,false,"No ability"),
rock: new Card("Dwayne Johnson",8,8,40,100,0,false,"No ability"),
thor: new Card("Chris Helmsworh", 4,8,30,100,0,true,"Any card attacked by this card loses 2 atk and 50% accuracy."),
hart: new Card("Kevin Hart", 2,2,10,100,50,true,"This card has a 50% chance to dodge any attack. Takes no damage while attacking."),
peter: new Card("Peter Dinklage",2,1,0,100,0,true,"This card requires no star power to cast"),
megan: new Card("Megan The Stallion",3,4,20,100,0,true,"This card can perform 2 attacks per turn"),
nas: new Card("Lil Nas X",5,5,30,100,20,true,"While on the stage, your opponent's cards lose 20% accuracy. This card has a 20% chance to dodge any attack."),
terminator: new Card("Arnorld Shwartzenager?",10,10,40,40,0,true,"Only has a 40% chance to hit any attack."),
betty: new Card("Betty White",2,2,10,100,0,true,"Increase your life by 3 points while in battle."),
obama: new Card("Barack Obama",6,6,40,100,0,true,"Raises the attack of all cards on your stage by 2"),
taylor: new Card("Taylor Swift",5,5,30,100,0,true,"Raises your starpower by 10 when cast and on every turn she remains on the field."),
trump: new Card("Donald Trump",6,6,40,100,0,true,"Raises the defense of all cards on your stage by 2."),
gaga: new Card("Lady Gaga",6,7,30,100,0,false,"No Ability"),
harry: new Card("Daniel Radcliffe",2,4,20,100,0,true,"Increases the def of all your cards by 1."),
jim: new Card("Jim Carey",4,2,10,100,0,false,"No Ability"),
tom: new Card("Tom Cruise",5,4,20,70,0,true,"Has a 70% chance to hit any attack."),
rdj: new Card("Robert Downey Jr.",2,5,20,100,0,true,"You gain 5 star power for each battle this card is a part of."),
super: new Card("Henry Cavil",5,8,30,100,0,false,"No Ability"),
morgan: new Card("Morgan Freeman",3,2,10,100,30,true,"Has a 30% chance to dodge any attack."),
}
Object.entries(celebs).forEach((celeb) => {
    globalShuffle.push(celeb)
}
)

/*----- state variables -----*/
let player1Life = 30
let player2Life = 30
let sp1 = 20
let sp2 = 20
let spGain = 20


/*----- functions -----*/
// Drag Code <---------!
function onDragOver(ev) {
    ev.preventDefault()
  }
  
  function onDragStart(ev) {
    ev.dataTransfer.setData("text", ev.target.id)
    console.log(ev.path[0].card)
  }
  
  function onDrop(ev) {
    ev.preventDefault()
    let data = ev.dataTransfer.getData("text")
    ev.target.appendChild(document.getElementById(data))
    console.log(ev.path[0].children[0].card)
  }
//   Drag Code End

function shuffleCards(deck) {
for (let i = deck.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * i);
    let temp = deck[i];
    deck[i] = deck[j];
    deck[j] = temp;
} 
}


function chooseDecks(player) {
    globalShuffle.forEach((celeb) => {
        while (player.length <= 9) {
            if (Math.random() > 0.3) {
    player.push(celeb)
    break
    } else {
        break
    }
} shuffleCards(globalShuffle)
while (p1Deck.length <= 9) {
    if (Math.random() > 0.3) {
    player.push(celeb)
    break
    } else {
        break
    }
}
})
}

function battle(card1,card2) {
    if (Math.random() < card1.accuracy && Math.random() > card2.dodge) {
        card2.takeDamage(card1.atk)
        console.log(card2.def)
    }
    if (Math.random() < card2.accuracy && Math.random() > card2.dodge) {
        card1.takeDamage(card2.atk)
        console.log(card1.def)
    }

}
function directDamage(card1, playerLife) {
    playerLife -= card1.atk
    p1Life.innerText = `Player 1 Life: ${playerLife}`
}

function initialDraw() {
    let j = 0
    for(let i = 0;i < 5;i  ) {
        const p1Card = p1Deck[i][1];
        p1Hand[j].innerHTML = `<div id="card" draggable="true" ondragstart="onDragStart(event)">
        <div >${p1Card.spcost}</div>
        <div ><img src="" alt="">
            <!-- <div ></div> -->
        </div>
        <div ><span >${p1Card.name}<br></span> ${p1Card.abilityText} </div> 
        <div >${p1Card.atk}</div>   
        <div >${p1Card.def}</div>
        </div>`
        const p1cards = document.querySelectorAll('#p1Hand #card');
        p1cards[i].card = p1Card;
        j  = 1

    } 
    for(let i = 0;i < 5;i  ) {
        p1Deck.splice(0,1);
    }

    j = 0
    for(let i = 0;i < 5;i  ) {
        const p2Card = p2Deck[i][1];
        p2Hand[j].innerHTML = `<div id="card" draggable="true" ondragstart="onDragStart(event)">
        <div >${p2Card.spcost}</div>
        <div >
            <!-- <div ></div> -->
        </div>
        <div ><span >${p2Card.name}<br></span> ${p2Card.abilityText} </div> 
        <div >${p2Card.atk}</div>   
        <div >${p2Card.def}</div>
        </div>`
        

        const p2cards = document.querySelectorAll('#p2Hand #card');
        p2cards[i].card = p2Card;
        j  = 1
    }
    for(let i = 0;i < 5;i  ) {
        p2Deck.splice(0,1)
    }
}
/*----- cached elements  -----*/


  /*----- event listeners -----*/

//*-- Main Code --*\\
shuffleCards(globalShuffle)
chooseDecks(p1Deck)
chooseDecks(p2Deck)
shuffleCards(p1Deck)
shuffleCards(p2Deck)
// console.log(p1Deck[1][1])
// battle(p1Deck[0][1],p2Deck[0][1])
initialDraw()


HTML

<body>

    <div id="card" draggable="true" ondragstart="onDragStart(event)">
        <div >40</div>
        <div >
            <!-- <div ></div> -->
        </div>
        <div ><span >Dwayne Johnson<br></span> card is jacked.inline-size: min-content;inline-size: min-content;inline-size: </div> 
        <div >8</div>   
        <div >8</div>
    </div>
    <div
    id="draggable-3"
    
    draggable="true" ondragstart="drag(event)"
  >
    thing 3
  </div>

    <div
    
    ondrop="onDrop(event)" ondragover="allowDrop(event)"
  >
    dropzone
  </div>

  <!-- A div with container id to hold the card -->
  <div id="container">

    <!-- A div with card class for the card  -->
    <div >
      <img src="https://images.unsplash.com/photo-1536323760109-ca8c07450053" alt="Lago di Braies">

      <!-- A div with card__details class to hold the details in the card  -->
      <div >

        <!-- Span with tag class for the tag -->
        <span >Nature</span>

        <span >Lake</span>

        <!-- A div with name class for the name of the card -->
        <div >Lago di Braies</div>

        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Consectetur sodales morbi dignissim sed diam
          pharetra
          vitae ipsum odio.</p>

        <button>Read more</button>
      </div>


    </div>
  </div>
</body>

CSS

#card {
    height: 252px;
    width: 204px;
    margin: 2px;
    background-color: rgb(255, 184, 96);
    border-radius: 15px;
    border: solid;
    
}
#card:hover {
  box-shadow: 0 8px 16px 0 rgba(255, 6, 6, 0.2);
}
.spcost {
    position:sticky;
    display:inline;
    font-size: 35px;
    margin-left: -10px;
    margin-top: -20px;
    border:solid black;
    border-radius: 80px;
    background-color: rgb(1, 211, 211);
    font-weight: 800;
    color: white;
    border-width: 3px;
    z-index: 7;
    
}
.cardimgbox {
 
    height: 15vh;
    width: 9vw;
    border: solid;
    margin-top: -30px;
    margin-left: 24px;
    z-index: 1;
    border-radius: 15px;
    background-image: url(https://i.kym-cdn.com/photos/images/original/002/467/715/082.jpg);
    background-size: cover;
    background-position: 0 auto;
    background-position-x: -20px;

    
}
.atk {
    position: sticky;
    margin-top: 8vh;
    margin-left: -0.5vw;
    font-size: 35px;
    border:solid black;
    border-radius: 80px;
    background-color: rgb(211, 1, 1);
    font-weight: 800;
    color: white;
    border-width: 3px;
    z-index: 1;
    width: 30px;
    text-align: center;
}
.def {
    position: sticky;
    font-size: 35px;
    margin-left: 10.5vw;
    margin-top: -5.5vh;
    border:solid black;
    border-radius: 80px;
    background-color: rgb(1, 211, 211);
    font-weight: 800;
    color: white;
    border-width: 3px;
    z-index: 1;
    width: 30px;
    text-align: center;
}
.name {
  
  font-size: 15px;
  border: solid;
  font-weight:700;
  inline-size: 20vw;
  margin-left: 10px;
}
.ability {
    position: absolute;
    font-size: 14px;
    inline-size: 10vw;
    margin-left: 25px;
    margin-top: 0px;
}

/* test */
.example-parent {
    border: 2px solid #DFA612;
    color: black;
    display: flex;
    font-family: sans-serif;
    font-weight: bold;
  }
  
  .example-origin {
    flex-basis: 100%;
    flex-grow: 1;
    padding: 10px;
  }
  
  .example-draggable {
    background-color: #4AAE9B;
    font-weight: normal;
    margin-bottom: 10px;
    margin-top: 10px;
    padding: 10px;
  }
  
  .example-dropzone {
    background-color: #6DB65B;
    flex-basis: 100%;
    flex-grow: 1;
    padding: 10px;
  }
  img {
    width: 100%;
    border-radius: 12px;
    height: 214px;
    object-fit: cover;
  }
  body {
    background-color: #eaeff1;
    font-family: "Raleway", sans-serif;
  }
  #container {
    max-width: 300px;
  
    /* Center the container in middle on horizontal axis */
    margin: 0 auto;
  
    /* Add empty space above the container (20% of the view height) */
    margin-top: 20vh;
  }
  .card {
    /* Change background color */
    background-color: white;
  
    /* Add border */
    border: 1px solid #bacdd8;
  
    /* Add space between the border and the content */
    padding: 8px;
  
    border-radius: 12px;
  }
  .tag {
    padding: 4px 8px;
    border: 1px solid #e5eaed;
  
    border-radius: 50px;
    font-size: 12px;
    font-weight: 600;
    color: #788697;
  }
  
  /* Style div elements that have class equal to name */
  /* .name {
    font-size: 24px;
    font-weight: 600;
  
    margin-top: 16px;
  }
   */
  /* Style p element */
  p {
    font-size: 14px;
    color: #7f8c9b;
    line-height: 150%;
  }
  
  /* Style button element */
  button {
    border: none;
    padding: 12px 24px;
    border-radius: 50px;
  
    font-weight: 600;
    color: #0077ff;
    background-color: #e0efff;
  
    /* Button is inline-block element by default, it need to have block display for margin: 0 auto; to work */
    margin: 0 auto;
    display: block;
  
    /* Button is a clickable element, therefore it should have a pointer cursor */
    cursor: pointer;
  }
  
  .card__details {
    /* Add space around the details */
    padding: 16px 8px 8px 8px;
  }
  .tag {
  padding: 4px 8px;
  border: 1px solid #e5eaed;

  border-radius: 50px;
  font-size: 12px;
  font-weight: 600;
  color: #788697;
}

/* Style div elements that have class equal to name */
/* .name {
  font-size: 24px;
  font-weight: 600;

  margin-top: 16px;
} */

/* Style p element */
p {
  font-size: 14px;
  color: #7f8c9b;
  line-height: 150%;
}

/* Style button element */
button {
  border: none;
  padding: 12px 24px;
  border-radius: 50px;

  font-weight: 600;
  color: #0077ff;
  background-color: #e0efff;

  /* Button is inline-block element by default, it need to have block display for margin: 0 auto; to work */
  margin: 0 auto;
  display: block;

  /* Button is a clickable element, therefore it should have a pointer cursor */
  cursor: pointer;
}

.card__details {
  /* Add space around the details */
  padding: 16px 8px 8px 8px;
}
button:focus,
button:hover {
  background-color: #0077ff;
  color: #e0efff;
}

CodePudding user response:

This isn't really an answer, more of a comment, but my SO reputation isn't high enough to leave comments yet.

In your HTML, you are calling allowDrop, but I do not see a function named allowDrop in your JS.

  • Related