I am trying to modify a plug-in (Pikaday) and add my own little bit of functionality.
The plugin is built using the proto-type system, and I have added my funciton within it.
Pikaday.prototype = {
//OTHER PARTS OF PLUGIN
showYearPicker: function()
{
document.getElementsByClassName('pika-year-label').onclick=function(){
console.log("asfd");
}
},
//OTHER PARTS OF PLUGIN
}
return Pikaday;
What I am having trouble understanding is how to actually trigger this method. Clicking the specified element doesnt work.
Would anyone know how I can include this function as part of the plugin?
Full code (minus my addition) is here if anyone is interested.
Defining a method on the prototype of a function in simple terms means you've defined a method on an object that will be one link up the prototype chain from all instances of this function.
You can think of it as a common "parent" or "object-above" for every instance of that function.
Therefore, to use your method, you must instantiate the plugin and call your function on it.
function Pikaday() {}
Pikaday.prototype = {
showYearPicker: function() {
console.log('called');
}
}
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype
What this will do is check if pikaday
has showYearPicker
defined on it, and since it doesn't, it will go up the proto chain and check if that object has it, which it does.
In other words, this is essentially what the JS engine does behind the scenes:
let pikaday = new Pikaday();
pikaday.__proto__.showYearPicker();
Note that proto here is just for demonstration, its only recently been standardized in ES6 for legacy purposes, but this behavior should be left to the JS engine (The spec calls this proto link [[Prototype]]
).
If needed, the proper way to access the prototype is to use Object.getPrototypeOf (in +ES6 you could use the semantically-clearer Reflect.getPrototypeOf)
function Pikaday() {}
console.log(
Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
console.log(
Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
One problem with your code is that getElementsByClassName will return a NodeList (not an array) of nodes that have this class.
This means you must either loop over this list and attach a handler to each element,
let nodes = document.getElementsByClassName('pika-year-label');
Array.from(nodes) // convert NodeList to an array so we can use forEach
.forEach(node => {
// attach a handler on each node
node.onclick = function (){
console.log("asfd");
}
});
// Side Note: You can also use array spread to convert the node list to an array
// [...nodes].forEach( ... )
or alternatively attach a handler to a common parent for all the elements to delegate the behavior.
document.body.onclick = function(e) {
if (e.target.classList.contains('pika-year-label')) {
console.log("asfd");
}
}
Finally, if you only want to add this function to an existing function's prototype, one way to do it is to simply define it as a method on that prototype:
function Pikaday() {}
// define a method on the existing prototype
Pikaday.prototype.showYearPicker = function() {
console.log('called');
};
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype