Register listeners in javascript classes

1

I'm trying to create a javascript class for a droparea, I tried two different ways. Droparea class allows me to access the properties of the object but when the drop event occurs, e.preventDefault does not work. The class Droparea2 allows to avoid the default behavior of the drop event, but it does not allow me to access the properties of the object, Any solution ?. I prefer not to use any plugin.

class Droparea {
	// Contructor
	constructor(div, property1){
		this.div = div;
		this.property1 = property1;
	}

	// Metodos 
	registerEvents(){
		this.in();
		this.out();
		this.drop();
		return;
	}

	in(){
		var div = this.div;
    var property1 = this.property1;
		div.addEventListener('dragover',function(){
			div.style.background = "yellow";
      div.innerHTML = property1 + '1';
		},false);
	}

	out(){
		var div = this.div;
    var property1 = this.property1;
		div.addEventListener('dragleave',function(e){
			e.stopPropagation();
			e.preventDefault();
			div.style.background = "blue";
      div.innerHTML = property1 + '2';
		},false);
	}

	drop(){
		var div = this.div;
    var property1 = this.property1;
		div.addEventListener('drop',function(e){
			e.stopPropagation();
			e.preventDefault();
			div.style.background = "red";
      div.innerHTML = property1 + '3';
		},false);
	}
}

class Droparea2 {
	// Contructor
	constructor(div, property1){
		this.div = div;
		this.property1 = property1;
	}

	// Metodos 
	registerEvents(){
    this.div.addEventListener('dragover',this.in,false);
    this.div.addEventListener('dragleave',this.out,false);
    this.div.addEventListener('drop',this.drop,false);
	}

	in(e){
    e.stopPropagation();
    e.preventDefault();
    e.target.style.background = 'yellow';
	}

	out(e){
    e.stopPropagation();
    e.preventDefault();
    e.target.style.background = 'blue';
    e.target.innerHTML = this.property1;
	}

	drop(e){
    e.stopPropagation();
    e.preventDefault();
    e.target.style.background = 'red';
	}
}
var div = document.querySelector('.droparea');
var drop = new Droparea(div,'Something');
var div2 = document.querySelector('.droparea2');
var drop2 = new Droparea2(div2,'Something');
drop.registerEvents();
drop2.registerEvents();
.droparea {
  background: gray;
  height: 200px;
}

.droparea2 {
  background: darkgray;
  height: 200px;
}
<div class="droparea">Arrastra tu elemento aqui. 1</div>
<div class="droparea2">Arrastra tu elemento aqui. 2</div>
    
asked by Edwin V 16.02.2017 в 20:06
source

1 answer

2

If you register the listeners, the problem is that you forgot to prevent the default action in the event dragover :

div.addEventListener('dragover', function(e) {
  e.preventDefault(); // omitiste aquí
  div.style.background = "yellow";
  div.innerHTML = property1 + '1';
});

Remember to prevent events at events dragover , dragleave and drop if you want to customize behaviors. Also, in case you want to use a dataTransfer you can simulate one with an instance object, since the original object dataTransfer is only available in dragstart and drop . Here is an example of this.

Example DnD and File API

class AvatarUpload {
	constructor(id, data) {
  	this.$el = document.getElementById(id);
    this.data = data;
    // simula el dataTransfer nativo
    this.dataTransfer = {};
    this.bindEvents();
  }
  
  bindEvents () {
  	this.$el.addEventListener('dragover', this.over.bind(this));
    this.$el.addEventListener('dragleave', this.leave.bind(this));
    this.$el.addEventListener('drop', this.drop.bind(this));
  }
  
  over (e) {
  	e.preventDefault();
    this.dataTransfer.name = 'John Doe';
    this.$el.classList.add('over');
  }
  
  leave (e) {
  	e.preventDefault();
    this.$el.classList.remove('over');
  }
  
  drop (e) {
  	e.preventDefault();
    this.$el.classList.remove('over');
    this.toBase64(e).then(str => {
      this.$el.textContent = '';
    	this.$el.style.backgroundImage = 'url(${str})';
      console.log('Propiedades propias:', this.data);
      console.log('DataTransfer:', this.dataTransfer);
      this.dataTransfer = {}; // reinicializa dataTransfer
    });
  }
  
  toBase64(e) {
  	return new Promise(resolve => {
    	let fileReader = new FileReader();
      let file = e.dataTransfer.files[0];
      fileReader.onload = function () {
      	resolve(this.result);
      }
      fileReader.readAsDataURL(file);
    });
  }
}

new AvatarUpload('area', { property: 'Photo' });
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans');

#area {
  background-size: cover;
  border: 3px dashed #ccc;
  border-radius: 4px;
  color: #555;
  font-family: 'josefin sans';
  font-size: 22px;
  height: 200px;
  line-height: 200px;
  margin: 20px auto;
  text-align: center;
  width: 200px;
}

#area.over {
  border-color: #f39c12;
}
<div id="area">
  Arrastra tu foto aquí
</div>
    
answered by 16.02.2017 / 21:25
source