简体   繁体   中英

Issue with for-loop and standard Javascript AJAX

I have some issues with a for-loop and AJAX. I need to fetch some information from a database, so I pass the incrementing variable to PHP to grab the information and then send it back. The trouble is that it skips immediately to the maximum value, making it impossible to store any of the information.

I would prefer not to use jQuery. It may be more powerful, but I find Javascript easier to understand.

Here is the JS code:

for (var i = 0; i <= 3; i++) {
    var js_var = i;  
    document.getElementById("link").onclick = function () {            
        // ajax start
        var xhr;
        if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
        else xhr = new ActiveXObject("Microsoft.XMLHTTP");     // for IE

        var url = 'process.php?js_var=' + js_var;
        xhr.open('GET', url, false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState===4 && xhr.status===200) {
                var div = document.getElementById('test1');
                div.innerHTML = xhr.responseText;
                if (js_var == 2) {
                    var rawr = document.getElementById('test2');
                    rawr.innerHTML = xhr.responseText;
                }
            }
        }
        xhr.send();
        // ajax stop
        return false;
    }
};

Here is the PHP code:

<?php
if (isset($_GET['js_var'])) $count = $_GET['js_var'];
else $count = "<br />js_var is not set!";

$con = mysql_connect("xxx","xxxxx","xxxx");

mysql_select_db('computerparty_d', $con);

$get_hs = mysql_query("SELECT * FROM hearthstone");

$spiller_navn = utf8_encode(mysql_result($get_hs,$count,1));


echo "$spiller_navn";
?>

Be aware that you're making an synchronous AJAX call, which is undesirable (it hangs the browser during the request, which might not end). You may have problems in some browsers with this because you're calling onreadystatechange, that shouldn't be used with synchronous requests.

what you actually are doing is binding an onclick event in your for-loop not sending ajax request, and the other point is, it immediately overrides the previous onclick handler which you have created in the previous iteration.

So if you want to add multiple listeners you should first consider using nested functions and closures to keep the i variable safe for each listener, and then use addEventListener instead of setting the onclick function. Considering these points you can do this instead:

for (var i = 0; i <= 3; i++) {

    var clickFunc = (function (js_var) {
        return function () {
            // ajax start
            var xhr;
            if (window.XMLHttpRequest) xhr = new XMLHttpRequest(); // all browsers
            else xhr = new ActiveXObject("Microsoft.XMLHTTP"); // for IE

            var url = 'process.php?js_var=' + js_var;
            xhr.open('GET', url, false);
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    var div = document.getElementById('test1');
                    div.innerHTML = xhr.responseText;
                    if (js_var == 2) {
                        var rawr = document.getElementById('test2');
                        rawr.innerHTML = xhr.responseText;
                    }
                }
            }
            xhr.send();
            // ajax stop
            return false;
        };
    })(i);

    document.getElementById("link").addEventListener("click", clickFunc);
}

It looks like you are making the AJAX request with a user click.

for (var i = 0; i <= 3; i++) {
    var js_var = i;  
    document.getElementById("link").onclick

When this JS is executed it will override the "onclick" listener of "link" twice. First time it is assigned for the first time, second time it is overwritten, and the third time it is overwritten again. The result is that when the "link" element is clicked only the last listener exists, resulting in making a single AJAX request for the last configuration.

HTTP request are expensive(time), it might be worth to get all of the data in one request and then use client-side JS to sift through that data accordingly.

jQuery is not more powerful than JS, it is JS with a bunch of wrapper functions. My personal opinion is that once IE9 is no longer relevant, jQuery will be only used by people who know jQuery and not JS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM