简体   繁体   English

将属性赋予xmlhttprequest对象

[英]Giving an attribute to an xmlhttprequest object

I have the following code : 我有以下代码:

<head>
<script>

function startChanging() {
    var elems = document.getElementsByTagName("img");

    for(var i=0; i < elems.length; i++)
    {
        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["elem"] = elems[i];
        xmlhttp.onreadystatechange=function()
        {
            if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
                this["elem"].src = xmlhttp.responseText;
            }
        }
        xmlhttp.open("GET", "http://myurl.com/somescript.php", true);
        xmlhttp.send();
    }

};

</script>
</head>

<body onload="startChanging()">
<img src="https://www.google.com/images/srpr/logo11w.png">
<br/>
<img src="https://www.google.com/images/srpr/logo11w.png">
<br/>
<img src="https://www.google.com/images/srpr/logo11w.png">
</body>

Even though I create a new instance of XMLHttpRequest for each iteration and add the current element to an attribute, when the request returns a response only the last img element is changed. 即使我为每次迭代创建一个XMLHttpRequest的新实例并将当前元素添加到属性中,当请求返回响应时,仅最后一个img元素被更改。

I am looking for a simple solution to change the src of the img element without iterating through all the elements again when the response comes. 我正在寻找一个简单的解决方案来更改img元素的src ,而在响应到来时不再次遍历所有元素。 I would like a pure Javascript solution (read: no JQuery). 我想要一个纯Javascript解决方案(阅读:无JQuery)。

I am certainly doing something wrong here I just don't understand what. 我在这里肯定做错了,只是我不明白是什么。 Any help would be appreciated. 任何帮助,将不胜感激。

In your for loop, you are overwriting the xmlhttp variable so when you get into the onreadystatechage function and you check the value of xmlhttp.readyState , it will not be checking the right object. for循环中,您将覆盖xmlhttp变量,因此当您进入onreadystatechage函数并检查xmlhttp.readyState的值时,它将不会检查正确的对象。

I'd suggest this fix which changes two things: 我建议此修复程序可以更改两件事:

  1. It puts each ajax call into it's own IIFE which keeps the xmlhttp variable separate for each ajax call. 它将每个ajax调用放入其自己的IIFE中,这使每个ajax调用的xmlhttp变量保持独立。
  2. It passes elems[i] into the closure so you don't have to do the property saving hack. 它将elems[i]传递到闭包中,因此您不必做保存属性的技巧。

Code: 码:

function startChanging() {
    var elems = document.getElementsByTagName("img");

    for(var i=0; i < elems.length; i++)
    {
        (function(obj) {
            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)
                {
                    obj.src = xmlhttp.responseText;
                }
            }
            xmlhttp.open("GET", "http://myurl.com/somescript.php", true);
            xmlhttp.send();
        })(elems[i]);
    }

};

One possible approach: 一种可能的方法:

xmlhttp.onreadystatechange = function() {
  if (this.readyState === 4 && this.status === 200) {
    this.elem.src = this.responseText;
  }
}

As you see, I've replaced all the references to xmlhttp within that handler function to this . 如您所见,我已将处理程序函数中所有对xmlhttp的引用替换为this

The problem is even though you've created a new AJAX-serving object at each step of the loop, each newly-created 'readystatechange' handler function referred to the same object known under xmlhttp variable. 问题是,即使您在循环的每个步骤中都创建了一个新的AJAX服务对象,每个新创建的'readystatechange'处理函数都引用了xmlhttp变量下已知的同一对象。

In general, this is quite a common problem when someone works with a variable declared within a loop yet referred by functions created in the same loop. 通常,当某人使用在循环中声明但由同一循环中创建的函数引用的变量时,这是一个相当普遍的问题。 Stumble upon this once or twice, and you'll begin to see the pattern. 偶然发现这一次或两次,您将开始看到这种模式。 )

xmlhttp.send();

Put data into the send method: 将数据放入send方法中:

xmlhttp.send(data);

Source: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest 来源: https : //developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

void send();
void send(ArrayBuffer data);
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(DOMString? data);
void send(FormData data);

Where data is a JavaScript variable, you can put anything into. data是JavaScript变量的地方,您可以放入任何内容。 If you want multipart message, you'd use var data = new FormData(); 如果您想要多部分消息,则可以使用var data = new FormData(); and put data into it using data.append('image', file); 并使用data.append('image', file);将数据放入其中 for file upload via ajax for example. 例如通过ajax上传文件。 If no multipart, simply put anything in like: 如果没有多部分,则只需输入:

data = { images: document.getElementsByTagName("img") }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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