我知道如何创建动态元素并将其添加到现有元素,以及如何创建点击事件并将其附加。请在下面查看我的代码段
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
属性。
但是,代码会运行,但是不会触发click事件,并且不会报告任何错误。
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
被保留了吗?如果是这样,为什么我不能覆盖其定义?
我在做什么错了?
答案 0 :(得分:12)
有两个问题。首先,应在尝试调用btn1.click()
之前将 分配给原型,否则将调用 native .click()
。 (元素的本机.click()
方法以编程方式触发该元素的click事件。)
另一个问题是btn1
是一个元素,而不仅仅是一个对象,并且HTMLElement
的原型具有click
属性。因此,即使您分配给Object.prototype.click
,也将在原型链中更快地看到HTMLElement.prototype.click
,因此您的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
属性分配给实例,而不是原型:
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>