I know how to create dynamic elements and append them to existing ones, and how to create click events and attach them. See my snippet below
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>
I am trying to mimic jQuery's .click()
behavior. (I don't want to use jQuery, I just need a shorter way of assigning click events to dynamically created elements).
What I mean, is I would like to extend Object.prototype
by adding a function that accepts a function as the parameter, and all it does behind the scenes is assign it to the object's .onclick
property.
However, the code runs, but no click event is triggered, and no error is reported.
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>
I can tell that my extension of Object.prototype.click
has not been executed since the console.log()
never happens.
Is it because Object.prototype.click
is reserved? If so, why am I not being able to override its definition?
What am I doing wrong?
There are two issues. First, you should assign to the prototype before you try calling btn1.click()
, else the native .click()
will be called. (The native .click()
method of an element programatically triggers a click event on that element.)
The other problem is that btn1
is an element, not just an object, and HTMLElement
s have a click
property on their prototype. So, even if you assign to Object.prototype.click
, HTMLElement.prototype.click
will be seen sooner in the prototype chain, and so your Object.prototype.click
will be ignored. You'll have to either overwrite HTMLElement.prototype.click
or 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>
But mutating the built-in objects like this isn't very good practice and can lead to things breaking (such as if a library assumes that .click()
will trigger the normal HTMLElement.prototype.click
function) - you might consider assigning click
property directly to the instance, rather than to the 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With