Call class function with addEventListener - javascript

I want to access the doSomething function when the button that the render function creates is clicked? I get the following error instead.
Uncaught ReferenceError: getMethod is not defined
main.js
class Div {
constructor(div){
this.div = div;
}
init(){
this.getMethod();
}
getMethod(){
var div = this.div;
var createButton = {
render: function(){
let button = `
<button
onclick="getMethod.doSomething(this)"
type="button">
Click Me!
</button>
`;
div.innerHTML = button;
},
doSomething: function(){
// do something
}
}
createButton.render();
}
}
const div = new Div(document.querySelector('div'));
div.init();

There are multiple problems with your code.
Event handlers in html attributes (e.g.onclick) get run in global scope, yet getMethod is defined in a local scope, the scope of your class.
getMethod does not have a property doSomething, I think you meant to write createButton.doSomething
To fix the first issue you have to define your button as an object, not just as text. Since text doesn't know anything about scope. Then you can addEventListener to add a handler for the click event. In the handler callback function's you will have access to all variables in your local scope (the scope of the getMethod function)
class Div {
constructor(div){
this.div = div;
}
init(){
this.getMethod();
}
getMethod(){
var div = this.div;
var createButton = {
render: function(){
const button = document.createElement('button');
button.type = "button";
button.textContent = "Click Me!";
button.addEventListener('click', () => {
createButton.doSomething(this)
})
//clear inner html / delete all children
div.innerHTML = '';
div.appendChild(button);
},
doSomething: function(){
console.log("do something");
}
}
createButton.render();
}
}
const divElem = document.getElementById("mydiv");
const div = new Div(divElem);
div.init();
<div id="mydiv"></div>

Related

TamperMonkey EventListener on button not working

I created this snippet:
function addClick(button, container) {
console.log("In add click");
const data = container.nextElementSibling.childNodes[0].innerHTML;
button.addEventListener('click', ()=>{
alert('clicked')
console.log("Clicked");
})
}
function createCopyButtons(array){
array.forEach(element => {
const container = document.createElement('div');
const button = document.createElement('button');
button.innerHTML = "Copy"
styleContainer(container);
styleButton(button, element);
stylePrevious(element);
container.innerHTML = element.outerHTML + button.outerHTML;
element.parentNode.replaceChild(container, element);
addClick(button, container);
});
}
Now in here the array is the array of DOM elements I want this property to apply and I call the createCopyButtons() function down with some more stuff. Now the thing is that this event listener does not apply or does not work. I tried to wait till the document is loaded by these answers and only then apply my javascript snippet but the event listener doesn't seems to work.
document.addEventListener("DOMContentLoaded", function(event) {
//do work
});
if (document.readyState == "complete") {
// document is ready. Do your stuff here
}
Please help.
update:
function addClick(button) {
button.addEventListener('click', ()=>{
console.log("Clicked");
})
}
let p = document.querySelectorAll('p');
// innerHTML not work
let btn1 = document.createElement('button');
btn1.innerHTML = "Not work";
p[0].innerHTML = btn1.outerHTML;
addClick(btn1)
// work
let btn2 = document.createElement('button');
btn2.innerHTML = "work";
p[1].appendChild(btn2);
addClick(btn2)
<p></p>
<p></p>
because you append the button to the container using string (.innerHTML) not DOM or using appendChild()
container.innerHTML = element.outerHTML + button.outerHTML
the following function will not apply the event
addClick(button, container);
I don't know why you need to wrap target element and the button inside div, why not just append the button after target element using or insertBefore() or insertAdjacentHTML() but below is working code that follow yours.
it find the button inside the container for using as addClick() parameters
function addClick(button, container) {
console.log("In add click");
const data = container.nextElementSibling.childNodes[0].innerHTML;
button.addEventListener('click', () => {
alert('clicked')
console.log("Clicked");
})
}
function createCopyButtons(array) {
array.forEach(element => {
const container = document.createElement('div');
let button = document.createElement('button');
button.innerHTML = "Copy"
container.innerHTML = element.outerHTML + button.outerHTML;
element.parentNode.replaceChild(container, element);
let btn = container.querySelector('button'); // <== find the button
addClick(btn, btn.parentNode);
});
}
createCopyButtons(document.querySelectorAll('input'))
<div>
<input type="text">
<p><span>test</span></p>
</div>

How to add event listener with function callback in html inside a class?

Imagine having a class that generates content on the page. Part of the content should have event listener attached in html such as onclick=function().
How can I make sure to call the function from within the class that constructed the html?
class Container {
constructor(hook) {
this.hook = "#" + hook;
this.addDiv = this.addDiv.bind(this);
this.fireMe = this.fireMe.bind(this);
this.init = this.init.bind(this);
this.init();
}
addDiv() {
const div = `<div onclick="fireMe()">FIRE ME</div>`;
document.querySelector(this.hook).innerHTML = div;
}
fireMe() {
console.log("hello!");
}
init() {
this.addDiv();
}
}
let div = new Container("app");
now getting error that fireMe is undefined (which is right because it is not available in global scope).
I know I can add event listener by rendering the div first and than adding the event listener, but is there a way of adding event listener from within <div> tag to actually reach Container.fireMe() method?
You have to create the element -> something like this
class Container {
constructor (hook) {
this.hook = '#' + hook;
this.addDiv = this.addDiv.bind(this);
this.fireMe = this.fireMe.bind(this);
this.init = this.init.bind(this);
this.init();
}
addDiv () {
const div = document.createElement('div');
div.textContent = 'FIRE ME';
div.addEventListener('click', this.fireMe );
document.querySelector(this.hook).innerHTML = div;
}
fireMe () {
console.log('hello!');
}
init () {
this.addDiv();
}
}
const div = new Container('app');
Never use inline event handlers as there are many reasons to avoid this 20+ year old technique that just will not die.
Instead, use modern, standards-based code with .addEventListener(). If you do this along with making the new HTML using the DOM API, you'll be able to more easily accomplish your goal:
addDiv() {
const div = document.createElement("div");
div.textConent = "FIRE ME";
div.addEventListener("click", this.fireMe);
document.querySelector(this.hook).innerHTML = div;
}
You should create elements use document.createElement() rather than using string
class Container {
constructor(hook) {
this.hook = "#" + hook;
this.addDiv = this.addDiv.bind(this);
this.fireMe = this.fireMe.bind(this);
this.init = this.init.bind(this);
this.init();
}
addDiv(){
const div = document.createElement('div');
div.innerHTML = "Fire Me";
div.addEventListener("click",this.fireMe);
document.querySelector(this.hook).appendChild(div);
}
fireMe() {
console.log("hello!");
}
init() {
this.addDiv();
}
}
let div = new Container("app");

How do I add a button to a div class on load from Javascript? [duplicate]

This question already has answers here:
How to add onload event to a div element
(26 answers)
Closed 5 years ago.
For an assignment, I cannot touch the HTML code and am editing an external JS file. I have to refer the code to an existing class and turn that into a button to run a script.
The has to be ran on load to transform an element with a given id into a button that can also run a function on click.
So let's say the we have id="bar",
how do I go about it?
My code doesn't work at all.
document.getElementById("bar").onload = function () { myFunction() };
function myFunction() {
document.getElementById("bar").innerHTML = "<button></button>";
}
Why don't you just execute your script as the DOM is ready? To do so,
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("bar").innerHTML = "<button></button>";
}, false);
You just need a createElement function.
This works:
document.addEventListener("DOMContentLoaded", function(){
var button = document.createElement("button");
button.innerHTML = "This is a button";
// assuming the Div's ID is bar
var div = document.getElementById('bar');
div.appendChild(button);
//the following function will alert a window when the button is clicked
button.addEventListener ("click", function() {
alert("Button was clicked");
});
});
Updated Codepen
I think this is bit tha you needed
var bar = document.getElementById('bar');
window.onload = function() {
var barInner = bar.innerHTML;
bar.innerHTML = '<button>' + barInner + '</button>';
}
bar.onclick = function() {
alert("Hello\nHow are you?");
};
document.getElementById("bar").onload = myFunction();
function myFunction() {
document.getElementById("bar").innerHTML = "<button>Button</button>";
}
There you go!
Not every single HTML element has a load event.
Only some of them are concerned, such as the window, an image... etc
Have a look here on MDN to learn more about this.
Here is a simple snippet resolving all what you mentioned.
window.addEventListener("load", () => {
// you can put your entire script in here.
var elt = document.getElementById("bar"),
button = document.createElement("button");
button.textContent = elt.textContent;
button.onclick = callback;
elt.textContent = '';
elt.appendChild(button);
function callback() {
console.log("The button has been clicked");
}
});
<div id="bar" style="background: beige; height: 2em">Click me</div>
In the previous snippet, I am appending the button in the element. But if the matter is really to transform it into a button, there we go:
window.addEventListener("load", () => {
// you can put your entire script in here.
var elt = document.getElementById("bar"),
container = elt.parentNode,
button = document.createElement("button");
button.id = elt.id; // if you want to keep the id
button.textContent = elt.textContent;
button.onclick = callback;
container.removeChild(elt);
container.appendChild(button);
function callback() {
console.log("The button has been clicked");
}
});
<div style="background: #fee; height: 2em">
<div id="bar" style="background: beige; height: 2em">Click me</div>
</div>

Creating two elements using js and then having access to them later in another function

I am building some js functionality where I will be creating 2 elements on a page
var createBtn = function(
var btn = document.createElement('button')
...
)
var createIframe = function(
var iframe = document.createElement('iframe')
...
)
Pretty basic stuff, but later on I want to add an event listener to the button that will apply a style attribute to the iframe.
Something like:
var displayIframe = function(
Iframe.style['display'] = 'block'
)
button.addEventListener('click', displayIframe)
My question is how can I access the elements after I have created them without going through the annoyance of attaching classes to them and accessing them all over again that way. Is there someway of getting access to them in the create functions from the beginning.
Your codes is almost correct, but some changes is needed
var btn, iframe;
var createBtn = function () {
btn = document.createElement('button');
...
}
var createIframe = function () {
iframe = document.createElement('iframe');
...
}
Callback function
var displayIframe = function(){
iframe.style['display'] = 'block'
}
Attach click listener
btn.addEventListener('click', displayIframe);
Your mistakes:
you should declare btn and iframe as global variables to be accessible to other functions
function starts with { and ends with } not (, )
so far your codes is correct, without any error, but you won't see anything on the page because you have not attached your newly created elements to the body, For accomplish this try this function
function attachToBody(){
document.body.appendChild(btn);
document.body.appendChild(iframe);
}
In your example, I dont know why you use functions to create element, but you must have your point. Try this and let me know does this work for you.
//this is equivalent to: var btn = document.createElement('button');
var btn = (function(){
var btn = document.createElement('button');
return btn;
})();
var iframe = (function{
var iframe = document.createElement('iframe');
return iframe;
})();
document.getElementById("parentId").appendChild(btn);
document.getElementById("parentId").appendChild(iframe);
btn.addEventListener('click', function(){
iframe.style.display = "none";
});
var createBtn = function() {
var btn = document.createElement('button')
btn.setAttribute("id", "myButton");
return btn;
}
var createIframe = function() {
var iframe = document.createElement('iframe')
iframe.setAttribute("id", "myFrame");
return iframe;
}
document.body.appendChild(createBtn()); // Append button to body.
document.body.appendChild(createIframe()); // Append iFrame to body.
// Get Elements by Id.
var myButton = document.getElementById("myButton");
var myFrame = document.getElementById("myFrame");
// Add event listener.
myButton.addEventListener("click", function() {
myFrame.style.display = "none", false);
}

adding click event in newly created div in javascript

I am creating a new div on a click of button and inside that onclick function I am adding a click event to newly created div but its not working.
document.getElementById('blah').onclick = function(){
var innerDiv = document.createElement("div");
document.getElementById('container').appendChild(innerDiv);
innerDiv.onclick =createWorkFunction;
}
function createWorkFunction(e){
alert();
}
can anybody quickly help me
Your code is corrct, But you did not set the text of the your div (an empty div can not be clicked by an user), Try this:
document.getElementById('blah').onclick = function(){
var innerDiv = document.createElement("div");
innerDiv.innerHTML = 'This is a div'; // set it's text
document.getElementById('container').appendChild(innerDiv);
innerDiv.onclick = createWorkFunction;
}
function createWorkFunction(e){
alert('this is some text');
}
Also it's better to use addEventListener
(function() {
var oBlah = document.getElementById('blah');
oBlah.addEventListener('click', function() {
var innerDiv = document.createElement("div");
document.getElementById('container').appendChild(innerDiv);
}, false);
innerDiv.addEventListener('click', function() {
alert();
}, false);
})();
This should help.
try this:
innerDiv.setAttribute("onclick","createWorkFunction()")
function createWorkFunction(){
alert("working");
}

Categories