Hi. I know this is a long post, but it's very simple conceptually. I just wanted to post all the code so someone can better help me out.
My problem boils down to this. I have some buttons on a page. When a button gets clicked, I send an ajax call to increment a counter in a mysql database. Sound simple? But when I click the button, the ajax fires multiple times, sometimes THOUSANDS of times!!. The number of times seems to depend on the amount of time I wait between clicks of the button after a page refresh.
So here's what I have (a simplified version that I have actually been testing)
HTML (just five identical images with different id)
//Jquery event handler just pulls the corresponding value from .btn object id and
//passes it to function incrementCounter
//Note that the variable id is preset to some value identifying the key in the mysql
//database whose record is to be updated.
$(".btn").click(
function () {
incrementCounter($(this).attr("id"));
}
);
function incrementCounter(value)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var resp = xmlhttp.responseText;
alert(resp);
}
}
xmlhttp.open("POST","php/increment.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("value="+value);
}
PHP (To make it simple, forget the mysql stuff. Just echo the value that was sent.)
Code:
<?php
$value = $_POST['value'];
echo("Ajax called ".$value);
?>
As far as I know, this is about as simple an AJAX/PHP demo can be. But what is happening is that I'm getting multiple alerts from the "alert(resp);" in the Javascript. In this version I get anywhere from 1 to 5 alerts. In my full version where I actually write the results to a mysql database, I may get hundreds or thousands, and each call writes the data to the database, so I know that the ajax is actually being called all those times.
I even tried ditching the jquery and just used the onclick="incrementCounter(idValueGoesHere);" in the <img> tags. I figured there might be some weird jquery .click binding stuff that was going on. But I get the same behaviour this way.
I'd be very happy if someone can tell me what is happening.
Firstly, it seems kind of silly to be using jQuery for event binding, but then use regular old xmlhttp requests method instead of jQuery's $.ajax XHR wrapper function which makes writing XHR's almost pleasant.
Secondly, we'd need to see the rest of your code - your HTML even (a link would be awesome). Perhaps you're clicking on an .btn element that has several parent .btn elements in which case the click would get triggered on all of them.
I've switched careers...
I'm NO LONGER a scientist,
but now a web developer...
awesome.
I agree with aj_nsc. Stick with jquery to make your code more compact.
Try this:
$(".btn").click(
function () {
incrementCounter($(this).attr("id"));
return false;
}
);
Thanks for your replies guys. I should definitely stick to jquery as you say. I will get around to it. Actually part of what I'm doing is converting a bunch of Javascript to Jquery. And therein was my problem.
What was happening is that after each click, I was re-binding the .btn objects to the .click event via the .live function. I still don't really understand it, but I'm guessing that if you keep rebinding an object to a jquery event you get multiple instances of it. That's why each successive click was producing more and more copies of the ajax call. Does that make any sense?
Maybe it is not related with the issue, but the id's value can not start with a digit, according to the W3C specifications, thus id="1", id="2", etc is not legal in HTML/JavaScript.
Interesting point. As you may see, I am using the value of id to pass as a parameter to the .click eventhandler. How can I pass a numerical parameter to the event handler without using id like I'm doing?
You may name them "x1", "x2" and remove the x character either before request, or at the serverside level. Or you may create a custom attribute for the HTML tag:
Bookmarks