JavaScript While loop in a onClick function not responding - javascript

<body>
<button onclick="yesClick()">Click me for a suprise word!</button>
<script>
function yesClick() {
alert("Are you sure?")
alert("Check again... but first click ok")
let element = document.createElement("div");
element.innerText = clickMe;
let clickMe = "Gigachad"
// Loop
while (true) {
document.body.appendChild(element)
}
}
</script>
</body>
Click on the button, two alerts pop up saying "Are you sure?" and "Check again... but first click ok"). When clicked, the while loop should run infinitely since it's a while true loop, right? Well not for me... When clicked a new div should be added with a text inside stating "Gigachad" (don't judge it's just practice) but it doesn't work.
I reviewed the code, had my group partner check it out but didn't work

Your while loop will run forever because true will always be true and there's nothing in the loop that will change that. In fact, the loop is not even necessary and is probably causing the browser to lock up.
Also, your let statements must precede your use of the let variables.
<button onclick="yesClick()">Click me for a suprise word!</button>
<script>
function yesClick() {
alert("Are you sure?")
alert("Check again... but first click ok")
let element = document.createElement("div");
let clickMe = "Gigachad"
element.innerText = clickMe;
document.body.appendChild(element)
}
</script>
Now, you also really shouldn't be using inline event attributes to set up event handlers as that is a 25+ year old legacy way to work with events. And, instead of an alert when you are asking a question, use a confirm.
<button type="button">Click me for a suprise word!</button>
<script>
document.querySelector("button").addEventListener("click", function() {
if(confirm("Are you sure?")) {
alert("Check again... but first click ok")
let element = document.createElement("div");
element.textContent = "Gigachad";
document.body.appendChild(element);
}
});
</script>

Related

Can't change an element's innerText inside a callback

I'm trying to build a dynamic "reset" button which changes its innerText twice, in a loop: once when first clicked (changing from "Reset" to "Are you sure?") and once when clicked again (changing from "Are you sure?" to "Reset"). However, I can't get to modify the innerText inside the callback. It seems like I can modify the innerText just fine from the DOM console, so I assume that there's something that I don't know yet in terms of how event callbacks work in JS, and I can't figure out what it is.
function show_confirm_button() {
document.getElementById('reset-button').innerText = "Are you sure?";
document.getElementById('reset-button').onclick = reset_button;
}
function reset_button() {
/* resetting things here */
document.getElementById('reset-button').innerText = "Reset";
document.getElementById('reset-button').onclick = show_confirm_button;
}
show_confirm_button() is used in a simple bootstrap button:
<button class="..." type="button" onclick=show_confirm_button()>
<span id="reset-button">Reset</span>
</button>
What am I missing?
As #Barmar said:
You should be changing the onclick of the button, NOT the span.
This should work:
function show_confirm_button() {
document.getElementById('reset-button-text').innerText = "Are you sure?";
document.getElementById('reset-button').onclick = reset_button;
}
function reset_button() {
/* resetting things here */
document.getElementById('reset-button-text').innerText = "Reset";
document.getElementById('reset-button').onclick = show_confirm_button;
}
<button class="..." type="button" onclick=show_confirm_button() id="reset-button">
<span id="reset-button-text">Reset</span>
</button>

simple task javascript buttons in html

Can someone please help me make a button which prints thank you when clicked? I know there are lots of ways to do this but in my circumstance, I need to use an if statement and this has me totally stumped. I have not done much because I am totally unsure of what syntax to use. I have made a website for a school project and it has a form on one of the pages. It is a requirement to use javascript to do something with an if statement. I would like to have a button at the bottom of the form which does something to the page when clicked. I don't really mind what happens but I thought a thank you message would be nice.
Cheers :)
<!DOCTYPE html>
<html>
<body>
<button id="sub">Subscribe</button>
</body>
<script>
function button () {
var message = document.getElementById("message");
if (sub.onclicked == true) {
/*Pop up with thank you*/
};
};
button ();
</script>
</html>
If you need if then you can test if button was clicked only once. But first thing is that you need an event that will fire when button is clicked, and document.getElementById value need to match you html id attribute.
function button () {
var message = document.getElementById("sub");
var cliked = false
message.onclick = function() {
if (!cliked) {
cliked = true;
alert('Thank you');
}
};
}
button();
<button id="sub">Subscribe</button>
The key issue here is you're trying to introduce code that has no use. For example here's how you add a message to the page when you click a button:
const button = document.querySelector('#sub');
const message = document.querySelector("#message");
button.addEventListener('click', handleClick, false);
function handleClick(event) {
message.textContent = 'Hallo';
};
<button id="sub">Subscribe</button>
<div id="message" />
There's no room for an if statement here given the basic code example you have in your question. Your assignment may even be marked down if you start adding unnecessary code. That's why I suggested having a look at your requirements and changing them.
For example you might decide you want two buttons that give different messages when you click on them, using an if statement to differentiate between them:
// Because we have two buttons we use a class instead of an id
// and we can pick them up with `querySelectorAll`
const buttons = document.querySelectorAll('.sub');
const message = document.querySelector("#message");
// Instead of attaching one event listener to one element we
// loop over our buttons and attach an event listener to each one
buttons.forEach(button => button.addEventListener('click', handleClick, false));
function handleClick(event) {
// We destructure the dataset id from the button that was clicked
const { target: { dataset: { id } } } = event;
// And we use an if statement to choose between two different messages
if (id === 'msg1') message.textContent = 'Hallo';
if (id === 'msg2') message.textContent = 'Secret message!';
};
<!-- Each button has its own data attribute -->
<button data-id="msg1" class="sub">Button 1</button>
<button data-id="msg2" class="sub">Button 2</button>
<div id="message" />
Further reading:
querySelector and querySelectorAll
Destructuring assignment
Data attributes
addEventListener
<button id="sub">Subscribe</button>
<script>
document.getElementById("sub").addEventListener("click", () =>{
document.write("thank you");
});
</script>
or, if you don't want it to remove all your elements:
<button id="sub">Subscribe</button>
<p id="text"></p>
<script>
document.getElementById("sub").addEventListener("click", () =>{
document.getElementById("text").innerHTML = "thank you!";
});
</script>
<!DOCTYPE html>
<html>
<body>
<button id="sub" onclick="button(event)">Subscribe</button>
<script>
function button(event) {
var message = document.getElementById("message");
if (event) {
/*Pop up with thank you*/
alert("Thank you");
}
};
</script>
</body>
</html>

How to add a function/event listener to an element created with ES6's template literals?

I tried this:
const el = `<button class="create-panorama" onclick="${test()}">Create panorama</button>`
function test () {
console.log('esesesee')
}
element.insertAdjacentHTML('beforeend', el)
// element = <div id="element"></div>
However, nothing happens when I click the button.
What's the best way to add a click action to button?
onclick="${test()}"
That basically tries to execute:
${test()}
which obviously won't work as you cant use template literals outside of a string. Therefore just do
onclick="test()"
What's the best way to add a click action to button?
Inline event listeners are bad for a few reasons, always use .addEventListener !
const el = document.createElement("button");
el.textContent = "Click me!";
el.className = "sth";
el.addEventListener("click", test);
element.appendChild(el);
Change ${test()} to just test()
const el = `<button class="create-panorama" onclick="test()">Create panorama</button>`
document.getElementById("i");
i.innerHTML = el
function test () {
console.log('esesesee')
}
<div id="i"></div>
Note: The best way to add listener is .addEventListener(.. as inline event handlers are executed as eval in HTML markups - It is a bad practice, difficult to manage.
"What's the best way to add a click action to button?"
addEventListener
const el = '<button class="create-panorama">Create panorama</button>';
document.body.insertAdjacentHTML('beforeend', el);
const cp = document.querySelector('.create-panorama');
cp.addEventListener('click', test, false);
function test() {
console.log('esesesee')
}

Button element is not retrieved at the first call

I've came across a curious thing while scripting in JavaScript and I'm not entirely sure if my way of understanding it is correct.
Basically I would like to click a button which brings up another one, if the second button is not brought up by the first I need to quit the loop.
var intervalID = window.setInterval(myfunc,1000);
function t(){
console.log('quit');
clearInterval(intervalID);
}
function myfunc(){
//first button
document.getElementsByClassName('hit')[0].click();
//try to retrieve the second one
var el = document.getElementsByClassName('hit_ok');
console.log(el.length);
//if it exists click it
if (el.length == 1){
el[0].click();
//otherwise exit
} else {
console.log('ready to quit');
window.setTimeout(t,50);
}
}
My problem is that the first instance returns always 0 in the if statements
I also tried the following:
function myfunc(){
document.getElementsByClassName('hit')[0].click();
var el = document.getElementsByClassName('hit_ok');
console.log(el);
if (el != null){
el[0].click();
} else {
console.log('ready to quit');
window.setTimeout(t,50);
}
}
and in fact it returns:
[] --> length: 0__proto__: HTMLCollection
VM3642:1 Uncaught TypeError: Cannot read property 'click' of undefined
instead of:
[span.hit_ok]
Which means that the first time it cant retrieve the button.
Clearly the second button is there since the first one is pressed.
HTML code:
//first button
<div class="try">
<input type="hidden" id="isHit" value="">
Try
</div>
//second button
<div class="msgbox_button">
<span class="hit_ok" onclick="remove();">OK</span>
</div>
Any ideas?
Regards,
What you do:
intervalID=window.setInterval();
This is valid js, but the script is started before the page has loaded, wich means the DOM is not created at that time.
What to do:
window.onload=function(){
var intervalID=window.Interval(...);
};
This starts the loop after the page has loaded

Change onclick action with a Javascript function

I have a button:
<button id="a" onclick="Foo()">Button A</button>
When I click this button the first time, I want it to execute Foo (which it does correctly):
function Foo() {
document.getElementById("a").onclick = Bar();
}
What I want to happen when I click the button the first time is to change the onclick function from Foo() to Bar(). Thus far, I've only been able to achieve an infinite loop or no change at all. Bar() would look something like this:
function Bar() {
document.getElementById("a").onclick = Foo();
}
Thus, clicking this button is just alternating which function gets called. How can I get this to work? Alternatively, what's a better way to show/hide the full text of a post? It originally starts shorted, and I provide a button to "see the full text." But when I click that button I want users to be able to click the button again to have the long version of the text go away.
Here's the full code, if it helps:
function ShowError(id) {
document.getElementById(id).className = document.getElementById(id).className.replace(/\bheight_limited\b/, '');
document.getElementById(id+"Text").className = document.getElementById(id+"Text").className.replace(/\bheight_limited\b/, '');
document.getElementById(id+"Button").innerHTML = "HIDE FULL ERROR";
document.getElementById(id+"Button").onclick = HideError(id);
}
function HideError(id) {
document.getElementById(id).className += " height_limited";
document.getElementById(id+"Text").className += " height_limited";
document.getElementById(id+"Button").innerHTML = "SHOW FULL ERROR";
document.getElementById(id+"Button").onclick = "ShowError(id)";
}
Your code is calling the function and assigning the return value to onClick, also it should be 'onclick'. This is how it should look.
document.getElementById("a").onclick = Bar;
Looking at your other code you probably want to do something like this:
document.getElementById(id+"Button").onclick = function() { HideError(id); }
var Foo = function(){
document.getElementById( "a" ).setAttribute( "onClick", "javascript: Boo();" );
}
var Boo = function(){
alert("test");
}
Do not invoke the method when assigning the new onclick handler.
Simply remove the parenthesis:
document.getElementById("a").onclick = Foo;
UPDATE (due to new information):
document.getElementById("a").onclick = function () { Foo(param); };
Thanks to João Paulo Oliveira, this was my solution which includes a variable (which was my goal).
document.getElementById( "myID" ).setAttribute( "onClick", "myFunction("+VALUE+");" );
I recommend this approach:
Instead of having two click handlers, have only one function with a if-else statement. Let the state of the BUTTON element determine which branch of the if-else statement gets executed:
HTML:
<button id="a" onclick="toggleError(this)">Button A</button>
JavaScript:
function toggleError(button) {
if ( button.className === 'visible' ) {
// HIDE ERROR
button.className = '';
} else {
// SHOW ERROR
button.className = 'visible';
}
}
Live demo: http://jsfiddle.net/simevidas/hPQP9/
You could try changing the button attribute like this:
element.setAttribute( "onClick", "javascript: Boo();" );
What might be easier, is to have two buttons and show/hide them in your functions. (ie. display:none|block;) Each button could then have it's own onclick with whatever code you need.
So, at first button1 would be display:block and button2 would be display:none. Then when you click button1 it would switch button2 to be display:block and button1 to be display:none.
For anyone, like me, trying to set a query string on the action and wondering why it's not working-
You cannot set a query string for a GET form submission, but I have found you can for a POST.
For a GET submission you must set the values in hidden inputs e.g.
an action of: "/handleformsubmission?foo=bar"
would have be added as the hidden field like: <input type="hidden" name="foo" value="bar" />
This can be done add dynamically in JavaScript as (where clickedButton is the submitted button that was clicked:
var form = clickedButton.form;
var hidden = document.createElement("input");
hidden.setAttribute("type", "hidden");
hidden.setAttribute("name", "foo");
hidden.setAttribute("value", "bar");
form.appendChild(hidden);
See this question for more info
submitting a GET form with query string params and hidden params disappear

Categories

Resources