Let's say I have some code like this:
let myList = new map();
let something = new objectMaker();
object.set(someIndex,new objectMaker());
function objectMaker(){
this.parentThing=new createElement("div");
this.childThing=new createElement("div");
this.parentThing.onclick=clickyFunction();
//See below for details of function call
this.parentThing.id=someIndex "something";
}
Now, the problem is finding the object which owns the element when I call "clickyFunction()." My current solution looks something like: this.parentThing.onclick=function(){clickElement(event,this);};
If someone clicks childThing e.srcElement
will reference childThing and the this
parameter will refer to this.parentThing
.
Thus, then I have to run a loop
function clickyFunction(e,callingObject) {
for (let key of myList.keys()) {
if (myList.get(key).parentThing.id==callingObject.id){
//This is the parent
...
Is there a way to just pass the instance of objectMaker
to clickyFunction()
(regardless of which)? It seems like this would be a more elegant solution. Or, should I make some overall change to how the program is organized?
CodePudding user response:
You can use the 'bind' method to create a new function with the desired 'this' value and pass the instance of objectMaker
to the clickyFunction
.
For example, you can modify the line where you set the onclick
handler like this:
this.parentThing.onclick = clickyFunction.bind(this);
By doing this, you're creating a new function that will call clickyFunction
with the current instance of objectMaker
set as the this
value. Then, when you use the this
keyword in clickyFunction
, you can access the instance of objectMaker
directly:
function clickyFunction(e) {
// `this` refers to the instance of objectMaker
...
}
As an alternative, you could pass the instance of objectMaker
to the clickyFunction
as an argument, like this::
this.parentThing.onclick = function(e) {
clickyFunction(e, this);
}
function clickyFunction(e, objectMakerInstance) {
// `objectMakerInstance` refers to the instance of objectMaker
...
}
Either way, you can skip the loop and access the desired instance of objectMaker
directly.
*EDIT:
You can find the object that owns an HTML element in JavaScript using the ownerDocument
property of the element. This'll give you the Document
object that owns the element. Then, you can use the defaultView
property of the document to get the Window
object that owns the document, like:
let element = document.getElementById('my-element');
let ownerWindow = element.ownerDocument.defaultView;
Alternatively, you can use the parentNode
property to navigate up the DOM tree and find the nearest ancestor element that has an ownerDocument
property.
You can do this like this:
let element = document.getElementById('my-element');
let ancestor = element;
while (ancestor && !ancestor.ownerDocument) {
ancestor = ancestor.parentNode;
}
let ownerWindow = ancestor.ownerDocument.defaultView;
This can be handy if the element isn't directly owned by a document, but is instead owned by an element that is itself owned by a document, like a template
element or a svg
element.