我知道如何创建动态元素并将它们附加到现有元素,以及如何创建点击事件并附加它们。请参阅下面的代码段
var container = document.getElementById("container");
var btn1 = document.createElement("button");
var btn2 = document.createElement("button");
btn1.innerHTML = "button 1";
btn2.innerHTML = "button 2";
btn1.onclick = function(){ console.log('button 1 clicked'); }; // this works fine
btn2.onclick = function(){ console.log('button 2 clicked'); };
container.append(btn1);
container.append(btn2);
<div id="container"></div>
我正在尝试模仿 jQuery 的 .click()
行为。 (我不想使用 jQuery,我只需要一种更短的方法来将点击事件分配给动态创建的元素)。
我的意思是,我想通过添加一个接受函数作为参数的函数来扩展 Object.prototype
,它在幕后所做的就是将它分配给对象的 .onclick
属性。
但是,代码运行起来,却没有触发点击事件,也没有报错。
var container = document.getElementById("container");
var btn1 = document.createElement("button");
var btn2 = document.createElement("button");
btn1.click(function(){ console.log('button 1 clicked'); }); // this doesn't work
btn2.click(function(){ console.log('button 2 clicked'); }); // this doesn't work
btn1.innerHTML = "button 1";
btn2.innerHTML = "button 2";
container.append(btn1);
container.append(btn2);
Object.prototype.click = function(fn) {
console.log('this function never gets executed');
this.onclick = fn;
}
<div id="container"></div>
我可以看出我的 Object.prototype.click
扩展还没有执行,因为 console.log()
从未发生过。
是不是因为Object.prototype.click
被保留了?如果是这样,为什么我不能覆盖它的定义?
我做错了什么?
最佳答案
有两个问题。首先,您应该在 尝试调用 btn1.click()
之前分配给原型(prototype),否则 native .click()
将被调用。 (元素的 native .click()
方法以编程方式触发该元素上的点击事件。)
另一个问题是btn1
是一个元素,而不仅仅是一个对象,HTMLElement
有一个click
原型(prototype)上的属性。因此,即使您分配给 Object.prototype.click
,HTMLElement.prototype.click
也会更快地出现在原型(prototype)链中,因此您的 Object.prototype .click
将被忽略。您必须覆盖 HTMLElement.prototype.click
或 HTMLButtonElement.click
:
var container = document.getElementById("container");
var btn1 = document.createElement("button");
var btn2 = document.createElement("button");
HTMLElement.prototype.click = function(fn) {
console.log('setting up click event');
this.onclick = fn;
}
btn1.click(function(){ console.log('button 1 clicked'); });
btn2.click(function(){ console.log('button 2 clicked'); });
btn1.innerHTML = "button 1";
btn2.innerHTML = "button 2";
container.append(btn1);
container.append(btn2);
<div id="container"></div>
但像这样改变内置对象并不是很好的做法,并且会导致事情中断(例如,如果库假设 .click()
将触发正常的 HTMLElement.prototype.click
函数)——您可以考虑将 click
属性直接分配给实例,而不是分配给原型(prototype):
var container = document.getElementById("container");
function myCreateElement(type) {
const elm = document.createElement(type);
elm.click = function(fn) {
console.log('setting up click event');
this.onclick = fn;
}
return elm;
}
var btn1 = myCreateElement("button");
var btn2 = myCreateElement("button");
btn1.click(function(){ console.log('button 1 clicked'); });
btn2.click(function(){ console.log('button 2 clicked'); });
btn1.innerHTML = "button 1";
btn2.innerHTML = "button 2";
container.append(btn1);
container.append(btn2);
<div id="container"></div>
关于javascript - 为什么我不能为 Object.prototype.click 分配一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53902365/