What I'm trying to do is run the if statement once only and disable the statement. In my code if I click the button consecutively the if statement still get rendered. Why is that?
HTML:
<button onclick="appendMsg()">submit</button>
<div id="wrapper"></div>
Javascript:
function appendMsg(){
var triggerOnceforShare = true;
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
codepen:
What I'm trying to do is run the if statement once only and disable the statement. In my code if I click the button consecutively the if statement still get rendered. Why is that?
HTML:
<button onclick="appendMsg()">submit</button>
<div id="wrapper"></div>
Javascript:
function appendMsg(){
var triggerOnceforShare = true;
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
codepen: http://codepen.io/vincentccw/pen/uoBkI
Share Improve this question asked Feb 14, 2014 at 8:43 Vincent ChuaVincent Chua 1,0096 gold badges21 silver badges41 bronze badges6 Answers
Reset to default 7You should put your var triggerOnceforShare = true;
outside the function, as global and it will works.
var triggerOnceforShare = true;
function appendMsg(){
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
The variable triggerOnceforShare
is re-initialized every time you run your appendMsg
function - so it is always set to true
.
The way to ensure it is only run once is to store the variable in a closure:
// Using the revealing module pattern
// we create a closure using an immediately invoked function expression (IIFE)
var appendMsg = (function() {
// We store the boolean flag in this IIFE's closure scope
var triggerOnceforShare = true;
// And then we return a function from our IIFE to bind to our `appendMsg` var
return function appendMsg(){
if(triggerOnceforShare){
// Which changes the value of `triggerOnceForShare` in *the parent's* scope
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
}
}
})();
In fact, this sort of pattern can be generalized into a function which decorates another function:
function once(f) {
var hasRun = false;
return function() {
if (hasRun) { return; }
return f.apply(this, arguments);
};
}
which we could then use to simplify our code:
var appendMsg = once(function appendMsg() {
document.getElementById('wrapper').innerHTML+= "true<br />"
});
Try this, Move the var triggerOnceforShare = true;
from inside the function into outside
var triggerOnceforShare = true;
function appendMsg(){
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
<script>
var triggerOnceforShare = true;
function appendMsg(){
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
</script>
Try this pls...
you have to declare the variable outside the function appendMsg()
var triggerOnceforShare = true;
function appendMsg(){
if(triggerOnceforShare){
triggerOnceforShare = false;
document.getElementById('wrapper').innerHTML+=triggerOnceforShare + "<br />"
console.log(triggerOnceforShare);
}
}
Everything in the function gets ran when the function gets called, this includes the triggerOnceforShare = true
statement.
You can either do this;
function appendMsg() {
if (appendMsg.ran)
return;
appendMsg.ran = true;
document.getElementById('wrapper').innerHTML += triggerOnceforShare + "<br />"
}
Which saves the ran
state to the function once ran, and if it's ran again, immediately returns
.
Or you could do something more efficient. Modify your onclick to this; onclick="appendMsg(this)"
and use this;
function appendMsg(button) {
button.onclick = null;
document.getElementById('wrapper').innerHTML += triggerOnceforShare + "<br />"
}
Which removes the handler from the button once ran.