Javascript. Pressing button - call function - javascript

function greet () {
console.log ("Hi there!");
}
function addButton () {
document.createElement("[wanted_HTML_tag_here]");
}
There is separate HTML document. It has a button that calls the function addButton() upon being pressed. Said function has to create a new element and append it to the element. Pressing this new button has to call the function greet().
I try with [element_name].setAttribute("[attribute]", "[attribute_value]") but useless
Also trying document.[element_to_append_into].appendChild([element_being_added]); but same

Here's a complete working example (it is one way of doing it):
<html lang="en">
<body>
<button id="btn">Create Button</button>
</body>
<script>
function greet() {
console.log('Hi there')
}
function addButton() {
const button = document.createElement('button')
const buttonTextNode = document.createTextNode('Click')
button.appendChild(buttonTextNode)
button.onclick = greet
document.body.appendChild(button)
}
// get the button that creates other buttons
const buttonCreator = document.getElementById('btn')
buttonCreator.onclick = addButton
</script>
</html>

Related

Vanilla Javascript how override added function on event listener?

I have a bootstrap modal that has some custom events, like hidden.bs.modal, depending on where the user does, I want the function in this event to be replaced, maybe it's better to understand with a simple example, consider:
const currentModal; // imagine an any modal here.
window.addEventListener('load', () => {
currentModal.addEventListener('hidden.bs.modal', standardFunction );
});
function standardFunction(){
alert('hi there');
// this is standard output to modal closed
}
function buttonClickedChange(){
// Here, i need override standardFunction
this.standardFunction = function(){
alert('modal event hidden.bs.modal changed with success!');
// this must be override previous output
};
}
What happens is that regardless of the redeclaration of the function, the output for the method is still standard, this is because the eventlistener does not refer to the stored function but only "copy" its content and creates its scope only inside.
The problem you have is when you bind the event, you are referencing that function. When you replace it does not update the reference to that function. You can clearly see that this will not work with the example
var btn = document.querySelector("button");
function myFunc () {
console.log(1);
}
btn.addEventListener("click", myFunc);
myFunc = function() {
console.log(2);
}
<button>Click Will Show 1</button>
Just remove the event listener and bind a new event.
currentModal.removeEventListener('hidden.bs.modal', standardFunction );
currentModal.addEventListener('hidden.bs.modal', myUpdatedFunction );
function myFunc () {
console.log(1);
}
var btn = document.querySelector("button");
btn.addEventListener("click", myFunc);
function myFunc2() {
console.log(2);
}
btn.removeEventListener("click", myFunc);
btn.addEventListener("click", myFunc2);
<button>Click</button>
If for some reason you can not remove the event, the only way around it would not to bind directly to the function, but to have another function call that function.
var btn = document.querySelector("button");
var myFunc = function() {
console.log(1);
}
function clickFunction () {
myFunc();
}
btn.addEventListener("click", clickFunction);
myFunc = function() {
console.log(2);
}
<button>Click</button>
Or how most people would do it is to add the logic into the function on what to do
var btn = document.querySelector("button");
var state = 0;
var myFunc = function() {
if (state===0) {
console.log(1);
} else {
console.log(2);
}
}
state = 1;
btn.addEventListener("click", myFunc);
<button>Click</button>
You used function expressin instead of function declaration. When you use function yourFunction it is moved to the top with all of the other declared functions. When you use var yourFunction = function () it is right there where you declared it. This means that hidden.bs.modal is searching for the top most function with that name which in this case is the first one you declared or the standard one. One of the ways is that you can declare your function in the global scope: function standardFunctionOverride() and add that to the listener.

Button Doesn't Work If Created Using innerHTML

I have this kind of structure
<button ng-click="something(1)">click!</button>
<div id="place"></div>
something() works in this situation, but if I try to make another button with innerHTML on a js code
str="<button ng-click=\"something(2)\">click 2!</button>"
document.getElementById("place").innerHTML = str;
thrn the 2nd button, the one created by innerHTML, apears normal, but doesn't call the function something() when clicked
Is there a nother way to add the button? the buttons should be generated proceduraly as the page runs
Thank you very much!
<script>
let btn = document.createElement("button");
btn.innerText = "click2"
// class
btn.classList = [];
// on click function
btn.onclick = () => {
}
document.getElementById("place").innerHTML = "";
document.getElementById("place").appendChild(btn)
</script>

How to stop an onended function onclick

I have an onclick shuffle function that executes everytime the audio finishes. It works all fine, but I want to make another button that stops its execution.
Please please help with an example
Full Code:
<button onclick="test();stats();auto()">Shuffle</button>
<button id="abort" onclick='exitauto()'>Stop Shuffle</button>
<script>
function exitauto(){
}
</script>
<script>
function stats() {
if(document.getElementById("audio").src == "test.mp3")
{
document.getElementById("p2").innerHTML = "some song";
document.getElementById("playerimg").src="img.png";
};
}
</script>
<script>
function auto(){
var aud = document.getElementById("audio");
aud.onended = function shuf() {
test();
stats();
};
}
</script>
<script>
function test() {
var values = ['test.mp3',
],
valueToUse = values[Math.floor(Math.random() * values.length)];
document.getElementById("audio").pause();
document.getElementById("audio").setAttribute('src', valueToUse);
document.getElementById("audio").load();
document.getElementById("audio").play();
};
</script>
You can add a global variable which can be used to decide whether to call the test() and stats() function in the auto function or not. You can set that variable to true when clicked on start and false when clicked on stop

Javascript object methods evaluate functions

first of all, I'm new to javascript.
my question is how can I add an event listener to the button and call the function from the myObj script. I tried to google but I don't know what is the keyword for that. thank you
<div id="my-btn"></div>
<script>
myObj.button('my-btn',{
onClick: function() {
alert('Button is clicked !');
},
onCancel: function() {
alert('You cancel the process !');
}
});
</script>
and my object
var myObj = {
button: function(btnId, methods)
{
var btn = document.getElementById(btnId);
for (var method in methods)
{
if (method.toLowerCase() == 'onclick')
{
//btn.addEventListener('click', function(e) {
//}
// i want to add listener
// and call the function "onClick"
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
}
thank you for your advice.
Here's one way.
<html>
<head></head>
<body>
<div id="my-btn"></div>
</body>
<script>
const myObj = {
button: (btnId, methods) => {
const btn = document.getElementById(btnId);
for (let method in methods) {
const nameLower = method.toLowerCase();
if (nameLower.startsWith('on')) {
btn.addEventListener(nameLower.substr(2), function(e) {
methods[method]();
});
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
};
myObj.button('my-btn',{
onClick: () => alert('Button is clicked !'),
onCancel: () => alert('You cancel the process !')
});
</script>
</html>
We can map the function names to their events by converting to lowercase and stripping off the "on" prefix. So onClick becomes click. You could simplify things by just using the standard event names in your call to myObj.button.
Start by iterating over the functions, map the name and add the event listener. Inside the event listener all we do is call the function provided in the arguments.

Toggle Event Listeners

I am trying to make a function that would allow me to toggle eventListener of an element.
In the example below, I have three buttons: main, on and off. When I click on the on button, the main button becomes functional. After I click off button, the main button should not work anymore (but now it still does).
Now I can achieve a desired behavior by clicking on button for the second time, but I guess it's a bad coincidence and it's not supposed to work that way.
Maybe I should add that I would like to work this out without using jQuery or similar and it needs to be a function, because I am going to use it for a lot of buttons.
(I suspect something with scope causes the problem (clickHandler when calling the function to activate the button is not the same as the clickHandler when calling the function to disable the button), but I can't think of a way to test it.)
// buttons definitions, not important
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButton = document.querySelector("#offButton");
// main function
var toggleButtons = function(toggleVal, button, element) {
var activateButton, clickHandler, disableButton;
// callback function for listener bellow
clickHandler = function() {
document.querySelector(element).classList.toggle("yellow");
};
activateButton = function() {
button.addEventListener("click", clickHandler);
};
disableButton = function() {
button.removeEventListener("click", clickHandler);
};
// when first argument is 1, make the button functional, otherwise disable its functionality
if (toggleVal === 1) {
activateButton();
} else {
disableButton();
}
};
// when onButton is clicked, call main function with arguments
// this works
onButton.addEventListener("click", function() {
toggleButtons(1, mainButton, "body");
});
// this fails to disable the button
offButton.addEventListener("click", function() {
toggleButtons(0, mainButton);
});
.yellow {
background-color: yellow;
}
<button type="button" id="mainButton">mainButton
</button>
<button type="button" id="onButton">onButton
</button>
<button type="button" id="offButton">offButton
</button>
<p>mainButton: toggles background color on click
</p>
<p>onButton: turns on mainButtons's functionality</p>
<p>offButton: supposed to turn off mainButton's functionality</p>
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButon = document.querySelector("#offButton");
var element; // declare the element here and change it from toggleButtons when needed.
function clickHandler() {
document.querySelector(element).classList.toggle('yellow');
}
function activateButton(button) { // You missed this part
button.addEventListener('click', clickHandler);
}
function disableButton(button) { // You missed this part
button.removeEventListener('click', clickHandler);
}
function toggleButtons(value, button) {
if (value === 1) {
activateButton(button); // You missed this part
} else {
disableButton(button); // You missed this part
}
};
onButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(1, mainButton);
});
offButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(0, mainButton);
});
Below code helps to toggle between two functions from an eventListener:
var playmusic=false;
function playSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.currentTime = 0
audio.play()
playmusic=true;
}
function stopSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.pause()
playmusic=false;
}
window.addEventListener('keydown',
function(){playmusic?stopSound():playSound()} )

Categories

Resources