简体   繁体   中英

events are fired multiple times in class/object

To explain the context, i have a div named Repertory who contain divs with class Card, on the instantiation of my class Explorer i use loadDragNDropEvents() who load dragstart and dragend events on cards, when I start a drag i need to make my canvas have over event and drop event (only when a card is drag).

  1. Dragstart and dragend are fired twice, how can i fix that ? i already try to do a removeEventListener before the adding one without success
  2. Roughly as above dragover and drop events aren't removed, how can i fix that ?

My code : (I simplify it to focus on the needs)

HTML :

<div id="Repertory">
  <div class="Card">Card 1</div>
  <div class="Card">Card 2</div>
  <div class="Card">Card 3</div>
  <div class="Card">Card 4</div>
  <div class="Card">Card 5</div>
  <div class="Card">Card 6</div>
</div>

<canvas id="canvas" style="width:100px; height: 100px;"></canvas>

JS :

const canvas = document.getElementById("canvas");
var explorer1 = new Explorer(); // Create an Explorer and use loadDragNDropEvents() 2 times

class Explorer() {

  contructor(){
    loadDragNDropEvents();
    loadDragNDropEvents();
  }

  loadDragNDropEvents() {
    const repertory = document.getElementById("Repertory");
    if (repertory == undefined) { return this; }
        
    const cards = repertory.querySelectorAll(".Card"); 
    if (cards.length <= 0) { return this; }

    console.log("loadDragNDropEvents");

    cards.forEach(card => {
      card.addEventListener("dragstart", this.#CardDragStartEvent.bind(this), false);
      card.addEventListener("dragend", this.#CardDragEndEvent.bind(this), false);
    });
  }

  unloadDragNDropEvents() {
    const repertory = document.getElementById("Repertory");
    if (repertory == undefined) { return this; }
        
    const cards = repertory.querySelectorAll(".Card"); 
    if (cards.length <= 0) { return this; }

    console.log("loadDragNDropEvents");

    cards.forEach(card => {
      card.removeEventListener("dragstart", this.#CardDragStartEvent.bind(this), false);
      card.removeEventListener("dragend", this.#CardDragEndEvent.bind(this), false);
    });
  }

  #CardDragStartEvent(event) {
    console.log("dragstart");
    canvas.addEventListener("dragover", this.#CanvasDragOverEvent.bind(this), false);
    canvas.addEventListener("drop", this.#CanvasDropEvent.bind(this), false);
    event.dataTransfer.effectAllowed = "move";
  }

  #CardDragEndEvent(event) {
    console.log("dragend");
    canvas.removeEventListener("dragover", this.#CanvasDragOverEvent.bind(this), false);
    canvas.removeEventListener("drop", this.#CanvasDropEvent.bind(this), false);
  }

  #CanvasDragOverEvent(event) {
    console.log("over");
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";
  }

  #CanvasDropEvent(event) {
    console.log("drop");
    event.preventDefault();
  }

}

thanks by advance

I use another method that isn't clean but that work well, I'm always listening if someone can solve my problem.

loadDragNDropEvents() {

  this.unloadDragNDropEvents(); // Unload drag and drop events before adding new ones

  const repertory = document.getElementById("Repertory");
  if (repertory == undefined) { return this; }
        
  const cards = repertory.querySelectorAll(".Card"); 
  if (cards.length <= 0) { return this; }

  console.log("loadDragNDropEvents");

  cards.forEach(card => {
    card.addEventListener("dragstart", this.#CardDragStartEvent.bind(this), false);
    card.addEventListener("dragend", this.#CardDragEndEvent.bind(this), false);
  });
}

// Now clone and replace the DOM élément to clea
unloadDragNDropEvents() {

  console.log("unloadDragNDrop");

  let oldRep = document.getElementById("Repertory");
  let newRep = oldRep.cloneNode(true);
  oldRep.parrentNode.replaceChild(newRep, oldRep);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM