I have the following:
Element.prototype.makeDraggable = (elem = null) => {
//this.draggable = true;
this.setAttribute("draggable", "true");
this.ondragstart = (e) => { e.dataTransfer.setData("text", elem ? elem.id : e.target.id); }
};
When the browser gets to that function it throws an error on the first line:
Drag.js:7 Uncaught TypeError: n.setAttribute is not a function
Where n
is the minified name of the element, or so I thought.
as you can see in the picture, this
seems to be an Element
, but n
is.. well I don't know what it is. Am I doing it wrong?
At this same point, if I do this.draggable = true
in the console it works just fine... You can also see that I tried doing it in the code but that doesn't work either.
Any ideas?
The this
you see in the debugger is the actual this
value; the this
you see in the source view is the source-mapped version of n
, and the value of n
isn’t what you want it to be.
You used an arrow function, so you got lexical this
. That’s what arrow functions do. To access the this
from call time (what’s generally intended when adding methods to a prototype), use a non-arrow function:
Element.prototype.makeDraggable = function (elem = null) {
//this.draggable = true;
this.setAttribute("draggable", "true");
this.ondragstart = (e) => { e.dataTransfer.setData("text", elem ? elem.id : e.target.id); }
};
See also Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?.
Finally, extending the prototypes you have some of the least control over – browser built-ins – is considered a bad idea. (You could produce a conflict with future extensions to the spec, for example – or with other libraries you use.) A standalone function usually works better:
const makeDraggable = (target, elem = null) {
target.draggable = true;
target.ondragstart = (e) => { e.dataTransfer.setData("text", elem ? elem.id : e.target.id); }
};