I'm making a monopoly game for my website, and I have a problem that I can't add event listeners for "i" element in a custom element
Here's my custom element:
class Popup extends HTMLElement {
constructor() {
super();
var that = this;
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('div');
wrapper.setAttribute("class","popup-wrapper");
var popup = document.createElement('div');
popup.setAttribute('class','popup');
let exitButton = document.createElement('i');
exitButton.className = "fas fa-times fa-lg exit";
exitButton.addEventListener("click", function () {
console.log('a');
});
// styles
var style = document.createElement('style');
style.textContent = `
@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css");
@import url("https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css");
.popup-wrapper {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background-color: rgba(0, 0, 0, .6);
z-index: 9999;
visibility: visible;
}
.popup {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #d6d6d6;
background-color: #fff;
border-radius: .25rem;
padding: 1rem 2rem;
}
/* .exit {
position: absolute;
top: .5rem; right: .5rem;
cursor: pointer;
} */
`;
popup.appendChild(exitButton);
wrapper.appendChild(popup);
shadow.appendChild(style);
shadow.appendChild(wrapper);
this.isOpen = false;
this.popup_wrapper = wrapper;
this.popup = popup;
this.exitButton = exitButton;
}
close() {
console.log('a');
this.remove();
}
}
class TextPopup extends Popup {
constructor() {
super();
}
show() {
this.exitButton.addEventListener("click", function () {
console.log('a');
});
this.heading = this.getAttribute("heading");
this.text = this.getAttribute("text");
this.popup.innerHTML += `
<h1>${this.heading}</h1>
<p>${this.text}</p>
`;
}
}
customElements.define('text-popup', TextPopup);
I had tried to place it in multiple locations but it is still not working
I also have another custom element where addEventListener working:
class Copy extends HTMLElement {
constructor() {
super();
if (!this.hasAttribute('text')) return console.error("Text is not specified");
this.text = this.getAttribute('text');
this.style.cursor = "pointer";
var that = this;
this.addEvents(["click", "touchend"], () => {
that.copy(that.text)
});
}
copy(text) {
navigator.clipboard.writeText(text).then(function() {
// successfull
}, function(err) {
// unsuccessfull
});
}
}
customElements.define('copy-button', Copy);
PS: addEvents prototype:
Element.prototype.addEvents = Document.prototype.addEvents = Window.prototype.addEvents = function (events, callback) {
for (var i = 0; i < events.length; i++) this.addEventListener(events[i], callback);
};
I'm on the last version of chrome
So thanks to @Jared Smith and @Ken yo, I have this solution:
I have found that there is path
, which is an array with all of the path of the click
class TextPopup extends Popup {
constructor() {
super();
}
connectedCallback() {
document.body.addEventListener("click", function (e) {
if (e.path[0].classList.contains("exit")) {
console.log("exitButton was clicked!");
}
});
}
show() {
this.heading = this.getAttribute("heading");
this.text = this.getAttribute("text");
this.popup.innerHTML += `
<h1>${this.heading}</h1>
<p>${this.text}</p>
`;
}
}