Michael Grigsby
Michael Grigsby

Reputation: 12163

Preventing a js function from executing when it's already been executed

How would I prevent sendMessageAppendData() from being prepended to the 'newMessageSpace' id if sendMessageAppendData() has already been executed in the current js session.

function sendMessageAppendData() {
return '<table id="newMessageBox1" cellpadding="0" cellspacing="0" style="border-radius: 3pt; width: 267px; border: 1px solid #CCCCCC">'+
           '<tr>'+
           '<td valign="top" class="font1" style="text-align: center; padding: 3pt">You are messaging <?php echo $row->firstname." ".$row->lastname ?></td>'+
           '</tr>'+
           '<tr>'+
           '<td valign="top" style="text-align: center; width: 253px; padding: 3pt">'+
           '<input autofocus placeholder="Type your message" id="responseMessage" spellcheck="false" autocomplete="off" class="textbox1" type="text" style="width: 185pt; height: 17px" /></td>'+
           '</tr>'+
           '</table>';
}

$('#clickSendAMessage').live('click', function() {
    $('#newMessageSpace').prepend(sendMessageAppendData());

});

Upvotes: 0

Views: 163

Answers (7)

Nippey
Nippey

Reputation: 4739

I prefer doing it all in-scope by appending the executed-variable to the function itself:

function testFunc() {
  if(!arguments.callee.hasOwnProperty("executed")) {
    arguments.callee.executed = true;
    //alert("First Run");
  }
  else {
    //alert("Too late!");
  }
}

Upvotes: 0

pedrofurla
pedrofurla

Reputation: 12783

You can check if the element doesn't already exists:

$('#clickSendAMessage').live('click', function() {
    if(!$('#newMessageBox1')) {
        $('#newMessageSpace').prepend(sendMessageAppendData());
    }
});

An even better solution is to just replace live with one:

$('#clickSendAMessage').one('click', function() {
   $('#newMessageSpace').prepend(sendMessageAppendData());
});

This way jQuery makes sure it's only executed once.

Upvotes: 0

Stephen
Stephen

Reputation: 5470

Oh, these are fun - try this:

function sendMessageAppendData () {
   console.log("I ran!");
   sendMessageAppendData = function () {}
}

And just for a 'super clean' suggestion..

var clickSendAMessageHandler = function() {
    $('#newMessageSpace').prepend(sendMessageAppendData());
    $('#clickSendAMessage').die('click', clickSendAMessageHandler );
}
$('#clickSendAMessage').live('click', clickSendAMessageHandler);

Essentially the same idea - you use a self reference to stop whatever it was from happening ever again.

Upvotes: 2

Ord
Ord

Reputation: 5843

Here's a little utility that you can use to make any function run only once:

 function onceOnly(fn) {
     var executed = false;
     return function() {
         if (!executed) {
             executed = true;
             fn.apply(this, arguments);
         }
     };
 }

Then, just write sendMessageAppendData = onceOnly(sendMessageAppendData);

Upvotes: 1

xdazz
xdazz

Reputation: 160923

You could use .data() to save the state.

$('#clickSendAMessage').live('click', function() {
    var newMessageSpace = $('#newMessageSpace');
    if (!newMessageSpace.data('prepended')) {
        newMessageSpace.prepend(sendMessageAppendData()).data('prepended', true);
    } 
});

And note .live is deprecated, you could use .on instead.

Upvotes: 0

pdoherty926
pdoherty926

Reputation: 10379

Assuming you don't mind the additional dependency, Underscore.js has a once method.

Upvotes: 1

Rab
Rab

Reputation: 35582

With the help of using javascript global scopr variable

var Isexcuted=0;
function sendMessageAppendData() {
Isexcuted=1;
return '<table id="newMessageBox1" cellpadding="0" cellspacing="0" style="border-radius: 3pt; width: 267px; border: 1px solid #CCCCCC">'+
           '<tr>'+
           '<td valign="top" class="font1" style="text-align: center; padding: 3pt">You are messaging <?php echo $row->firstname." ".$row->lastname ?></td>'+
           '</tr>'+
           '<tr>'+
           '<td valign="top" style="text-align: center; width: 253px; padding: 3pt">'+
           '<input autofocus placeholder="Type your message" id="responseMessage" spellcheck="false" autocomplete="off" class="textbox1" type="text" style="width: 185pt; height: 17px" /></td>'+
           '</tr>'+
           '</table>';
}

$('#clickSendAMessage').live('click', function() {
    if(Isexcuted==0)
    $('#newMessageSpace').prepend(sendMessageAppendData());

});

Upvotes: 1

Related Questions