开发者

JavaScript problem?

Now when I have a user cast a vote the script updates my database but it won't display the following code below to tell the user its vote has been excepted everything else works correctly except my AJAX code.

How can I fix this problem to get the below code to display the new rating when user enters his or her vote?

I'm using PHP

Here is the JavaScript code.

    function vote(id, rating) {
        if (window.XMLHttpRequest) {
            http = new X开发者_开发知识库MLHttpRequest();
        } else if (window.ActiveXObject) {
            http = new ActiveXObject("Microsoft.XMLHTTP");
        }
        var url = 'ajax.php?';
        var fullurl = url + 'id=' + id + '&rating=' + rating;
        //This will create the request to our file, with the information about the vote.
        http.open("GET", fullurl, true);
        http.send(null);
        http.onreadystatechange = statechange_rate;
    }

    function statechange_rate() {
        if (http.readyState == 4) {
            var xmlObj = http.responseXML;
            var html = xmlObj.getElementsByTagName('result').item(0).firstChild.data;
            var id = xmlObj.getElementsByTagName('result').item(0).getAttribute("id");
            var votes = xmlObj.getElementsByTagName('result').item(0).getAttribute("votes");
            var rating = xmlObj.getElementsByTagName('result').item(0).getAttribute("rating");
            //Before, you may have noticed we set votes="-1" if they had already voted, this was just to provide an easy way to check the return of our ajax.php script.
            if(votes != -1) {
                //This will inform the user about the vote they have cast.
                document.getElementsByName('output_' + id).item(0).innerHTML = "<br />" + html;
                //This will set a delay to make that message go away in 5000 miliseconds (5 seconds).
                window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
                //This will update the rating on the page to the new one.
                document.getElementsByName('rating_' + id).item(0).innerHTML = rating;
                document.getElementsByName('votes_' + id).item(0).innerHTML = votes;
            }else{
                document.getElementsByName('output_' + id).item(0).innerHTML = "<br />" + html;
                window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
            }
        }
    }


I have never seen what you are showing, so I don't know if this is your problem, but you have a tag called <result>...</result>?

You have this line, which leads to my question:

xmlObj.getElementsByTagName('result')...

It would be helpful if you could modify your statechange_rate thusly:

alert("votes result: " + votes);
if(votes != -1) {
  //This will inform the user about the vote they have cast.
  var elem = document.getElementsByName('output_' + id);
  elem.item(0).innerHTML = "<br />" + html;
  //This will set a delay to make that message go away in 5000 miliseconds (5 seconds).
  window.setTimeout("document.getElementsByName('output_" + id + "').item(0).innerHTML = '';", 5000);
  //This will update the rating on the page to the new one.
  elem = document.getElementsByName('rating_' + id);
  elem.item(0).innerHTML = rating;
  elem = document.getElementsByName('votes_' + id);
  elem.item(0).innerHTML = votes;

If you are using IE8 then bring up the javascript debugger (I press F12 to get it) and if using Firefox then use the Firebug plugin, which is my preferred approach.

After each elem = ... put a breakpoint and make certain that you are getting the items you want.

I expect that the first alert may be the problem though, as your result from the ajax call may be getting cached. You need to make certain that your browser won't cache the response, but, I have found it best to set the header in the response to no-cache, but also to pass the current seconds + milliseconds in my request, though I never check that value, but, by putting it there it is unlikely that it will be repeated and so won't be pulled from the browser cache.

If the fact that you are using getElementsByTagName is incorrect, as you aren't checking for there to be any elements returned, you may be getting an error when you try to get the first element. You should do a sanity check when you should have at least one in a list and make certain the list is not empty. Firebug will show an error on the console if you are throwing an exception, which would explain why your update is not showing up.

If you don't want to use jQuery, if you can set the ids of the elements it would be better to use document.getElementById.


I can't be sure since I don't know what error you're getting but maybe you want to set http.onreadystatechange = statechange_rate; after you open the connection but before you call send.


First off I should ask, Are you sending an XML Content type header such as "text/xml" with your response from PHP? If not the responseXML property will not contain any content.

Here is what I think this code should look like:-

function vote(id, rating) { var http = getXHR() var fullurl = 'ajax.php?id=' + id + '&rating=' + rating;

if (http) { http.open("GET", fullurl, true); http.onreadystatechange = statechange_rate; http.send(null); }

function statechange_rate() { if (http.readyState == 4) { var xmlObj = http.responseXML; var result = http.responseXML.documentElement; var html = result.firstChild.data; var id = result.getAttribute("id"); var votes = result.getAttribute("votes"); var rating = result.getAttribute("rating");

elem = document.getElementById('output_' + id);

elem.innerHTML = "<br />" + html;
window.setTimeout(function() {elem.innerHTML = '';}, 5000);
if (votes != -1)
{
 document.getElementById('rating_' + id).innerHTML = rating;
 document.getElementById('votes_' + id).innerHTML = votes;
}

} } }

function getXHR() { if (window.XMLHttpRequest) { http = new XMLHttpRequest(); } else if (window.ActiveXObject) { http = new ActiveXObject("Microsoft.XMLHTTP"); } }

Notes:-

  • Assigned the call back to onreadystatechanged before calling send
  • I suspect the "results" element is the root element of the XML.
  • Use id attributes on HTML elements and getElementById to find them.
  • Extracted duplicate code from If
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜