我正在尝试修改插件(Pikaday)并添加我自己的一些功能。
该插件是使用原型系统构建的,我在其中添加了我的功能。
Pikaday.prototype = {
//OTHER PARTS OF PLUGIN
showYearPicker: function()
{
document.getElementsByClassName('pika-year-label').onclick=function(){
console.log("asfd");
}
},
//OTHER PARTS OF PLUGIN
}
return Pikaday;
我无法理解的是如何实际触发此方法。单击指定的元素不起作用。
有谁知道如何将此功能作为插件的一部分包含在内?
如果有人有兴趣的话,Full code(减去我的补充)就在这里。
答案 0 :(得分:3)
用简单的术语在函数原型上定义一个方法意味着你已经在一个对象上定义了一个方法,该方法将是来自该函数的所有实例的原型链的一个链接。
您可以将其视为该函数的每个实例的常见“父”或“对象 - 上”。
因此,要使用您的方法,您必须实例化插件并在其上调用您的函数。
function Pikaday() {}
Pikaday.prototype = {
showYearPicker: function() {
console.log('called');
}
}
let pikaday = new Pikaday();
pikaday.showYearPicker(); // <-- call the function on the prototype
这将检查pikaday
是否已定义showYearPicker
,并且由于它没有,它会上升到proto链并检查该对象是否具有它,它是。
换句话说,这基本上就是JS引擎在幕后所做的事情:
let pikaday = new Pikaday();
pikaday.__proto__.showYearPicker();
请注意,此处proto仅用于演示,它最近才在ES6中标准化以用于遗留目的,但此行为应留给JS引擎(spec调用此proto链接{{ 1}})。
如果需要,访问原型的正确方法是使用Object.getPrototypeOf(在+ ES6中,您可以使用语义更清晰的Reflect.getPrototypeOf)
[[Prototype]]
您的代码存在的一个问题是,getElementsByClassName将返回具有此类的节点的NodeList(不是数组)。
这意味着您必须遍历此列表并为每个元素附加处理程序
function Pikaday() {}
console.log(
Object.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
console.log(
Reflect.getPrototypeOf(new Pikaday()) === Pikaday.prototype
);
或者将处理程序附加到公共父级,以便所有元素委派行为。
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( ... )
最后,如果您只想将此函数添加到现有函数的原型中,一种方法是将其定义为该原型上的方法:
document.body.onclick = function(e) {
if (e.target.classList.contains('pika-year-label')) {
console.log("asfd");
}
}